I have "Filling form" worksheet where user is filling information and then I have "Print version" worksheet that is actually printing. I am making "CV tool" so user is filling his personal information and then my current VBA is saving end file from "Print version" to xls. and .pdf to the same folder with certain name both files where my "CV tool" is. Some people have experience of 10 years in 10 different work places and others have been only in 2 different companies previously. So before saving to .pdf and .xls my VBA hides rows that are empty to make end result look good.
The problem is that estetically it is not so good looking because some heading of work positions are at the end of the page and work description is continuing on the next page. Is there any way to make some kind of VBA to look for each page in "PrintArea" and if certain block is not fitting to this page VBA will insert "Page Break" before it to move it to the next page?
My current macro below (Sub doitallplease() is main command):
Sub Color()
Dim myRange As Range
Dim cell As Range
Set myRange = ThisWorkbook.Sheets("Print version").Range("Print_Area")
For Each cell In myRange
myRange.Interior.ColorIndex = 0
If cell.HasFormula = True And cell.value = "" And cell.EntireRow.Hidden = False Then Rows(cell.Row).EntireRow.Hidden = True
Next
End Sub
Sub MagicButton()
Dim iFileName$, iRow&, iCol&, iCell As Range, iArr
iFileName = ThisWorkbook.Path & "\CV_" & Sheets("Filling form").Range("F7") & "_" & Sheets("Filling form").Range("F9") & ".xls"
iArr = Array(1, 3, 4): iCol = UBound(iArr) + 1
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlManual
ThisWorkbook.Sheets("Print version").Copy
With ActiveWorkbook.ActiveSheet
.Buttons.Delete '.Shapes("Button 1").Delete
.UsedRange.value = .UsedRange.value
.SaveAs iFileName, xlExcel8: .Parent.Close
End With
Application.Calculation = xlAutomatic
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Sub exportpdfthisfile()
ActiveWorkbook.Sheets("Print version").Select
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=ThisWorkbook.Path & "\CV_" & Sheets("Filling form").Range("F7") & "_" & Sheets("Filling form").Range("F9") & ".pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End Sub
Sub doitallplease()
Application.ScreenUpdating = False
ActiveWorkbook.Sheets("Print version").Visible = True
Call Color
Call MagicButton
Call exportpdfthisfile
ActiveWorkbook.Sheets("Filling form").Activate
ActiveWorkbook.Sheets("Print version").Visible = False
Application.ScreenUpdating = True
End Sub
Related
I have written the following code tied to a command button to prompt the user to define a save path, export the active sheet to PDF and open it, then delete the sheet after it's been exported and activate a different sheet. The code works to completion but right at the end, I get a the following error:
Run-time error '-2147221080 (800401a8)':
Automation error
Below is my code. Any help would be immensely appreciated.
Private Sub ExceptionPrint_Click()
Sheet_Name = ActiveSheet.Name
PDF_Name = "Exception - " & ActiveSheet.Name & ".pdf"
Set File_Dialog = Application.FileDialog(msoFileDialogFolderPicker)
File_Dialog.AllowMultiSelect = False
File_Dialog.Title = "Select the Desired Location"
If File_Dialog.Show <> -1 Then
Exit Sub
End If
PDF_Name = File_Dialog.SelectedItems(1) & "\" & PDF_Name
ActiveSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=PDF_Name, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=True
If Sheets("Data").Range("H12").Value = "W1" Then
Sheets("Week 1").Activate
Sheets("Data").Range("H12").Value = ""
Else
Sheets("Week 1").Activate
Sheets("Data").Range("H12").Value = ""
End If
Application.DisplayAlerts = False
Sheets(Sheet_Name).Delete
Application.DisplayAlerts = True
End Sub
I've tried everything I could think of, but I'm not that great with VBA to begin with.
Assign the active sheet to a reference at the start and use that reference throughout the program. Also try to catch early any errors that the user might make.
Option Explicit
Private Sub ExceptionPrint_Click()
Dim wb As Workbook, wsPDF As Worksheet, PDF_Name As String
' validation
Set wb = ThisWorkbook
Set wsPDF = wb.ActiveSheet
With wsPDF
If .Name = "Week 1" Or .Name = "Data" Then
MsgBox "Sheet " & wsPDF.Name & " must not be selected", vbCritical
Exit Sub
ElseIf WorksheetFunction.CountA(.UsedRange) = 0 Then
MsgBox .Name & " is blank", vbCritical
Exit Sub
End If
End With
' select folder
With Application.FileDialog(msoFileDialogFolderPicker)
.AllowMultiSelect = False
.Title = "Select the Desired Location"
If .Show <> -1 Then Exit Sub
PDF_Name = .SelectedItems(1) & "\Exception - " & wsPDF.Name & ".pdf"
End With
' print and delete
wsPDF.ExportAsFixedFormat Filename:=PDF_Name, Type:=xlTypePDF, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=True
Application.DisplayAlerts = False
wsPDF.Delete
Application.DisplayAlerts = True
' finish
With wb
.Sheets("Week 1").Activate
.Sheets("Data").Range("H12").Value = ""
End With
End Sub
I ended up just leaving a "Delete Sheet" button on the sheet in question rather than having it automatically delete. Thank you everyone.
This is what I am working on. I have a workbook that is exporting data, running data through a couple of other macros to sort and format it before inserting the data into a formatted worksheet that will have a "Print to PDF" button. What I am running into is that the print area on this ends up printing hundreds of pages.
My suspicion is that this is happening because I use an excel formula that is modifying the data in every column. The answer MAY be to write this out as VBA code instead of nesting the formulas in the columns. But I think it is counting the cells down through these rows because it has a formula even though the cell itself is blank. Does that make sense? Or can you see any other problems??
Option Explicit
Const EXPORTS As String = "P:\Public\Generated Letters\LTXN Export Spreadsheets\"
Sub Create_PDF()
Dim ws As Worksheet
Dim AccountNumber As String, dt As String, FullName As String, fName As String, sep As String
Dim myrange As String
Set ws = ActiveSheet
AccountNumber = Right(ws.Range("A3").Value, 3) 'not just `A3`
'sets the string end for the print area
myrange = Cells(Rows.Count, 6).End(xlUp).Address
With ActiveSheet.PageSetup
.PrintArea = "A1:" & myrange
.Orientation = xlLandscape
.Zoom = False
.FitToPagesTall = False
.FitToPagesWide = 1
End With
dt = Format(Now, "mm.dd.yyyy hh mm")
fName = EXPORTS & "AccountEnding" & AccountNumber & " - Created On - "
If Len(Dir(fName & ".pdf")) > 0 Then sep = " - "
fName = fName & sep & dt & ".pdf"
ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:=fName, _
Quality:=xlQualityStandard, IncludeDocProperties:=False, _
IgnorePrintAreas:=False, OpenAfterPublish:=True
Call Shell("explorer.exe" & " " & "P:\Public\Generated Letters\LTXN Export Spreadsheets\", vbNormalFocus)
End Sub
So I found an update as I have been milling around on this, it seems like a copy and insert function is causing the issue here. I have this code run before the print to pdf code:
Sub Data_Filter()
If CountRows = ThisWorkbook.Worksheets("LTXN Data").Range("A:A").Cells.SpecialCells(xlCellTypeConstants).Count > 5000 Then
MsgBox ("Due to the number of transactions please reach out to David Wallenburg for assistance.")
Exit Sub
End If
Application.DisplayAlerts = False
Sheets("LTXN Data").Select
Range("A2:I2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("LTXN Formatting").Select
Range("A1:I1").PasteSpecial
Application.CutCopyMode = False
Sheets("LTXN Formatting").Select
Range("M1:R1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Worksheets("LTXN Formatting Sort").Visible = True
Sheets("LTXN Formatting Sort").Select
Range("a1:f1").PasteSpecial xlPasteValues
Application.CutCopyMode = False
Columns("A:F").Sort key1:=Range("E1"), Order1:=xlDescending
Range("A1:F1").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Worksheets("LTXN Report").Visible = True
Sheets("LTXN Report").Select
Range("A6:F6").Select
Selection.Insert xlShiftDown
Application.CutCopyMode = False
Dim myrange As String
myrange = Cells(Rows.Count, 6).End(xlUp).Address
Sheets("LTXN Report").Range(Selection, ("a1:" & myrange)).Select
ActiveSheet.Range("A1:" & myrange).BorderAround ColorIndex:=1, Weight:=xlThick
Application.DisplayAlerts = True
Sheets("LTXN Report").Activate
End Sub
I think the problem is that when it goes to the LTXN Formatting Sort page it is selecting much more than the columns with DATA. IS there an easy fix i am missing?
Two ways to go about this then. The first one is to use array formulas, specifically Filter(Range,criteria) and depending on how complicated the data is, you might want to have a separate row to determine what data to include. In my example I'm using:
=COUNTIF(E2:G2,"-/-")<>3
Then I have the "Output Report" section, which can be moved to separate page if need be, by using the formula:
=FILTER(E2:G31,I2:I31)
(to note, I'm using "-/-" instead of "" just to help show the blank spaces.)
You Can now confidently use range("somerange").end(xlup).row to find last row
OR -
If you have no blank rows, you can use
Sheet4.Range("E:E").Find(what:="", LookIn:=xlValues).Row -1
and that will give you the first row without data.
However, if you have some rows that may have nothing in them, you might want to pull the data into an array and step backwards through it to find last row:
Option Explicit
Sub Set_Print_Area()
Dim I
Dim iLow As Long
Dim iHigh As Long
Dim RG
iHigh = Sheet4.Range("E" & Rows.Count).End(xlUp).Row
Set RG = Sheet4.Range("E1:E" & iHigh)
For I = iHigh To 1 Step -1
If RG(I) <> "" Then
Debug.Print I
ActiveSheet.PageSetup.PrintArea = "E1:G" & I
Exit For
End If
Next I
End Sub
Hopefully one of these methods helps.
Hi all and thank you for taking the time to read.
In relation to the code below (code provided by M--) from this post VBA to select each slicer item AND then save each selected slicer item as a pdf?
Rather than a predetermined save / export location i would like the user to select a folder of their choice.
I have been politely informed in stack chat by #QHarr that i need a filedialog object to introduce this function. Would this be at the beginning of the module? Is export better than save.as in this scenario? Would the latter effect the way the slicer items are transferred?
Much appreciated and kind regards
wAnd
Public Sub myMacro()
Dim sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Store_Number")
'This reminds the user to only select the first slicer item
If sC.VisibleSlicerItems.Count <> 1 Or sC.SlicerItems(1).Selected = False Then
MsgBox "Please Only Select Store-Number 1"
Exit Sub
End If
For i = 1 To sC.SlicerItems.Count
'Do not clear ilter as it causes to select all of the items (sC.ClearManualFilter)
sC.SlicerItems(i).Selected = True
If i <> 1 Then sC.SlicerItems(i - 1).Selected = False
'Debug.Print sI.Name
'add export to PDF code here
With Sheet18.PageSetup
.PrintArea = Sheet18.Range("A1:N34" & lastRow).Address
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
Sheet18.Range("M1") = sC.SlicerItems(i).Name
'This prints to C directory, change the path as you wish
Sheet18.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"C:\" & Range("M1").Text & ".pdf", Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next
End Sub
After looking around i have managed to solve it. In a nutshell i didnt use the back slash for Filename:=path & \ & Range("G2").Text
Final code below
Private Sub CommandButton1_Click()
Dim sC As SlicerCache
Set sC = ActiveWorkbook.SlicerCaches("Slicer_Site_Product")
Dim dialog As FileDialog
Dim path As String
Set dialog = Application.FileDialog(msoFileDialogFolderPicker)
dialog.AllowMultiSelect = False
If dialog.Show = -1 Then
path = dialog.SelectedItems(1)
'This reminds the user to only select the first slicer item
If sC.VisibleSlicerItems.Count <> 1 Or sC.SlicerItems(1).Selected = False Then
MsgBox "Please select the top most item"
Exit Sub
End If
For i = 1 To sC.SlicerItems.Count
'Do not clear ilter as it causes to select all of the items (sC.ClearManualFilter)
sC.SlicerItems(i).Selected = True
If i <> 1 Then sC.SlicerItems(i - 1).Selected = False
'Debug.Print sI.Name
'add export to PDF code here
With Sheet5.PageSetup
.PrintArea = Sheet5.Range("B2:M76" & lastRow).Address
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
Sheet5.Range("G2") = sC.SlicerItems(i).Name
For Each CL In Sheet5.Range("M11:M67")
If CL.WrapText Then CL.Rows.AutoFit
Sheet5.Range("A1:A74").AutoFilter Field:=1, Criteria1:=Sheet5.Range("A2")
Next
'This prints to C directory, change the path as you wish
Sheet5.ExportAsFixedFormat Type:=xlTypePDF, Filename:=path & "\" & Range("G2").Text, Quality:= _
xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=False
Next
End If
End Sub
I have the file save path located in J2, so I want to have a macro that creates a folder in the location that's in J2 and if that file is already created to end the process and loop to my other code which creates PDF's and save each one into that location. I already have that code working. I will paste both below:
This is the first code that I'm working on to create a folder based on the location in the cell
Sub MakeMyFolder()
Dim FldrName As String
On Error Resume Next
Set fsoFSO = CreateObject("Scripting.FileSystemObject")
If fsoFSO.FolderExists = Range("J2") Then
MsgBox "found it"
Else
fsoFSO.CreateFolder = Range("J2")
MsgBox "Done"
End If
End Sub
This is my second code that's already working that creates and saves PDF's in the location in J2
Sub PDF_Generator()
Dim cell As Range
Dim wsSummary As Worksheet
Dim counter As Long
Set wsSummary = Sheets("SUMMARY BY PROVIDER")
For Each cell In Worksheets("NAME KEY").Range("$H2:$H60")
If cell.Value <> "Exclude" Then
'progress in status bar
counter = counter + 1
Application.StatusBar = "Processing file: " & counter & "/1042"
With wsSummary
.Range("$B$8").Value = cell.Value
.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=ThisWorkbook.Sheets("SUMMARY BY PROVIDER").Range("J2").Value & _
"\" & cell.Value & ".pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End With
End If
Next cell
Set wsSummary = Nothing
End Sub
I want to get the first code working than combine that procedure with the next, any insight on this question will be great!
These are functions so they have a return value. Try it like this:
fsoFSO.FolderExists(Range("J2"))
instead of
fsoFSO.FolderExists = Range("J2")
The same for CreateFolder:
Sub MakeMyFolder(strFolder as string)
Set fsoFSO = CreateObject("Scripting.FileSystemObject")
If fsoFSO.FolderExists(strFolder) Then
MsgBox "found it"
Else
fsoFSO.CreateFolder(strFolder)
MsgBox "Done"
End If
End Sub
To combine them, add an argument to your sub MakeMyFolder(strFolder as string)
I am assuming your cell that could have exclude will have the folder path, so call your sub with that as the argument; MakeMyFolder cell.Value from in your PDF_generate sub.
Sub MakeMyFolder(strFolder as string)
Set fsoFSO = CreateObject("Scripting.FileSystemObject")
If fsoFSO.FolderExists(strFolder) Then
MsgBox "found it"
Else
fsoFSO.CreateFolder(strFolder)
MsgBox "Done"
End If
End Sub
Sub PDF_Generator()
Dim cell As Range
Dim wsSummary As Worksheet
Dim counter As Long
Set wsSummary = Sheets("SUMMARY BY PROVIDER")
For Each cell In Worksheets("NAME KEY").Range("$H2:$H60")
If cell.Value <> "Exclude" Then
'******* Call your sub here with the folder to be creted ****************************
MakeMyFolder cell.Value
'progress in status bar
counter = counter + 1
Application.StatusBar = "Processing file: " & counter & "/1042"
With wsSummary
.Range("$B$8").Value = cell.Value
.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=ThisWorkbook.Sheets("SUMMARY BY PROVIDER").Range("J2").Value & _
"\" & cell.Value & ".pdf", _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End With
End If
Next cell
Set wsSummary = Nothing
End Sub
Edit:
After doing a bit more research I stumbled on this handy little shortcut:
Just right click on the little arrows on the bottom left corner to show all sheets - no code required!
I have an excel workbook with 100 tabs. Luckily for me the tabs are all numbered 1-100. I Have an index page with all the numbers in a row and I would like to make a row next to that row with a hyperlink to the numbered tab.
A B
---------------------------
| 1 | link to tab 1 |
---------------------------
| 2 | link to tab 2 |
---------------------------
etc...
So far the most promising thing I've found is:
=Hyperlink(“C:\Documents and Settings\Admin1\Desktop\” & A1 & “.xls”,A1)
I know that the hyperlink function expects:
=HYPERLINK(link_location,friendly_name)
And when I do it manually, I get this:
=HYPERLINK('1'!$A$1,A1)
So I want to do something like this:
=HYPERLINK('& A1 &'!$A$1,A1)
But it's not working. Any help is much appreciated. Also, if there is an easier way to approach this - I am all ears.
With code something like this
Press Alt + F11 to open the Visual Basic Editor (VBE).
From the Menu, choose Insert-Module.
Paste the code into the right-hand code window.
Close the VBE, save the file if desired.
In excel-2003 go to Tools-Macro-Macros and double-click CreateTOC
In excel-2007 click the Macros button in the Code group of the Developer tab, then click CreateTOC in the list box.
Option Explicit
Sub CreateTOC()
Dim ws As Worksheet
Dim nmToc As Name
Dim rng1 As Range
Dim lngProceed As Boolean
Dim bNonWkSht As Boolean
Dim lngSht As Long
Dim lngShtNum As Long
Dim strWScode As String
Dim vbCodeMod
'Test for an ActiveWorkbook to summarise
If ActiveWorkbook Is Nothing Then
MsgBox "You must have a workbook open first!", vbInformation, "No Open Book"
Exit Sub
End If
'Turn off updates, alerts and events
With Application
.ScreenUpdating = False
.DisplayAlerts = False
.EnableEvents = False
End With
'If the Table of Contents exists (using a marker range name "TOC_Index") prompt the user whether to proceed
On Error Resume Next
Set nmToc = ActiveWorkbook.Names("TOC_Index")
If Not nmToc Is Nothing Then
lngProceed = MsgBox("Index exists!" & vbCrLf & "Do you want to overwrite it?", vbYesNo + vbCritical, "Warning")
If lngProceed = vbYes Then
Exit Sub
Else
ActiveWorkbook.Sheets(Range("TOC_Index").Parent.Name).Delete
End If
End If
Set ws = ActiveWorkbook.Sheets.Add
ws.Move before:=Sheets(1)
'Add the marker range name
ActiveWorkbook.Names.Add "TOC_INDEX", ws.[a1]
ws.Name = "TOC_Index"
On Error GoTo 0
On Error GoTo ErrHandler
For lngSht = 2 To ActiveWorkbook.Sheets.Count
'set to start at A6 of TOC sheet
'Test sheets to determine whether they are normal worksheets
ws.Cells(lngSht + 4, 2).Value = TypeName(ActiveWorkbook.Sheets(lngSht))
If TypeName(ActiveWorkbook.Sheets(lngSht)) = "Worksheet" Then
'Add hyperlinks to normal worksheets
ws.Hyperlinks.Add Anchor:=ws.Cells(lngSht + 4, 1), Address:="", SubAddress:="'" & ActiveWorkbook.Sheets(lngSht).Name & "'!A1", TextToDisplay:=ActiveWorkbook.Sheets(lngSht).Name
Else
'Add name of any non-worksheets
ws.Cells(lngSht + 4, 1).Value = ActiveWorkbook.Sheets(lngSht).Name
'Colour these sheets yellow
ws.Cells(lngSht + 4, 1).Interior.Color = vbYellow
ws.Cells(lngSht + 4, 2).Font.Italic = True
bNonWkSht = True
End If
Next lngSht
'Add headers and formatting
With ws
With .[a1:a4]
.Value = Application.Transpose(Array(ActiveWorkbook.Name, "", Format(Now(), "dd-mmm-yy hh:mm"), ActiveWorkbook.Sheets.Count - 1 & " sheets"))
.Font.Size = 14
.Cells(1).Font.Bold = True
End With
With .[a6].Resize(lngSht - 1, 1)
.Font.Bold = True
.Font.ColorIndex = 41
.Resize(1, 2).EntireColumn.HorizontalAlignment = xlLeft
.Columns("A:B").EntireColumn.AutoFit
End With
End With
'Add warnings and macro code if there are non WorkSheet types present
If bNonWkSht Then
With ws.[A5]
.Value = "This workbook contains at least one Chart or Dialog Sheet. These sheets will only be activated if macros are enabled (NB: Please doubleclick yellow sheet names to select them)"
.Font.ColorIndex = 3
.Font.Italic = True
End With
strWScode = "Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)" & vbCrLf _
& " Dim rng1 As Range" & vbCrLf _
& " Set rng1 = Intersect(Target, Range([a6], Cells(Rows.Count, 1).End(xlUp)))" & vbCrLf _
& " If rng1 Is Nothing Then Exit Sub" & vbCrLf _
& " On Error Resume Next" & vbCrLf _
& " If Target.Cells(1).Offset(0, 1) <> ""Worksheet"" Then Sheets(Target.Value).Activate" & vbCrLf _
& " If Err.Number <> 0 Then MsgBox ""Could not select sheet"" & Target.Value" & vbCrLf _
& "End Sub" & vbCrLf
Set vbCodeMod = ActiveWorkbook.VBProject.VBComponents(ws.CodeName)
vbCodeMod.CodeModule.AddFromString strWScode
End If
'tidy up Application settins
With Application
.ScreenUpdating = True
.DisplayAlerts = True
.EnableEvents = True
End With
ErrHandler:
If Err.Number <> 0 Then MsgBox Err.Description & vbCrLf & "Please note that your Application settings have been reset", vbCritical, "Code Error!"
End Sub
My snippet:
Sub AddLinks()
Dim wksLinks As Worksheet
Dim wks As Worksheet
Dim row As Integer
Set wksLinks = Worksheets("Links")
wksLinks.UsedRange.Delete
row = 1
For Each wks In Worksheets
' Debug.Print wks.Name
wks.Hyperlinks.Add wksLinks.Cells(row, 1), "", wks.Name & "!A1", , wks.Name
row = row + 1
Next wks
End Sub
Assumes a worksheet named 'Links"
Might not be a direct answer to your method, but I would create something more pleasing to the eye, like ... some shapes formatted nicely and then asign some basic macros to them, for selecting the sheets.
This can be easely modified to go to a specific address (like the Go TO Ctrl+Gbuilt in Excel feature).Hope this helps on the fashion style of your file :)
EDIT!
Don't know why my answer received a -1 rating. As I've said it's an alternative and not a direct solution to the given question. Still, I do believe my initial answer was superficial without a proven/working VBA code, thus I've developed a little practical example below:
Sub Add_Link_Buttons()
'Clear any Shapes present in the "Links" sheet
For j = ActiveSheet.Shapes().Count To 1 Step -1
ActiveSheet.Shapes(j).Delete
Next j
'Add the shapes and then asign the "Link" Macros
For i = 1 To ActiveWorkbook.Sheets.Count
ActiveSheet.Shapes.AddShape Type:=msoShapeRoundedRectangle, Left:=50, Top:=i * 25, Width:=100, Height:=25
ActiveSheet.Shapes(i).OnAction = "Select_Sheet" & i
'even add the the sheet Name as Test:
ActiveSheet.Shapes(i).TextFrame2.TextRange.Characters.Text = Sheets(i).Name
Next i
End Sub
where the "basic Select Macros" whould be:
Sub Select_Sheet1()
ActiveWorkbook.Sheets(1).Select
End Sub
Sub Select_Sheet2()
ActiveWorkbook.Sheets(2).Select
End Sub
Sub Select_Sheet3()
ActiveWorkbook.Sheets(3).Select
End Sub
' and so on!
' Note! to link a specific address within the sheets use the range like in 'Sheets(1).Range("A1").Select
Again, This is an alternative and doesn't add hyperlinks (as asked), but enables the sheet select from the same location.
TO address the buttons to links for outside files, simply define the address > filename/workbook Sheets() and Open ;)
Here is the code I use:
Sub CreateIndex()
'This macro checks for an Index tab in the active worksheet and creates one if one does not already exist.
'If an Index tab already exists, the user is asked to continue. If they continue, the original Index tab is replaced by a new Index tab. If they do not continue, the macro stops.
'The user is then asked if they want to create a link back to the Index tab on all other worksheets (yes or no) and the macro acts accordingly.
Dim wsIndex As Worksheet
Dim wSheet As Worksheet
Dim retV As Integer
Dim i As Integer
With Application
.DisplayAlerts = False
.ScreenUpdating = False
End With
Set wsIndex = Worksheets.Add(Before:=Sheets(1))
With wsIndex
On Error Resume Next
.Name = "Index"
If Err.Number = 1004 Then
If MsgBox(Prompt:="A sheet named ""Index"" already exists. Do you wish to continue by replacing it with a new Index?", _
Buttons:=vbInformation + vbYesNo) = vbNo Then
.Delete
MsgBox "No changes were made."
GoTo EarlyExit:
End If
Sheets("Index").Delete
.Name = "Index"
End If
On Error GoTo 0
retV = MsgBox("Create links back to ""Index"" sheet on other sheets?", vbYesNo, "Linking Options")
For Each wSheet In ActiveWorkbook.Worksheets
If wSheet.Name <> "Index" Then
i = i + 1
If wSheet.Visible = xlSheetVisible Then
.Range("B" & i).Value = "Visible"
ElseIf wSheet.Visible = xlSheetHidden Then
.Range("B" & i).Value = "Hidden"
Else
.Range("B" & i).Value = "Very Hidden"
End If
.Hyperlinks.Add Anchor:=.Range("A" & i), Address:="", SubAddress:="'" & wSheet.Name & "'!A1", TextToDisplay:=wSheet.Name
If retV = 6 And wSheet.Range("A1").Value <> "Index" Then
wSheet.Rows(1).Insert
wSheet.Range("A1").Hyperlinks.Add Anchor:=wSheet.Range("A1"), Address:="", SubAddress:="'" & .Name & "'!A1", TextToDisplay:=.Name
End If
End If
Next wSheet
.Rows(1).Insert
With .Rows(1).Font
.Bold = True
.Underline = xlUnderlineStyleSingle
End With
.Range("A1") = "Sheet Name"
.Range("B1") = "Status"
.UsedRange.AutoFilter
Rows("2:2").Select
ActiveWindow.FreezePanes = True
Application.Goto Reference:="R1C1"
.Columns("A:B").AutoFit
End With
With ActiveWorkbook.Sheets("Index").Tab
.Color = 255
.TintAndShade = 0
End With
EarlyExit:
With Application
.DisplayAlerts = True
.ScreenUpdating = True
End With
End Sub
-Mike