Excel to Word Macro resulting in Run-time error 462 - excel

I've written a VBA macro which resides in an Excel workbook. When run, it will open an existing Word document (which is stored in the same directory as the Excel workbook), copy some content from cells in the Excel workbook into the Word document, save the Word doc under a new name (in the same directory) and kill the original Word doc. This process works as expected on first run. But on a second run, I get a Run-time error 462. I'm sure it's due to my ignorance around creating and using application instances within VBA code (I've just begun learning). I'm using Microsoft 365 Apps for Enterprise.
Sub ExcelToWord()
Dim wordApp As Word.Application
Dim wDoc As Word.Document
Dim strFile As String
'Open Word file
strFile = ("G:\HOME\Word File.docx")
Set wordApp = CreateObject("word.Application")
Set wDoc = wordApp.Documents.Open("G:\HOME\Word File.docx")
wordApp.Visible = True
'Copy data from Excel to Word
wDoc.ContentControls(1).Range.Text = Sheets("Model").Cells(4, 2)
wDoc.ContentControls(2).Range.Text = Format(Date, "mm/dd/yyyy")
wDoc.ContentControls(3).Range.Text = Sheets("Model").Range("X4")
Word.Application.Activate
'Save Word Document with new name
ActiveDocument.SaveAs Filename:=ActiveDocument.Path & "\" & Format(Sheets("Model").Range("B14"), "YYYY") & " " & ThisWorkbook.Sheets("Model").Range("B4") & " " & Format(Date, "YYYY-mm-dd") & ".docx"
'Delete original Word document
Kill strFile
End Sub
I've researched this for hours and tried multiple solutions, including commenting out all of the Copy Data block to try and zero in on the error. But no luck. I hope I've posted this request properly. Thank you in advance for any help.

Is this what you are trying? I have commented the code but if you face any issues, simply ask. What you have is Early Binding. I have used Late Binding so that you do not need to add any references to the MS Word application.
Option Explicit
Private Const wdFormatXMLDocument As Integer = 12
Sub ExcelToWord()
Dim oWordApp As Object, oWordDoc As Object
Dim FlName As String
Dim FilePath As String
Dim NewFileName As String
'~~> This is the original word file. Change as applicable
FlName = "G:\HOME\Word File.docx"
'~~> Check if word file exists
If Dir(FlName) = "" Then
MsgBox "Word File Not Found"
Exit Sub
End If
'~~> Establish an Word application object if open
On Error Resume Next
Set oWordApp = GetObject(, "Word.Application")
'~~> If not open then create a new word application instance
If Err.Number <> 0 Then
Set oWordApp = CreateObject("Word.Application")
End If
Err.Clear
On Error GoTo 0
oWordApp.Visible = True
Set oWordDoc = oWordApp.Documents.Open(FlName)
With oWordDoc
'~~> File path
FilePath = .Path & "\"
'~~> New File name
NewFileName = FilePath & _
Format(ThisWorkbook.Sheets("Model").Range("B14").Value, "YYYY") & _
" " & _
ThisWorkbook.Sheets("Model").Range("B4").Value & _
" " & _
Format(Date, "YYYY-mm-dd") & ".docx"
'~~> Copy data from Excel to Word
.ContentControls(1).Range.Text = Sheets("Model").Cells(4, 2).Value2
.ContentControls(2).Range.Text = Format(Date, "mm/dd/yyyy")
.ContentControls(3).Range.Text = Sheets("Model").Range("X4").Value2
'~~> Save the word document
.SaveAs Filename:=NewFileName, FileFormat:=wdFormatXMLDocument
DoEvents
End With
'~~> Delete original Word document
Kill FlName
End Sub

Related

How to Run PPTM macro from excel for Embedded PPTM file

