My VBA behaves differently when assigned to a button - vba

I have set up a Quality Check sheet which needs to store results in a separate sheet called 'Data' as a row of data, and save an archived version of the full Check Sheet in a separate workbook.
I'm quite a novice on VBA but have managed to get what I need working. My problem comes when I assign the macro to a button which is contained on my check sheet. If I press the button it copies the wrong sheet over and basically does not do what it does when I run the macro manually. Can anyone suggest anything please?
Thanks
My code is as follows:
Sub SaveForm()
' SaveForm Macro
' Saves form data to the Data Sheet
'Checks for completion of mandatory fields
If IsEmpty(Range("b3").Value) = True Then
MsgBox "Please complete 'Agent Name' before saving"
Exit Sub
ElseIf IsEmpty(Range("b4").Value) = True Then
MsgBox "Please complete 'Call ID' before saving"
Exit Sub
ElseIf IsEmpty(Range("b5").Value) = True Then
MsgBox "Please complete 'Call Length' before saving"
Exit Sub
ElseIf IsEmpty(Range("D3").Value) = True Then
MsgBox "Please complete 'Business Name' before saving"
Exit Sub
ElseIf IsEmpty(Range("D4").Value) = True Then
MsgBox "Please complete 'Date of Call' before saving"
Exit Sub
ElseIf IsEmpty(Range("D5").Value) = True Then
MsgBox "Please complete 'Time of Call' before saving"
Exit Sub
ElseIf IsEmpty(Range("b7").Value) = True Then
MsgBox "Please complete 'Assessor Name' before saving"
Exit Sub
ElseIf IsEmpty(Range("b8").Value) = True Then
MsgBox "Please complete 'Date of Assessment' before saving"
Exit Sub
End If
'Copies a range contained within the "Checksheet" and pastes
'it into the next available row on the "Data" sheet
'The reason it is in a straight row as opposed to sporadic cell
'references is because I have set the sheet up this way for simplicity
Range("M14:BP14").Copy
Sheets("Data").Range("A" & Rows.Count).End(xlUp).Offset(1, 0).PasteSpecial xlPasteValues
ActiveWindow.ScrollRow = 1
Workbooks("Call Feedback Form V0.42.xlsm").Sheets("Checksheet").Activate
Call CopyRenameWorksheet
Workbooks("Call Feedback Form V0.42.xlsm").Sheets("Checksheet").Activate
End Sub
.
Sub CopyRenameWorksheet()
'This renames the worksheet based on cell references and archives to another workbook
Dim ws As Worksheet
Set wh = Worksheets(ActiveSheet.Name)
ActiveSheet.Copy After:=Worksheets(Sheets.Count)
If wh.Range("B3").Value <> "" Then
ActiveSheet.Name = wh.Range("B3").Value & " " & Format(wh.Range("D4").Value, ("yymmdd")) & " " & wh.Range("B4").Value
ActiveSheet.Move After:=Workbooks( _
"Archived Quality Forms.xlsx").Sheets(1)
End If

I think your problem is due to the fact that you are referencing the wrong sheet. Make sure you always fully qualify when you will be using different sheets.
I would start the Subs with
dim ws as worksheet
set ws = Worksheets("Sheetname")
and then you can change all of the ranges to be like ws.range("A1")
This way they will always reference the range on the correct sheet.
I would start by going through your code and making sure that every single reference to a range is referencing a worksheet and a range on said worksheet.
Hope it helps!

Your problem is with this line of code
Range("M14:BP14").Copy
You need to explicitly state what sheet youre referring too. Like i.e.
ThisWorkbook.Sheets("Sheet1").Range("M14:BP14").Copy

Related

Copy and Paste with criteria VBA or Filter

