VBA: For Loop hitting Automation Error -2147221080 - excel

Here is my code.
My purpose is, open a test excel and then save as a filename contained within the 'Test' sheet. I simply want to automate the task of saving an Excel for each of a list of filenames.
Sub POPButton1_Click()
Dim i As Long, LastRow As Long
LastRow = Test.Range("A" & Rows.Count).End(xlUp).Row
Dim filename As String
filename = ThisWorkbook.Path & Application.PathSeparator & "Test.xlsx"
Dim sjk As Workbook
Set sjk = Workbooks.Open(filename)
Dim saveName As String
For i = 1 To LastRow
saveName = Test.Cells(i, "D").Value
sjk.SaveAs ThisWorkbook.Path & "\" & saveName
sjk.Close
Next i
End Sub
The first excel is saved just fine, then I hit the bug. -2147221080 Automation error.
The line of code that highlights on debug is:
sjk.SaveAs ThisWorkbook.Path & "\" & saveName
I have looked around on this site and many others, as it appears a common bug, and I get the feeling it is an easy fix, but nothing I have tried has worked. I have re-written the code many times to get it to this point - I just can't see where the error is...

Ah! I think the answer is that you close the file but then never re-open it.
Move your Set sjk = Workbooks.Open(filename) inside your For loop at the top.
That should fix it for you.

Related

Excel VBA / Mac (Big Sur) - Cannot access read-only document