I have an Excel file with a .PPTM embedded into a sheet (nothing else is on the sheet). I want to run a macro that is in the PPTM file.
The problem is the last line of code to run the macro. The cell in worksheet "PPTM" that has the embedded file has a formula of "=EMBED("Presentation","")"
Sub run_ppt_macro()
fName = ActiveWorkbook.Name
Path = ActiveWorkbook.Path
Worksheets("PPTM").OLEObjects("PPT_Temp_19").Verb 0
Dim PPTObj As Object
Set myPP = GetObject(, "PowerPoint.Application")
Set PPTObj = myPP.ActivePresentation
PPTObj.Run PPTObj.Name & "!Main", fName, Path
End Sub
Thanks Shyam, that was part of the problem. Because the file is opened through IE or Email, it opens in a very odd place that errors the macro. I solved the problem by saving both the data (XLSM) file and the template (PPTM) file to the temp directory, before creating the new report.
Sub auto_open()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
fName = ActiveWorkbook.Name
tempath = IIf(Environ$("tmp") <> "", Environ$("tmp"), Environ$("temp")) 'finds the temporary evironment on the current machine
ActiveWorkbook.SaveAs Filename:=(tempath & "\" & fName)
MsgBox "Your report " & tempath & "\" & fName & " should be completed within 5 minutes." & Chr(10) & Chr(10) & "Please check your PowerPoint application at that time." & Chr(10) & Chr(10) & "Thank you.", vbInformation
Dim PPTObj As Object
Worksheets("PPTM").OLEObjects("PPT_Temp_19").Verb 3 'opens the embedded object
Set myPP = GetObject(, "PowerPoint.Application") 'get the PowerPoint object
Set PPTObj = myPP.ActivePresentation 'Get the presentation that was opened
tempath = IIf(Environ$("tmp") <> "", Environ$("tmp"), Environ$("temp")) 'finds the temporary evironment on the current machine
Template = tempath & "\template.pptm" 'creates path and name for temp file
PPTObj.SaveAs Filename:=(Template) 'saves temp file
myPP.Presentations.Open (Template) 'opens the saved file
Worksheets("PPTM").OLEObjects("PPT_Temp_19").Object.Close
myPP.Run Template & "!Main", fName, tempath 'runs the macro
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub

Excel VBA to modify word documents with bookmarks

I have a problem with my code below. I created an userform in order to generate Word documents automatically which I prepared (I created a bunch of bookmarks).
It works really well on my computer but not on another computer and I really don't understand why. Both computers have the same Office version (1902) and I have activated the Microsoft Word 16.0 Object Library reference.
What I mean by "it's not working" it is that the Word document will open but no action will be Performed... And also I have not a single error message.
Private Sub BCO_Click()
Dim objWord As New Word.Application, wordDoc As Word.Document
'FCO is the userform and the subobjects are combobox entries.
If FCO.SOCIETENAME <> "" And FCO.NUMCO <> "" And FCO.ComboBox1 <> "" Then
Dim pathcovierge As String
Dim pathconew As String
'Path of the files needed there, copy from an existing (pathcovierge) to a new one (pathconex)
pathcovierge = path & "\Documents_Vierges\" & "CO.docx"
pathconew = path & "\CO\CO_" & UCase(FCO.SOCIETENAME.Value) & "_" & UCase(FCO.NUMCO.Value) & ".docx"
If Dir(path & "\CO\", vbDirectory) = "" Then MkDir path & "\CO\"
'If file already open, msgbox
On Error Resume Next
FileCopy pathcovierge, pathconew
If Err > 0 Then
MsgBox "Veuillez fermer CO.docx afin de générer un CO."
End If
'opening of the new word document
objWord.Visible = True
objWord.Documents.Open pathconew
Dim DocDest As Word.Document
Set DocDest = GetObject(pathconew)
'THIS IS NOT WORKING.
DocDest.Bookmarks("WNUMCO").Range.Text = FCO.NUMCO.Value
DocDest.Bookmarks("WDATECO").Range.Text = FCO.DATECO.Value
DocDest.Bookmarks("WNOMCLIENT").Range.Text = FCO.SOCIETENAME.Value
'Saving (working)
DocDest.SaveAs pathconew
AppActivate ("CO_" & UCase(FCO.SOCIETENAME.Value) & "_" & UCase(FCO.NUMCO.Value) & ".docx")
On Error GoTo 0
Else
MsgBox "Veuillez rentrer tous les champs obligatoires (*)"
End If
End Sub
I took a look in your code and made some changes (also see my comments in the code):
I enhanced the readability by early exiting the procedure instead of using 'arrow code'.
Now the opened Word document will be set to the variable immediately.
Your error handling suppressed all errors. I changed it, but you should add proper error handling though. Think about splitting your procedure in several separate procedures.
This should lead you to your result:
Private Sub BCO_Click()
If FCO.SOCIETENAME = "" Or FCO.NUMCO = "" Or FCO.ComboBox1 = "" Then
MsgBox "Veuillez rentrer tous les champs obligatoires (*)"
Exit Sub
End If
Dim pathcovierge As String
pathcovierge = path & "\Documents_Vierges\" & "CO.docx"
Dim pathconew As String
pathconew = path & "\CO\CO_" & UCase(FCO.SOCIETENAME.Value) & "_" & UCase(FCO.NUMCO.Value) & ".docx"
If Dir(path & "\CO\", vbDirectory) = "" Then MkDir path & "\CO\"
'This seems to be the reason why you get no error:
On Error Resume Next
FileCopy pathcovierge, pathconew
If Err > 0 Then
MsgBox "Veuillez fermer CO.docx afin de générer un CO."
End If
'This will let you see a possible error, but you should think about implement a proper error handling though:
On Error Goto 0
Dim objWord As Word.Application
Set objWord = New Word.Application
objWord.Visible = True
Dim docDest As Word.Document
'If the problem was to get the handle to the opened document, this should work better:
Set docDest = objWord.Documents.Open(pathconew)
docDest.Bookmarks("WNUMCO").Range.Text = FCO.NUMCO.Value
docDest.Bookmarks("WDATECO").Range.Text = FCO.DATECO.Value
docDest.Bookmarks("WNOMCLIENT").Range.Text = FCO.SOCIETENAME.Value
docDest.SaveAs pathconew
AppActivate ("CO_" & UCase(FCO.SOCIETENAME.Value) & "_" & UCase(FCO.NUMCO.Value) & ".docx")
End Sub

combining multiple workbooks into one worksheet

I am currently trying to get data recorded into excel workbooks to be automatically copied over onto one "mass data" sheet. The files are named by date ex. "5-28-17". There is one for each day of the month. I'd like to collect all data into one sheet, as previously stated, in order by date descending.
I am currently using this code which should place all of the different workbooks onto their own worksheet, but I am having issues with that as well.
Option Explicit
Const path As String = "C:\Users\dt\Desktop\dt kte\"
Sub GetSheets()
Dim FileName As String
Dim wb As Workbook
Dim sheet As Worksheet
FileName = Dir(path & "*.xls*")
Do While FileName <> ""
Set wb = Workbooks.Open(FileName:=path & FileName, ReadOnly:=True)
For Each sheet In wb.Sheets
sheet.Copy After:=ThisWorkbook.Sheets(1)
Next sheet
wb.Close
FileName = Dir()
Loop
End Sub
I am trying to do this with VBA. There are 15 columns in the sheets I'm pulling from and the sheet I want to copy to. All line up perfectly. Is there a way to move the sheets from the WB I'm currently working on which should contain a worksheet for each WB onto one mass worksheet? Or can I pull all data directly from the folder with all of the workbooks saved by date to one worksheet?
I would use this AddIn.
https://www.rondebruin.nl/win/addins/rdbmerge.htm
It will do what you want, and a whole lot more as well.
Consider using an MS Access database. Not to worry if you do not have the Office GUI .exe app installed. Because you use a Windows machine, you do have its Jet/ACE SQL Engine (.dll files).
CREATE DATABASE
Sub CreateDatabase()
On Error GoTo ErrHandle
Dim fso As Object, olDb As Object, db As Object
Const dbLangGeneral = ";LANGID=0x0409;CP=1252;COUNTRY=0"
Const strpath As String = "C:\Path\To\ExcelDatabase.accdb"
' CREATE DATABASE
Set fso = CreateObject("Scripting.FileSystemObject")
Set olDb = CreateObject("DAO.DBEngine.120")
If Not fso.FileExists(strpath) Then
Set db = olDb.CreateDatabase(strpath, dbLangGeneral)
End If
MsgBox "Successfully created database!", vbInformation
ExitSub:
Set db = Nothing: Set olDb = Nothing: Set fso = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume ExitSub
End Sub
CREATE, POPULATE, EXPORT EXCEL TABLE (Excel files never opened)
Sub CreateTable()
On Error GoTo ErrHandle
Dim conn As Object, rst As Object
Dim constr As String, FileName As String, i As Integer
Const xlpath As String = "C:\Users\dt\Desktop\dt kte\"
Const accpath As String = "C:\Path\To\ExcelDatabase.accdb"
' CONNECT TO DATABASE
constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & accpath & ";"
Set conn = CreateObject("ADODB.Connection")
conn.Open constr
i = 1
FileName = Dir(xlpath & "*.xls*")
Do While FileName <> ""
If i = 1 Then
' CREATE TABLE VIA MAKE TABLE QUERY
conn.Execute "SELECT * INTO MyExcelTable" _
& " FROM [Excel 12.0 Xml;HDR=Yes;" _
& " Database=" & xlpath & FileName & "].[Sheet1$]"
Else
' POPULATE VIA APPEND QUERY
conn.Execute "INSERT INTO MyExcelTable" _
& " SELECT * FROM [Excel 12.0 Xml;HDR=Yes;" _
& " Database=" & xlpath & FileName & "].[Sheet1$]"
End If
i = i + 1
FileName = Dir()
Loop
' EXPORT TO EXCEL
Set rst = CreateObject("ADODB.Recordset")
rst.Open "SELECT * FROM MyExcelTable", conn
ThisWorkbook.Worksheets("MASS_DATA").Range("A1").CopyFromRecordset rst
' CLOSE CONNECTION
rst.Close: conn.Close
MsgBox "Successfully created and populated table!", vbInformation
ExitSub:
Set rst = Nothing: Set conn = Nothing
Exit Sub
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Resume ExitSub
End Sub

Open File From Outlook to Excel and Save as Different Format Depending on Sender

I use Stack Overflow a lot but this is my first post. I know just enough to be dangerous with VBA.
I originally wrote this piece of code for Outlook - its original purpose was to rename any attachment file and save it in a specific directory (I still need that functionality for the one person who sends me files denoted below as email#email.com).
Now I have more than one person sending files and need to modify the script to determine who the sender of the file is and (I know one sender always sends the attachment as an Excel XLSX file but I need it as a CSV) open the XLSX file in excel and save it as a pure CSV.
Obviously my method isn't working and I can't find any cases similar to what I'm trying to do on Stack Overflow. Is anyone willing to help me figure this out? Many thanks to everyone for all your help!
This is what I have now but my If statement doesn't appear to be working...
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim saveFolder2 As String
Dim dateFormat
dateFormat = Format(Now, "yyyy-mm-dd H-mm")
saveFolder = "c:temp1"
saveFolder2 = "c:\temp2"
' CASE 1
If objAtt.SenderName = "Sender's First & Last Name" Then
For Each objAtt In itm.Attachments
' open excel
Workbooks.Open (objAtt)
' save as csv to queue directory for upload to FTP site
ActiveWorkbook.SaveAs FileName:=saveFolder2 & "\" & dateFormat & ".csv",FileFormat:=CSV, CreateBackup:=False
ActiveWorkbook.Saved = True
ActiveWindow.Close
Set objAtt = Nothing
End If
' CASE 2
If objAtt.SenderName = "email#email.com" Then
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & dateFormat & "FC.csv"
Set objAtt = Nothing
Next
End If
End Sub
After David's modifications/suggestions, the code looks like this:
Hi #DavidZemens! Thank you so much for your well thought out answer and for pointing out the issues; your method makes a lot of sense to me. I have reconfigured the code with your suggestions, and I am getting a "Runtime Error 91 - Object Variable or With block variable not set" error which highlights the first line of my "If" statement. Can you identify what I might be doing incorrectly to get this error?
Option Explicit
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim saveFolder2 As String
Dim dateFormat
Const xlCSV As Long = 6
Dim xlsxPath As String
Dim wb As Object
Dim oExcel As Object
Set oExcel = CreateObject("Excel.Application")
dateFormat = Format(Now, "yyyy-mm-dd H-mm")
saveFolder = "c:\temp1"
saveFolder2 = "c:\temp2"
'CASE 1
If objAtt.SenderName = "John Smith" Then
xlsxPath = saveFolder2 & "\" & dateFormat & ".xlsx"
objAtt.SaveAsFile xlsxPath
' use excel to open and save the file as csv
Set wb = oExcel.Workbooks.Open(xlsxPath)
wb.SaveAs FileName:=Replace(xlsxPath, ".xlsx", ".csv"), FileFormat:=xlCSV
wb.Close
oExcel.Quit
End If
'CASE 2
If objAtt.SenderName = "email#email.com" Then
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & dateFormat & ".csv"
Set objAtt = Nothing
Next
End If
End Sub
After the most recent suggestions this is the new code with a new error
The error it gives me when a new email comes in is that the array is out of bounds and highlights the line with that says: Set objAtt = itm.Attachments(0)
Public Sub saveAttachtoDisk(itm As Outlook.MailItem)
Dim objAtt As Outlook.Attachment
Dim saveFolder As String
Dim saveFolder2 As String
Dim dateFormat
Const xlCSV As Long = 6
Dim xlsxPath As String
Dim wb As Object
Dim oExcel As Object
Set oExcel = CreateObject("Excel.Application")
dateFormat = Format(Now, "yyyy-mm-dd H-mm")
saveFolder = "c:\temp1"
saveFolder2 = "c:\temp2"
xlsxPath = saveFolder2 & "\" & dateFormat & ".xlsx"
**'Case 1**
If itm.SenderName = "John Smith" Then
If itm.Attachments.Count > 0 Then <-- note: I had this as <> and had same error
Set objAtt = itm.Attachments(0)
Else: GoTo EarlyExit
End If
End If
objAtt.SaveAsFile xlsxPath
'## Use excel to open and save the file:
Set wb = oExcel.Workbooks.Open(xlsxPath)
wb.SaveAs FileName:=Replace(xlsxPath, ".xlsx", ".csv"), FileFormat:=xlCSV
wb.Close
'## Get rid of the XLSX version if it's no longer needed
On Error Resume Next
Kill xlsxPath
On Error GoTo 0
EarlyExit:
oExcel.Quit
**' Case 2**
If itm.SenderEmailAddress = "email#email.com" Then
For Each objAtt In itm.Attachments
objAtt.SaveAsFile saveFolder & "\" & dateFormat & "FranklinCounty.csv"
Set objAtt = Nothing
Next
End If
This is an error:
Workbooks.Open (objAtt)
Because Open method expects a string file path, not an Outlook.Attachment object.
Also, because I don't see any early-bound reference to the Excel object model, so you can probably expect a compile error: User-defined type not defined on the Workbooks.Open line. You'll need to create an object to hold Excel Application:
Dim oExcel as Object
Set oExcel = CreateObject("Excel.Application")
Further, your variable CSV is not declared, nor assigned any value, so that will most likely raise another error if you get the code to compile.
'## Require explicit declaration of Excel constants, unless you're using early-binding
Const xlCSV as Long = 6
NOTE: Using Option Explicit at the top of your code modules will prevent you from writing hacky code with undeclared variables, unenumerated constants, typos in variable names, etc.
Since you can't use Workbooks.Open on an Attachment, first, you want to Save the attachment to disk, then use Excel to open the saved file (from disk), then you can use the SaveAs to save it as different format. This will result in duplicate files (one XLSX, and one CSV), you can use the Kill statement on the one you don't want to keep.
Dim xlsxPath As String
Dim wb as Object 'Excel.Workbook
xlsxPath = saveFolder2 & "\" & dateFormat & ".xlsx"
'## This assumes the file will always be XLSX format
'## get a handle on your mail item:
If itm.Attachments.Count <> 0 Then
Set objAtt = itm.Attachments(1)
Else: Goto EarlyExit
End If
objAtt.SaveAsFile xlsxPath
'## use Excel to open and save the file:
Set wb = oExcel.Workbooks.Open(xlsxPath)
wb.SaveAs FileName:=Replace(xlsxPath, ".xlsx", ".csv"), FileFormat:=xlCSV
wb.Close
'## Get rid of the XLSX version if it's no longer needed
On Error Resume Next
Kill xlsxPath
On Error GoTo 0
Then, quit Excel before your End Sub:
EarlyExit:
oExcel.Quit()
End Sub

Running macro (to assign linked cells to all checkboxes on given sheets) on all files in a folder

I am trying to reassign all the linked cells for checkboxes on three given worksheets in a large collection of workbooks.
The macro I have works successfully on any book I have open:
Sub CheckBoxesControl()
On Error Resume Next
Dim i As Long
For i = 1 To 400
Sheet4.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AA" & i
Sheet21.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AB" & i
Sheet22.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AC" & i
Next i
End Sub
However I want to run this across a large number of sheets, so I tried the following:
Sub CheckBoxesControl()
On Error Resume Next
Dim path As String
Dim file As String
Dim wkbk As Workbook
Dim i As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
path = "C:\file\path\"
file = Dir(path)
Do While Not file = ""
Workbooks.Open (path & file)
Set wkbk = ActiveWorkbook
For i = 1 To 400
Sheet4.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AA" & i
Sheet21.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AB" & i
Sheet22.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AC" & i
Next i
wkbk.Save
wkbk.Close
file = Dir
Loop
End Sub
The macro certainly opens and closes each file, and runs without error, but it is not having the desired affect.
It only changes the check boxes for the sheet I run the macro from still (despite apparently opening saving and closing all the others).
Am I failing to correctly set the active workbook?
EDIT 1: Suggested fix (failed)
Method suggested in comments (proved unsuccessful):
Sub CheckBoxesControl()
On Error Resume Next
Dim path As String
Dim file As String
Dim wkbk As Workbook
Dim i As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
path = "C:\file\path\"
file = Dir(path)
Do While Not file = ""
Set wkbk = Workbooks.Open(path & file)
For i = 1 To 400
wkbk.Sheet4.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AA" & i
wkbk.Sheet21.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AB" & i
wkbk.Sheet22.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AC" & i
If Err.Number <> 0 Then
End If
Next i
wkbk.Save
wkbk.Close
file = Dir
Loop
End Sub
EDIT 2: REMOVING ON ERROR RESUME NEXT
Suggestedion to remove the error ignoring has illustrated the following: when the macro runs an error:
Run-time error 1004
The item with the specific name wasn't found.
Debugging this error highlights:
Sheet4.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AA" & i
I believe I realise what this issue is: I'm using a "go between 1 and 400" loop to ensure I catch all the checkboxes on each page, but there isn't a checkbox for each one of those instances, (checkbox1 doesn't exist for example, on all pages - notably not on sheet 4)
I remember now this is why I had On error resume next there in the first place... but I need "next" to be the next "i" in the loop, not the next expression completely.
Update 4
For those keeping score at home, the problem is that OP was using the sheets CodeName, which cannot be used when referring to it from a macro in another spreadsheet.
Modify to accept the worksheet Name, and either of the subs can be called like:
Dim ws As Worksheet
Set ws = wkbk.Sheets("10. Prevention Finance")
UpdateChkBoxes3 ws, "ChkBoxOutput!AA"
Set ws = wkbk.Sheets("...") '#Modify the sheet name
UpdateChkBoxes3 ws, "ChkBoxOutput!AB"
Set ws = wkbk.Sheets("...") '#Modify the sheet name
UpdateChkBoxes3 ws, "ChkBoxOutput!AC"
Update 3 (non-ActiveX Checkboxes)
Sub UpdateChkBoxes3(sht as Worksheet, lnkdCell as String)
Dim cb as CheckBox
Dim cbNum As Integer
With sht
For Each cb In sht.CheckBoxes
cbNum = Replace(cb.Name, "Check Box ", vbNullString)
cb.LinkedCell = lnkdCell & cbNum
Next
End With
I also revised the sub in Update 2, previously had pasted in my testing code, instead of the proper sub that requires sht/lnkdCell as arguments.
Update 2
To account for non-indexed checkbox names, but still looping over all checkboxes in each worksheet, call this subroutine. I attempt to get the numeric value from the checkbox's .Name property, this should relate it to the cell location just like your i indexing did before, only you will avoid errors where checkboxes don't exist, because we're not looping over an Index, we're looping over the shapes themselves. This should work with ActiveX checkboxes:
Sub UpdateChkBoxes2(sht As Worksheet, lnkdCell As String)
'To address non-sequential/missing check box names not aligned with index
Dim cb As OLEObject
Dim cbNum As Integer
With sht
For Each cb In sht.OLEObjects
If cb.progID Like "Forms.CheckBox*" Then
cbNum = Replace(cb.Name, "Check Box ", vbNullString)
cb.LinkedCell = lnkdCell & cbNum
End If
Next
End With
End Sub
Update
Try something like this, which assumes CheckBoxes are named sequentially according to their index, and that there are no missing indices.
UpdateChkBoxes Sheet4, "ChkBoxOutput!AA"
UpdateChkBoxes Sheet21, "ChkBoxOutput!AB"
UpdateChkBoxes Sheet22, "ChkBoxOutput!AC"
'## Replaced the following error-prone code:
'For i = 1 To .CheckBoxes.Count
' wkbk.Sheet4.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AA" & i
' wkbk.Sheet21.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AB" & i
' wkbk.Sheet22.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AC" & i
' If Err.Number <> 0 Then
'
' End If
'Next i
Then, include this subroutine:
Sub UpdateChkBoxes(sht as Worksheet, lnkdCell as String)
With sht
For i = 1 to .CheckBoxes.Count
.CheckBoxes("Check Box " & i).LinkedCell = lnkdCell & i
Next
End With
End Sub
Original Response
OK, I think the problem is that nothing in your code is actually iterating over the files within a folder. You will need to use a FileSystemObject to do this. You can enable reference to the Microsoft Scripting Runtime dictionary, or, simply declare these variables as generic Object instead of Scripting....
Create an FSO, then assign a folder, and loop over the File objects within this folder. Open the file, and then pass it to a subroutine to perform your checkbox operations.
Something like this:
Option Explicit
Sub LoopFiles()
'## Requires reference to Microsoft Scripting Runtime Library
Dim path As String
Dim fso As New Scripting.FileSystemObject
Dim folder As Scripting.folder
Dim file As Scripting.file
Dim wkbk As Workbook
path = ThisWorkbook.path
Set folder = fso.GetFolder(path)
For Each file In folder.Files
Select Case UCase(Right(file.Name, 4)) '## Make sure you're only working on XLS file types
Case "XLSX", "XLSM", ".XLS" 'etc.
'
Set wkbk = Workbooks.Open(file.Name)
'Now, send this WOrkbook Object to a subroutine
CheckBoxesControl wkbk
wkbk.Save
wkbk.Close
Case Else
'Do nothing
End Select
Next
Set folder = Nothing
Set fso = Nothing
End Sub
Sub CheckBoxesControl(wkbk As Workbook)
Dim i As Long
On Error Resume Next
With wkbk
For i = 1 To 400
.Sheet4.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AA" & i
.Sheet21.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AB" & i
.Sheet22.CheckBoxes("Check Box " & i).LinkedCell = "ChkBoxOutput!AC" & i
Next i
End With
On Error GoTo 0
End Sub

Resources