My name is Pedro and I am very beginner in VBA development. I have a question about copy and paste with criteria. I have code that reports to me an error 1004 workbooks open when I run a macro that copy and paste row in another workbooks. How can I fix this error with the following code?
Dim LastRow As Integer, i As Integer, erow As Integer
LastRow = ActiveSheet.Range("A" & Rows.Count).End(xlUp).Row
Application.ScreenUpdating = False
Application.Calculation = xlManual
For i = 2 To LastRow
'If Cells(i, 9) = "Aline" Then
'Range(Cells(i, 1), Cells(i, 16)).Select
'Selection.Copy
'Workbooks.Open Filename:="L:\Controle\Assessoria Tecnica\Pessoas\Aline.xlsx"
'Worksheets("Plan1").Select
'erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
'ActiveSheet.Cells(erow, 1).Select
'ActiveSheet.Paste
'ActiveWorkbook.Save
'ActiveWorkbook.Close
'Application.CutCopyMode = False
End If
Next i
Application.ScreenUpdating = True '
Application.Calculation = xlCalculationAutomatic
MsgBox "Informações inseridas com sucesso", vbInformation
End sub
I also want to explain what my code do it. My code matches a specific condition in "I" column (like Aline, Carol, Karine, Lucas, Thiago) and after that it copies each row and pastes it in another workbook, according to the matched conditions in "I" column. So what do you think would be the problem in this situation? What can i do to fix the error? Or make a new code that copy a row with condition and paste it in another workbooks?
As for your posted code, you've commented your IF block but not the entire thing. The END IF should also be commented.
I've done similar things in the past, so let me offer some code snippets as advice. This should get you started. This is by no means the right or perfect way to do things, but it is simple to understand. After years and years of writing VB, I wouldn't write it this way. :)
Sub Open_SlaveWB()
vFile = Workbooks.Open Filename:="L:\Controle\Assessoria Tecnica\Pessoas\Aline.xlsx"
If TypeName(vFile) = "Boolean" Then Exit Sub
Set UpdateSheet = wbMaster.Sheets("Update") 'Name of the sheet in the master WB to copy into
Set wbSlave = Workbooks.Open(vFile)
Set SlaveSheet = wbSlave.Sheets("Plan1") 'Name of the sheet in the slave WB to copy from
Exit Sub
errMessage:
MsgBox Err.Number & vbCrLf & Err.Description, vbCritical, "Error!"
Resume Next
End Sub
If you're absolutely sure the path and file name will go unchanged use this, otherwise I would advise setting vfile to: Application.GetOpenFilename("Excel-files,*.xlsx", 1, "Select One File To Open", , False) which will open a file select dialog box.
I've found it more efficient to copy the sheet, to your master workbook, and get the data from there rather than subsequent slave workbooks.
Sub Copy_SlaveToMaster()
LastSlaveRow = SlaveSheet.UsedRange.Rows.Count
LastSlaveColumn = SlaveSheet.UsedRange.Columns.Count
SlaveSheet.Range(Cells(1, 1), Cells(LastSlaveRow, LastSlaveColumn)).Copy
UpdateSheet.Cells(1, 1).PasteSpecial
Exit Sub
errMessage:
MsgBox Err.Number & vbCrLf & Err.Description, vbCritical, "Error!"
Resume Next
End Sub
You obviously don't need the slave WB to stay open.
Sub Close_SlaveWB()
Application.DisplayAlerts = False
wbSlave.Close
Application.DisplayAlerts = True
Exit Sub
errMessage:
MsgBox Err.Number & vbCrLf & Err.Description, vbCritical, "Error!"
Resume Next
End Sub
From there you would just write some code to manipulate the new sheet, use the data from the new sheet as you wish.

Subscript out of range - Most computers work fine (mine included)