I'm trying to write a simple macro to run on my Mac (Excel 16.61, Mac Book Pro running Big Sur 11.4) that copies the visible rows of a table into a new workbook then saves the new workbook as a *.csv file.
The current (non-working) code:
Sub Macro()
Dim wb as Workbook
Dim wbOutput As Workbook
Dim FilePath As String
Set wb = ThisWorkbook
FilePath = "/path/to/filename.csv"
' Copy the visible rows of a filtered table
With wb.Sheets("WorksheetName").ListObjects("tblName")
.Range.AutoFilter Field:=18, Criteria1:="TRUE"
.Range.SpecialCells(xlCellTypeVisible).Copy
End With
' Paste the copied table rows into a new workbook and save as a *.csv file
Set wbOutput = Workbooks.Add
wbOutput.Worksheets("Sheet1").Range("A1").PasteSpecial xlPasteValues
wbOutput.SaveAs FileName:=FilePath, FileFormat:=xlCSV, CreateBackup:=False
wbOutput.Close
End Sub
When I run it however I get the following error:
Run-time error '1004': Cannot access read-only document [filename]
Having spent a few hours searching on-line, I'm no closer to a solution. The internet's suggestions include:
Adding Excel in System Preferences.../Security & Privacy/Files and Folders (I can't see an obvious way of adding a new app, just remove the access rights of apps that already have folder access)
The GrantAccessToMultipleFiles function, but adding FilePath in the input array of the function makes no difference.
How can I create a *.csv file from the table?
Ran into the same issue but my file format was .txt but here was my solution after doing some research and getting some solid help from the Mac VBA Guru Ron De Bruin.
The code essentially bypass creating the output files, in my case .txt files in a folder location that has security protocols that cause the Error 1004 message and creates a subfolder in the Microsoft Folder under my User profile which for whatever reason Excel/Mac don't see as a security threat and allows the VBA to create/save the output file(s) into that folder.
Hopefully, you can extract out what you need from the code and Function to get yours to work. One other thing, since the output is going to such a weird folder location I suggest you save the folder path under your favorites on the Finder Left Panel so you can easily get to the files. See the MsgPopup box for the folder location
Sub Create_TxtFiles()
Dim MacroFolder As String
Dim nW As Workbook
Dim ws1 As Worksheet, ws2 As Worksheet
Dim DT As String, RelativePath As String, wbNam1 As String, wbNam2 As String, Filepath As String
'Declarations
Set ws1 = ThisWorkbook.Sheets("Extract1")
Set ws2 = ThisWorkbook.Sheets("Extract2")
RelativePath = ThisWorkbook.Path & "/"
DT = Format(CStr(Now), "mm_dd_yyyy hh.mmam/pm")
wbNam1 = "Extract 1 Output" 'Creates the File Name
wbNam2 = "Extract 2 Output" 'Creates the File Name
MacroFolder = "Upload Files"
Call CreateFolderinMacOffice2016(MacroFolder)
'set the savepath as the obscure folder vba has access to'
savepath = Application.DefaultFilePath & MacroFolder & "/"
'copy the Output 1
ws1.Copy
ActiveWorkbook.SaveAs savepath & wbNam1 & DT & ".txt", FileFormat:=42
Workbooks(wbNam1 & DT & ".txt").Close
'copy the Output 2
ws2.Copy
ActiveWorkbook.SaveAs savepath & wbNam2 & DT & ".txt", FileFormat:=42
Workbooks(wbNam2 & DT & ".txt").Close
Application.ScreenUpdating = True
msgbox ("Upload file saved to folder: " & vbNewLine & vbNewLine & savepath)
End Sub
Function CreateFolderinMacOffice2016(NameFolder As String) As String
'Function to create folder if it not exists in the Microsoft Office Folder
'Ron de Bruin : 1-Feb-2019
Dim OfficeFolder As String
Dim PathToFolder As String
Dim TestStr As String
OfficeFolder = Application.DefaultFilePath
PathToFolder = OfficeFolder & NameFolder
On Error Resume Next
TestStr = Dir(PathToFolder & "*", vbDirectory)
On Error GoTo 0
If TestStr = vbNullString Then
MkDir PathToFolder
End If
CreateFolderinMacOffice2016 = PathToFolder
End Function

Excel VBA won't save: creating 8-digit alphanumeric "filename"

I am new to VBA. I am using a "shell" macro to run another macro on a series of files. It won't save. I am going to include my code here and also a series of photos because the photos were the only way to show the result of hovering over the values in the code.
So, the error message is generating something I don't understand. But it is clear that the links in the code link to what the results should be, so I'm confused.
This is the code:
Sub SHELLforMacros()
Dim wbMatrix As Workbook
Dim strFileName As String
Dim strFileName As String
Dim newFileName As String
Dim strPath As String
Dim strExt As String
Dim objWorkbook As Workbook
Dim ws As Worksheet
Dim Sheetname As Worksheet
Set Sheetname = Worksheets(1)
Dim Worksheet As Worksheet
Dim rng As Range
Set rng = Range("A2")
strPath = "C:\Users\myname\Desktop\All_mricgcm3_files\45\Fall45\test\"
strExt = "csv"
strFileName = Dir(strPath & "*." & strExt)
While strFileName <> ""
Set wbMatrix = Workbooks.Open(strPath & strFileName)
Application.Run "'C:\Users\myname\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB'!Graph_NEW"
strPath = "C:\Users\myname\All_mricgcm3_files\45\Fall45\test\"
newFileName = Sheetname.Range("A2").Value
ActiveWorkbook.SaveAs fileName:=strPath & newFileName, FileFormat:=51
ActiveWorkbook.Close SaveChanges:=True
Wend
End Sub
What this macro is supposed to do is open a file, run another macro on the file (creating a graph), and then save the file with the same name but as an .xlsx file. Then open the next file in the folder and do the same, until it runs out of files. I realize the code may not be the most current. It is cobbled together from things I've found online. Thanks for any help.
Edit: UPDATE - I removed all the section on saving and closing the file from the "shell" macro and put it into the "Graph_NEW" macro. Now the "shell" macro is running fine. But I am running into the same issue with the "Graph_NEW" macro now. It is exactly the same error message as highlighted in the first image, only each time there is a new 8-digit alphanumeric "filename" that it is looking for. This seems like a very specific thing.
I changed the section in the following ways, successively, in an attempt to debug. I added With and End With around the section:
With WB
ActiveWorkbook.Save
newFileName = Sheetname.Range("A2").Value
strPath = "C:\Users\qmontana\All_mricgcm3_files\mric45\Fall45\test\"
ActiveWorkbook.SaveAs fileName:=strPath & newFileName & ".xlsx", FileFormat:=51
ActiveWorkbook.Close SaveChanges:=True
End With
I changed the name of the folder from "45" to "mric45" thinking that maybe it didn't like a number as a folder name.
I removed the "backslash" at the end of the strPath--and then the 8-digit alphanumeric string showed up as an error after the Fall45 folder, like this "C:\Users\myname\Desktop\All_mricgcm3_files\45\Fall45\777GTY78". Yet, as I've shown in the images, all indications are that it knows what file it is working with. There are no "blank spaces" in the pathname.
I tried taking the underscores out of the folder "All_mricgcm3_files".
I moved the line newFileName = Sheetname.Range("A2").Value to come before the strPath line.
Where is this 8-digit alphanumeric "filename" coming from?? (See error code, first image.)
Ok, it was a very simple thing, in case anyone else runs into this problem.
Took me two days to find out though --> I had somehow dropped a folder layer in the path name. The catch? The alphanumeric string was showing up at the end of the path name, not where the folder layer was missing. That's why I was thrown off because my focus was on the ending.
When I added that folder\ back in, I had no more problem with saving and the macro ran fine.

Excel 2016/2013 crashes running SaveAs method 2 times

I'd like to create several new workbooks. The VBA code below runs fine with Excel 365 and 2010. BUT with Excel 2013 or 2016, it runs fine the first time (and create the files)... and on the second run, Excel crashes without any error message.
If I run it step by step, I see that it's the SaveAs line that causes the crash.
I tried to kill the file before saving, too. To use a timer...
I tried to repair Office, to rename a HKEY (Identities), I tried to run it on 2 different windows (7 or 10). Nothing helps :/
Sub ExtraireType()
Dim shVentes As Worksheet
Dim rngVentes As Range
Dim rngTypes As Range
Dim shNew As Worksheet
Dim wkbNew As Workbook
Dim strPath As String
Dim zaza As Range
Application.DisplayAlerts = False
Set shVentes = ThisWorkbook.Worksheets("Ventes")
Set rngVentes = shVentes.Range("A1").CurrentRegion
Set rngTypes = ThisWorkbook.Worksheets("Liste").Range("A2:A4")
strPath = ThisWorkbook.Path
For Each zaza In rngTypes
rngVentes.AutoFilter
rngVentes.AutoFilter field:=3, Criteria1:=zaza.Value
rngVentes.Copy
Set shNew = ThisWorkbook.Worksheets.Add
shNew.Paste
Application.CutCopyMode = False
shNew.Move
Set wkbNew = ActiveWorkbook
wkbNew.SaveAs strPath & "\Type" & zaza.Value & Format(Date, "yyyymmdd")
wkbNew.Close
Set shNew = Nothing
Set wkbNew = Nothing
Next zaza
Set rngVentes = Nothing
Set shVentes = Nothing
Set rngTypes = Nothing
Application.DisplayAlerts = False
End Sub
This code runs well with Excel 2010 or 2019/365. But I have to use it with 2013 or 2016 :(
What am I doing wrong? Thanks for any help !
I was having this problem as well and have found a workaround - use .SaveCopyAs instead.
In the below example, .SaveAs crashes Excel every second time if I've left the Excel spreadsheet open and deleted the resultant file, whilst .SaveCopyAs saves every time irrespective. The only difference between the two is that .SaveAs has more options for how to save whereas .SaveCopyAs's only option is the filename.
Private Sub SaveAsExcelFile(TempExcelFile As Workbook, _
NewFullFileName as string, _
Optional FileFormat As XlFileFormat = xlOpenXMLWorkbook, _
Optional CreateBackup As Boolean = False)
'
' created & last edited 2020-03-06 by Timothy Daniel Cox
'
' For this example it is assumed the new file name is valid and in .xlsx format
'
Dim NewFullFileName2 as string
NewFullFileName2 = Replace(NewFullFileName, ".xlsx", "2.xlsx")
Application.EnableEvents = False
TempExcelFile.SaveCopyAs Filename:=NewFullFileName 'doesn't crash here on 2nd run
TempExcelFile.SaveAs Filename:=NewFullFileName2, FileFormat:=FileFormat, _
CreateBackup:=False 'will crash here on 2nd run
Application.EnableEvents = true
End Sub
I still think there is a bug in Excel regarding the .SaveAs however:
There's a long thread at
https://chandoo.org/forum/threads/worksheet-save-as-to-new-workbook-crashes-excel-on-second-run.40136/#post-241024
which after meandering has an apparent resolution as linked but - having
downloaded the file to see what changes have been made - he only
appears to have changed the output directory and removed a
conflicting fileformat which was set. IMO it did not resolve the
issue.
There's another similar unsolved thread at https://www.reddit.com/r/excel/comments/58fqlg/my_vba_code_works_at_first_but_if_used_twice_in_a/ which has no useful answers.
The one of the reasons that your code crash (it crushed in my case, Excel 2016), might be because you didn't add file extension at the end of:
wkbNew.SaveAs strPath & "\Type" & zaza.Value & Format(Date, "yyyymmdd")
so it might be like:
wkbNew.SaveAs strPath & "\Type" & zaza.Value & Format(Date, "yyyymmdd") & ".xlsx"
Hope it helps.

Executing Excel macro on/from specific open file

I've got a need to open some Excel files and "pause" then close them. In this process I run one macro on opening, and another on closing. The opening one works fine because it is done as each file is opened. But the closing part of the code I can't get it to run the correct macro. They have the same names, but the file contests are different, and what the macro does per file is different.
This is the gist of what I'm doing now
Set xlApp = CreateObject("Excel.Application")
xlApp.Visible = True
path = "\\Gaalpa1cdfile19\north_sa_staff\Reports\Rpt-ProductionCurves\"
filename2018P1 = "2018 P1.xlsm"
Set xlbook2018P1 = xlApp.WorkBooks.Open(path & filename2018P1)
' Run Macro
xlApp.Run "AutoRefresh"
filename2018P3 = "P3 2018 HRR.xlsm"
Set xlbook2018P3 = xlApp.WorkBooks.Open(path & filename2018P3)
'Run Macro
xlApp.Run "AutoRefresh"
'My "pause"
WScript.Echo ("All Files were" & Chr(013) & _
"opened and refreshed, update ppt before OK" & Chr(013) & _
" DO NOT CLICK OK" & Chr(013))
'==========================
'Below is the trouble spot.
'==========================
xlapp.Run "'" & filename2018P1 & "'" & "!AutoPublish"
xlbook2018P1.Close False
Set xlbook2018P1 = Nothing
xlapp.run "'" & filename2018P3 & "'" & "!AutoPublish"
xlbook2018P3.Close False
Set xlbook2018P3 = Nothing
The first part works fine, but trying to run the file's respective AutoPublish macro does not. The code works fine if I leave out that Run line. (The real file names have spaces and I had to add the single quotes to get it to accept the filename.)
What it appears to be doing is using the macros from the last file opened, not the one it's directed to use it the run line. I think I need a way to "select" the correct file, or give it focus so the macro could run without an explicit filename argument, which it appears to be ignoring anyway.
EDIT:
Solution was:
xlbook2018P1.Activate ' This fixed it, I think
xlapp.Run "'" & filename2018P1 & "'" & "!AutoPublish"
xlbook2018P1.Close False
Set xlbook2018P1 = Nothing
xlbook2018P3.Activate
xlapp.run "'" & filename2018P3 & "'" & "!AutoPublish"
xlbook2018P3.Close False
Set xlbook2018P3 = Nothing
When tackling similar tasks, I usually work around by implementing a master Excel file first, and call a sub in this master file via VBS. The advantage to me seems it is way easier to fullfill all tasks in the VBA of the master file rather than having to code all that in VBS.
Create a master file, e.g. "Master.xlsm", list all your files you need to open on a sheet named "Files" in column A, starting in row 1.
Insert a module and place the following sub in this module:
Sub Main()
Dim strPath As String
Dim strFile As String
Dim lRow As Long
Dim i As Long
Dim k As Integer
Dim n As Long
Dim wb(1 To 3) As Workbook
Dim wbTest As Workbook
Set wbMaster = ThisWorkbook
strPath = "\\Gaalpa1cdfile19\north_sa_staff\Reports\Rpt-ProductionCurves\"
'Check how many files you need to open
With Sheets("Files")
lRow = Sheets("Files").Range("A" & .Rows.Count).End(xlUp).Row
End With
'open all available files
For i = 1 To lRow
Workbooks.Open (wbMaster.Sheets("Files").Range("A" & i).Value)
Next
'now run the two macros in each open file
For k = 2 To Workbooks.Count 'this will work only if your master file is the only one open when starting the sub!
Workbooks(k).Run "'" & Workbooks(k).Name & "'!AutoRefresh"
DoEvents
Workbooks(k).Run "'" & Workbooks(k).Name & "'!AutoPublish"
DoEvents
Next
'and close all files previously opened except for the master file
For n = Workbooks.Count To 2 Step -1
Workbooks(n).Close False
Next
End Sub
It seems like a possible explanation for what you're seeing is that your AutoPublish macro refers to ActiveWorkbook and not the safer ThisWorkbook. If another workbook is active when it's called that could lead to unexpected results.

Subscript out of range error - saveas method

Trying to get Excel to "saveas" a workbook by using the following code:
Sub SaveWorkbook(my_FileName, sFolder)
Dim workbook_Name As String
Dim fName As String
fName = CStr(Range("B9").Value)
workbook_Name = "\" & fName & ".xls"
Workbooks(my_FileName).SaveAs fileName:=sFolder & workbook_Name
End Sub
my_FileName and sFolder are being passed by another function:
Sub ProduceDoc()
MsgBox "Please Select the File that Contains the Document"
my_FileName = Application.GetOpenFilename(FileFilter:="Excel Files,*.xl*,*.xsl*,*.xm*")
sFolder = "C:\Users\" & InputBox("Please type your employee id") & "\Desktop\" & InputBox("What will you name your folder?")
Workbooks.Open (my_FileName)
SaveWorkbook (my_FileName)
End Sub
The subscript error is currently being thrown for the line:
Workbooks(my_FileName).SaveAs fileName:=sFolder & workbook_Name
and I can't figure out why. I'm assuming it's happening because I'm forgetting something simple.
What I've done so far to test:
Verified that my_FileName is successfully being passed to the function SaveWorkbook(), and it is. I was able to open the document specified in function ProduceDoc() and get my_FileName to print in a certain cell within SaveWorkbook()
That's all I have in the toolkit atm. Any thoughts?
Edit: I've now updated the line Workbooks(my_FileName).SaveAs fileName:=sFolder & workbook_Name to show new state, and also sFolder is being called in . It is still giving the same error.
I figured it out.
Everything was formatted correctly in all variables, except for these two lines:
workbook_Name = "\" & fName & ".xls"
Workbooks(my_FileName).SaveAs fileName:=sFolder & workbook_Name
Excel didn't like a few things here, so I tried to make it as basic as I could. I combined the concatenation of sFolder and workbook_Name into one variable, removed ".xls", and added the fileFormat:=xlWorkbookNormal argument into the SaveAs method.
What I think really fixed this is how I called the SaveAs method. Changed that to "ActiveWorkbook" rather than what is was previously.
workbook_Name = sFolder & "\" & fName
ActiveWorkbook.SaveAs fileName:=workbook_Name, fileFormat:=xlWorkbookNormal
It all behaves as expected now!
hope this helps anyone who runs into this in the future!

Resources