I am a new user of vba.
There is recently a vba problem that has left me rather clueless and helpless - subscript out of range - on a particular user's computer when every other user seems to have no issue with using the macro (myself included) hence I can't simply trial and error to troubleshoot.
Hence really need expert help from all of you! Really really appreciated!!
I have used a series of vba, which will run one after another and have pasted them in chronological order as follows.
VBA 1
Sub VBA_1()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.Outline.ShowLevels 1, 1
Next ws
End Sub
VBA 2
Sub VBA_2()
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
ws.Protect ("Password")
Next ws
End Sub
VBA 3
Sub VBA_3()
Dim iRet As Integer
Dim strPrompt As String
'Prompt
strPrompt = "This will take about 2 minutes. Click 'OK' to proceed."
'Show msgbox
iRet = MsgBox(strPrompt, vbOKCancel)
'When user clicked 'OK'..
If iRet = vbOK Then
'SaveAs Function
Dim fName As String
fName = Application.GetSaveAsFilename(, "Excel Binary Workbook (*.xlsb), *.xlsb")
If fName = "False" Then
MsgBox "File not saved.", vbOKOnly
Cancel = True
End If
Application.EnableEvents = False
ThisWorkbook.SaveAs Filename:=fName, FileFormat:=xlExcel12
Application.EnableEvents = True
' Calculate
Application.Calculate
Application.ScreenUpdating = True
' Outlet
Worksheets("Total Outlets").Activate
'Copy and Paste this portion to each worksheet
For Each cell In Range("A1")
If cell.Value = "Not Applicable" Then
ActiveSheet.Visible = xlSheetHidden
Else
Call HypMenuVRefresh
End If
Next
'End Outlet & Copy and Paste
Worksheets("D11101").Activate
For Each cell In Range("A1")
If cell.Value = "Not Applicable" Then
ActiveSheet.Visible = xlSheetHidden
Else
Call HypMenuVRefresh
End If
Next
Worksheets("D11102").Activate
For Each cell In Range("A1")
If cell.Value = "Not Applicable" Then
ActiveSheet.Visible = xlSheetHidden
Else
Call HypMenuVRefresh
End If
Next
'Hide sheets accordingly
Worksheets("Restaurant List").Visible = xlSheetVeryHidden
Worksheets("Hotel List").Visible = xlSheetVeryHidden
'Recalculate
Application.Calculate
Application.ScreenUpdating = True
'Renaming of tabs
Dim ws As Worksheet
For Each ws In ActiveWorkbook.Worksheets
If ws.Range("A2").Value = 1 Then
If ws.Visible = xlSheetVisible Then
On Error Resume Next
ws.Name = ws.Range("A10").Value
End If
End If
Next ws
'Save Workbook
ActiveWorkbook.Save
'Enable finishing screen to be 'Input'
Sheets("Input").Select
'Show msgbox
MsgBox ("Retrieval Completed!")
Else
MsgBox ("Retrieval of Data Cancelled")
End If
End Sub
I can think of the following possible causes but do not say any of them is the actual cause:
"...on a particular user's computer..."
Then:
the version of Excel/VBA is different;
somehwere a global Option Base is set (but I believe this cannot be set global, i.e. applicable to all workbooks loaded);
somewhere a separator is "hard coded" that does not conform to the Windows global setings (Control Panel --> Region and Language --> Formats --> Additional Settings);
the language differs with a reflection in VBA (e.g. a keyword/function name in the native language or identifier names with non-US ASCII 7 bit characters).
To find in where the program encounters the error (and stops), make a function that writes a status message to a file after every major step. Make sure to close the file after every message so the message is actually written.

How to call a Sub from another Sub dynamically

I have never come across this idea until now, but is it possible to set another macro to a variable within my current macro to call it from the VBA code? I have made the attempt to do so in my limited knowledge and it ain't working.
What I have is a user form that contains a combo box that is a list of reports. Then I have the selected value from that combo box matched to a specific Sub (by title). Each report has its own macro for updating each month.
I have coded the VBA of my first macro (based on a 'Run' button on the user form) to set a variable (iVal) to equal the value within the cell of the worksheet containing the matching Sub title. I was hoping I could use that variable to call the appropriate Sub title based on that value. It doesn't like the variable.
See a screenshot of the error here: https://i.imgsafe.org/a2a199edb8.png
Otherwise, I'm thinking my best option is to use an array loop. I was hoping to avoid that since this list of possible selections from this combo box is almost 50 different possibilities that could expand or diminish over time. Obviously, this would be time consuming and a challenge to manage as the list of reports and matching macros changed.
I don't even know if this is possible. This is a new VBA challenge I have never tackled before so it falls into that 'I don't know what I don't know' territory. Thanks in advance for any constructive feedback.
Private Sub Run_Click()
'Runs the Analysis
Dim ProjectWB As Workbook
Set ProjectWB = ActiveWorkbook
Dim iWS As Worksheet
Dim sName As String
Dim tName As String
Dim iName As String
Set iWS = Worksheets("Streetwise Ideas")
'Error handling for empty file fields
Application.ScreenUpdating = False
Unload Me
If TextBox1.Value = "" Then
MsgBox "Please select a Source file.", vbCritical, "Error No Source file"
If vbOK Then
UserForm1.Show
End If
Else
If TextBox2.Value = "" Then
MsgBox "Please select a Target file.", vbCritical, "Error No Target file"
If vbOK Then
UserForm1.Show
End If
Else
End If
End If
'place value of the selection from the combobox in cell D2 on "Streetwise Ideas" sheet for referencing later in the macro
iWS.Activate
Range("D2").Select
Selection.Value = cbSWIdeas
sName = TextBox1.Value
tName = TextBox2.Value
'Opens Source workbook file and sets it to variable sWB
Dim sWB As Workbook
Set sWB = Workbooks.Open(sName)
'Opens Target workbook file and sets it to variable tWB
Dim tWB As Workbook
Set tWB = Workbooks.Open(tName)
'Calls the correct macro for the combobox selection
Dim iVal As String
iVal = iWS.Range("E2").Value
If iVal <> "" Then
Call iVal
Else
'do nothing
MsgBox ("No Idea Selected.")
Exit Sub
End If
Application.ScreenUpdating = True
End Sub
You can use Application.Run to call a Macro by name
Sub Example()
Dim MacroName As String
MacroName = "HelloWorld"
Application.Run MacroName
End Sub
Sub HelloWorld()
MsgBox "Hello World!"
End Sub

Excel VBA: How to copy entire range including hidden columns

I'm looking for a VBA Macro to export data to a csv. I found this code
which after some tweaking does a great job. However, when copying from a range, Excel seems to ignore hidden columns while I want the CSV to contain all the columns. Has anyone discovered concise way to code this?
Here is the code I have so far:
Sub ExportListOrTable(Optional newBook As Boolean, Optional willNameSheet As Boolean, Optional asCSV As Boolean, Optional visibleOnly As Boolean)
'Sub CopyListOrTable2NewWorksheet()
'Works in Excel 2003 and Excel 2007. Only copies visible data.
'code source: https://msdn.microsoft.com/en-us/library/dd637097%28v=office.11%29.aspx
'improved by: Tzvi
' - replaced new worksheet with new workbook
'params:
' newBook: To create a new new sheet in the current workbook or (default) in a new workbook
' willNameSheet: To offer the user to name the sheet or (default) leave the default names
' asCSV: not implemented - will always save as CSV
' visibleOnly: to filter out any hidden columns - default false
'TODO
' -add parameter list for following options:
' - if table was not selected, copy activesheet.usedRange
' - optional saveFileType
' -
Dim New_Ws As Worksheet
Dim ACell, Data As Range
Dim CCount As Long
Dim ActiveCellInTable As Boolean
Dim CopyFormats, retrySave As Variant
Dim sheetName, user, defaultFileName, fileSaveName As String
Dim userChoice As Boolean
'Check to see if the worksheet or workbook is protected. TODO this may not be necessary anymore
If ActiveWorkbook.ProtectStructure = True Or ActiveSheet.ProtectContents = True Then
MsgBox "This macro will not work when the workbook or worksheet is write-protected."
Exit Sub
End If
'Set a reference to the ActiveCell. You can always use ACell to
'point to this cell, no matter where you are in the workbook.
Set ACell = activeCell
'Test to see if ACell is in a table or list. Note that by using ACell.ListObject, you
'do not need to know the name of the table to work with it.
On Error Resume Next
ActiveCellInTable = (ACell.ListObject.Name <> "")
On Error GoTo 0
'TODO here we will select the fields to export
'If the cell is in a list or table run the code.
If ActiveCellInTable = True Then
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
If visibleOnly = True Then
'Test if there are more than 8192 separate areas. Excel only supports
'a maximum of 8,192 non-contiguous areas through VBA macros and manual.
On Error Resume Next
With ACell.ListObject.ListColumns(1).Range 'TODO remove this "with"
CCount = .SpecialCells(xlCellTypeVisible).Areas(1).Cells.Count
End With
On Error GoTo 0
If CCount = 0 Then
MsgBox "There are more than 8192 individual areas, so it is not possible to " & _
"copy the visible data to a new worksheet. Tip: Sort your " & _
"data before you apply the filter and try this macro again.", _
vbOKOnly, "Copy to new worksheet"
Exit Sub
Else
'Copy the visible cells.
ACell.ListObject.Range.Copy
End If
Else
'The user indicated he wants to copy hidden columns too.
'**********************************************************
'HOW DO I PROPERLY IMPLEMENT THIS PART?
'**********************************************************
MsgBox ("You wanted to copy hidden columns too?")
ActiveSheet.UsedRange.Copy
End If
Else
' MsgBox "Select a cell in your list or table before you run the macro.", _
' vbOKOnly, "Copy to new worksheet"
userChoice = MsgBox("A Table/Table protion is not selected. Do you want to export the entire page?", vbYesNo)
If userChoice = False Then Exit Sub
ActiveSheet.UsedRange.Copy
'Exit Sub
End If
'Add a new Worksheet/WorkBook.
If newBook = False Then
Set New_Ws = Worksheets.Add(after:=Sheets(ActiveSheet.Index))
Else
Set New_Ws = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
End If
'Prompt the user for the worksheet name.
If willNameSheet = True Then
sheetName = InputBox("What is the name of the new worksheet?", _
"Name the New Sheet")
On Error Resume Next
New_Ws.Name = sheetName
If Err.Number > 0 Then
MsgBox "Change the name of sheet : " & New_Ws.Name & _
" manually after the macro is ready. The sheet name" & _
" you typed in already exists or you use characters" & _
" that are not allowed in a sheet name."
Err.Clear
End If
On Error GoTo 0
End If
'Paste the data into the new worksheet.
With New_Ws.Range("A1")
.PasteSpecial xlPasteColumnWidths
.PasteSpecial xlPasteValuesAndNumberFormats
.Select
Application.CutCopyMode = False
End With
Application.ScreenUpdating = False
'If you did not create a table, you have the option to copy the formats.
If ActiveCellInTable = False Then
Application.Goto ACell
CopyFormats = MsgBox("Do you also want to copy the Formatting?", _
vbOKCancel + vbExclamation, "Copy to new worksheet")
If CopyFormats = vbOK Then
ACell.ListObject.Range.Copy
With New_Ws.Range("A1")
.PasteSpecial xlPasteFormats
Application.CutCopyMode = False
End With
End If
End If
'Select the new worksheet if it is not active.
Application.Goto New_Ws.Range("A1")
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
'Now we're ready to save our new file as excel format
defaultFileName = ActiveWorkbook.Name
user = Environ("userprofile")
'marker getfilename: to return to if we need to look for a new filename
getfilename:
ChDir user & "\Desktop"
fileSaveName = Application.GetSaveAsFilename(defaultFileName & ".csv", "Comma Delimited Format (*.csv), *.csv")
If fileSaveName <> "False" Then
'error handling for 'file already exists and the user clicks 'no'
On Error Resume Next
ActiveWorkbook.SaveAs fileName:=fileSaveName, FileFormat:=xlCSV, ReadOnlyRecommended:=True, CreateBackup:=False, ConflictResolution:=xlUserResolution
If Err.Number = 1004 Then
'Offer user two options: To try a different filename or cancel the entire export
retrySave = MsgBox(Err.Description, vbRetryCancel, "Error creating file")
If retrySave = vbRetry Then
GoTo getfilename
Else
GoTo cancelprocedure
End If
End If
On Error GoTo 0
Else
GoTo cancelprocedure
End If
Exit Sub
cancelprocedure:
ActiveWorkbook.Close saveChanges:=False
Exit Sub
End Sub
Update:
In response to shagans concern. The parameter list on line one is intended to be set by another Macro as such:
Sub ExportVisibleAsCSV
Call ExportListOrTable(newBook:=True, willNameSheet:=False, asCSV:=True, visibleOnly:=True)
End Sub
Updating now that example code is available:
Ok looking at the code you posted, I see a bool named visibleOnly but I don't see where it gets set. Your ability for the logic to reach UsedRange.Copy entirely depends on that being set to false. The comment above ACell.ListObject.Range.Copy indicates that if you reach that statement you are only copying visible cells. In order to copy the hidden cells, visibleOnly would need to be set to false (bypassing the rest of the CCount stuff). So I would be interested in knowing how that bool is set and checking to see what its value is set to when you are running your code.
Update 2:
You need to set the value of your visibleOnly boolean somehow.
here's some code I edited that creates a message box that allows the user to say "yes" or "no" to "do you want to copy hidden data too?" that answer will dictate the value of visibleOnly which in turn dictates which flow they enter.
In addition to that, your assumption that ACell.ListObject.Range.Copy would only copy visible cells appears to have been incorrect. Instead that is being replaced with the specialcell type for visible cells.
Finally, vbYesNo does not actually return a boolean value. Instead it returns vbYes or vbNo which are vb type enumerators (value 6 and 7 respectively). So setting a bool to the value of a vbYesNo will always return True (as a value exists and essentially it just evaluates iferror).
So I changed that bit as well so it now properly checks the Yes/No condition on your userchoice (which is no longer a bool).
here's the code:
Dim ACell, Data As Range
Dim CCount As Long
Dim ActiveCellInTable As Boolean
Dim CopyFormats, retrySave As Variant
Dim sheetName, user, defaultFileName, fileSaveName As String
'Check to see if the worksheet or workbook is protected. TODO this may not be necessary anymore
If ActiveWorkbook.ProtectStructure = True Or ActiveSheet.ProtectContents = True Then
MsgBox "This macro will not work when the workbook or worksheet is write-protected."
Exit Sub
End If
'Set a reference to the ActiveCell. You can always use ACell to
'point to this cell, no matter where you are in the workbook.
Set ACell = ActiveCell
'Test to see if ACell is in a table or list. Note that by using ACell.ListObject, you
'do not need to know the name of the table to work with it.
On Error Resume Next
ActiveCellInTable = (ACell.ListObject.Name <> "")
On Error GoTo 0
'TODO here we will select the fields to export
'If the cell is in a list or table run the code.
If ActiveCellInTable = True Then
CopyHidden = MsgBox("Would you like to copy hidden data also?", vbYesNo, "Copy Hidden Data?")
If CopyHidden = vbYes Then
visibleOnly = False
ElseIf CopyHidden = vbNo Then
visibleOnly = True
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
If visibleOnly = True Then
'Test if there are more than 8192 separate areas. Excel only supports
'a maximum of 8,192 non-contiguous areas through VBA macros and manual.
On Error Resume Next
With ACell.ListObject.ListColumns(1).Range 'TODO remove this "with"
CCount = .SpecialCells(xlCellTypeVisible).Areas(1).Cells.Count
End With
On Error GoTo 0
If CCount = 0 Then
MsgBox "There are more than 8192 individual areas, so it is not possible to " & _
"copy the visible data to a new worksheet. Tip: Sort your " & _
"data before you apply the filter and try this macro again.", _
vbOKOnly, "Copy to new worksheet"
Exit Sub
Else
'Copy the visible cells.
ACell.ListObject.Range.SpecialCells(xlCellTypeVisible).Copy
' Only visible cells within the table are now in clipboard
End If
Else
'The user indicated he wants to copy hidden columns too.
MsgBox ("You wanted to copy hidden columns too?")
ACell.ListObject.Range.Copy
' All table data cells including hidden are now in clipboard
End If
Else
' MsgBox "Select a cell in your list or table before you run the macro.", _
' vbOKOnly, "Copy to new worksheet"
userChoice = MsgBox("A Table/Table protion is not selected. Do you want to export the entire page?", vbYesNo)
If userChoice = vbNo Then Exit Sub
ActiveSheet.UsedRange.Copy
'Entire sheet range is now in clipboard (this is not always accurate)
'Exit Sub
End If
Assign the Value of the range to your target range instead of using the .Copy method:
Sub ExportCSV(source As Range, filename As String)
Dim temp As Workbook
Set temp = Application.Workbooks.Add
Dim sheet As Worksheet
Set sheet = temp.Worksheets(1)
Dim target As Range
'Size the target range to the same dimension as the source range.
Set target = sheet.Range(sheet.Cells(1, 1), _
sheet.Cells(source.Rows.Count, source.Columns.Count))
target.Value = source.Value
temp.SaveAs filename, xlCSV
temp.Close False
End Sub
This also has the benefit of not nuking whatever the user might have on the clipboard.

Macro for multiple sheets doesn't work properly

Sub RunMacroOnAllSheetsToRight()
For i = ActiveSheet.Index To Sheets.Count
Call MyFunction(i)
Next i
End Sub
Function MyFunction(i)
'Code goes here
Columns("R:R").ColumnWidth = 8.1
[S1].Resize(, 14).EntireColumn.Insert
MsgBox "I'm currently on sheet " & ThisWorkbook.Sheets(i).name
End Function
I found a sample of code for running macro that should run on all sheets on the right from the active one, but it is not working, it keeps running on one sheets, but the msgbox shows me that the sheets are changed(each time it displays different name). Can you help me? I am new to vba-excel.
You need to activate each sheet. Then activate original sheet.
Sub RunMacroOnAllSheetsToRight()
Dim a As Integer
a = ActiveSheet.Index 'Save current sheet
For i = a To Sheets.Count
Call MyFunction(i)
Next i
Sheets(a).Activate 'At the end, activate original sheet
End Sub
Function MyFunction(i)
'Code goes here
Sheets(i).Activate 'Activate each sheet
Columns("R:R").ColumnWidth = 8.1
[S1].Resize(, 14).EntireColumn.Insert
MsgBox "I'm currently on sheet " & ActiveSheet.Name 'Trustworthy information
End Function