Users have an Excel spreadsheet. To save it, they press a button which runs the below VBA code.
The code attempts to save the Excel spreadsheet to a network location amending the file name with today's date.
Intermittently the code will fail with
"Run-time error '1004': Method 'SaveAs' of object'_Workbook' failed".
The script is:
Public Sub Copy_Save_R2()
Dim wbNew As Workbook
Dim fDate As Date
fDate = Worksheets("Update").Range("D3").Value
Set wbNew = ActiveWorkbook
With wbNew
ActiveWorkbook.SaveAs Filename:="Q:\R2 Portfolio Prints\#Archive - R2 Portfolio\" & "R2 Portfolio - CEC A " & Format(fDate, "mm-dd-yyyy")
End With
Sheets("Update").Activate
End Sub
As Hugo stated, it could be an issue with the mapped drive. I prefer to use the full UNC path (\\Thismachine\...), in case the workbook gets used on a machine that doesn't have the mapped drive set up.
I thought the missing extension could be the problem, but I just tested it in Excel 2013 and it automatically added .xlsx to the filename.
The issue is probably due to the wbNew reference. It's completely unnecessary and should not be combined with ActiveWorkbook. Basically, you should have either a reference to a workbook, or use the predefined ActiveWorkbook reference. I'd also recommend using ThisWorkbook instead, since the user might click on another book while code is running.
Public Sub Copy_Save_R2()
Dim wbNew As Workbook
Dim fDate As Date
fDate = Worksheets("Update").Range("D3").Value
Application.DisplayAlerts = False
ThisWorkbook.SaveAs Filename:="Q:\R2 Portfolio Prints\#Archive - R2 Portfolio\R2 Portfolio - CEC A " & Format(fDate, "mm-dd-yyyy") & ".xlsx"
Application.DisplayAlerts = True
ThisWorkbook.Sheets("Update").Activate
End Sub
Edit: Added Application.DisplayAlerts commands to prevent any Save popups, such as using .xlsx instead of .xlsm, and overwriting an existing copy.
Edit 2018-08-11: Added escape backslashes to fix UNC path display. Added strike-through to inaccurate statement about the With statement (see comments below). Basically, since nothing between With and End With begins with a ., the statement isn't doing anything at all.
I was also looking for the cause of this error, and then remembered I was working on a version of my spreadsheet that had been recovered. Once I manually saved the recovered file and reopened it there was no problem with the vba code to save the workbook.
When it happened to me, I added a command before the save.
On Error Resume Next
Kill TargetFullname
On Error GoTo 0
wb.SaveCopyAs TargetFullname
(I also use application.display=false)
Had the same error message when saving a workbook with a dynamic file name to a network location. Saving stage suddenly stopped working. Error 1004 Workbook SaveAs method failed.
Realised after a while that the location where the macro saved the output had changed and the macro's script had been tweaked by the team to reflect the new network address.
Whilst the new network address was accurate, it was simply too long...
I shortened the folder names, as well as the file name and bingo... Workbooks are being saved again, with no error messages.
This worked for me. Ensure your workbook is not shared. I guess "Shared" workbooks have limitations.
Saw this here:
https://www.ozgrid.com/forum/forum/help-forums/excel-general/27843-save-xls-as-txt
In the "Review" tab click "Share Workbook" and ensure "Allow changes by more than one user at the same time. This allows workbook merging" is unchecked.
Related
I'm trying to run a Macro across multiple files. I have used this script before and it worked, but maybe I have changed something inadvertently? The problem I'm having is that I get an error message that "PERSONAL.XLSB cannot be found, is it possible it was moved..." However, I'm using the full path of the .xlsb file and I am running the macro from that file.
This is my script:
'Sub SHELLforMacros()
Dim wbMatrix As Workbook
Dim strFileName As String
Dim strPath As String
Dim strExt As String
Dim objWorkbook As Workbook
Dim ws As Worksheet
'This is the folder of files it needs to run through:
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)
'Set objWorkbook = ActiveWorkbook
Application.Run "C:\Users\myname\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB'!Graph_NEW"
wbMatrix.ActiveWorkbook.Save
wbMatrix.Close SaveChanges:=True
strFileName = Dir
Wend
End Sub
I have also tried putting the PERSONAL.XLSB file into the same folder as the files it needs to run (and changing the path to reflect that). And I tried to run, or get it started, from one of the files in the folder rather than from the PERSONAL.XLSB without using a full path. I don't understand why it can't be found. Thanks.
Running a macro from another workbook can be simple done in a way I will try describing in a following step.
But running "a Macro across multiple files" does not mean any modification in terms of calling the macro. You did not show the macro code, but if it references ThisWorkbook like the one to be processed, it must reference the needed one (ActiveWorkbook, or wb, if previously it has been Set).
If "I am running the macro from that file" means running the macro from "PERSONAL.XLSB", it should simple be called as:
Graph_NEW
as it has already been suggested. If you insist to use Application.Run, even if it is not necessary, you can try:
Application.Run "Graph_NEW"
Now, if you run the code in a different workbook and need to run the macro from "PERSONAL.XLSB", the simplest way is using:
Application.Run "PERSONAL.XLSB!Graph_NEW"
Of course, "PERSONAL.XLSB" should be open.
If you insist to use the "PERSONAL.XLSB" full path, it will also work and you can use something similar with what you are trying. The advantage is that, if the workbook is closed, it will be open to run the macro:
Application.Run
Application.Run "'C:\Users\myname\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB'!Graph_NEW"
Your code misses the prefix "'". It will work without it if no any spaces exist in the workbook full path, but you should delete the one before "!"... In your case, if "myname" does not contain any space, it may be missing.
You can also add a reference to "Personal.xlxb" VBAProject and call the macro as you do in the working workbook. To do that, previously change the initial/existing standard name in something like "PersVBProject" (right click on the project from VBE 'Project Explorer`, choose 'VBAProject Properties...', change the existing name and press 'OK').
So, simple call it as:
Graph_NEW
I have a data entry userform and when user saves data to sheet. I want to save the Excel file - to achieve this I use ThisWorkbook.Save and this works like a charm on my machine.
The file is created and saved as a .XLSM file in Excel 2016 (windows 64 bit).
Now when I distribute the same to my peers at office - some machines work fine.
Some machines throw a runtime 1004 error save method of worksheet class failed.
Application.DisplayAlerts = False
Dim xWs As Worksheet
Dim xName As String
xName = "data"
For Each xWs In Application.ActiveWorkbook.Worksheets
If xWs.Name <> xName Then
xWs.Visible = False
End If
Next
ThisWorkbook.Save '<<<< Runtime 1004 Error on this line
Unload Me
Application.Quit
On checking the file, the data is saved to the sheet but the error throws up.
What could be the potential reason for this?
Just something that came to my mind based on
"https://www.rondebruin.nl/win/s5/win001.htm"
Users can open my file (type .xlsm) in any version of excel excel 2007 / excel 2003 ? Is that the root cause? If yes what is my way around?
I believe the problem is how you distribute the file.
My guess is that you email it to them and they open it from the email?
What happens is the file is in a position where you can't save it.
Ask your colleagues to save as the file on the desktop or documents folder where you know for sure they have full read and write capabilities.
Then open the file.
This has bugged me also a few times.
It's easy to forget.
You want to avoid using ActiveWorkbook. Create a variable to store your workbook(s) and use that variable. Your problem is probably due to the fact that your ActiveWorkbookis pointing to a different workbook than the one you wanted.
Using Excel 2010 on Windows 7. I have a VBA macro that saves the first worksheet of an excel workbook (.xlsm) into a CSV file. This had mostly worked in the past. Recently, I get error messages per the picture below, which state "Run-time error '1004': Microsoft Excel cannot open or save any more documents because there is not enough available memory or disk space."
So a couple things:
A common suggested solution from my Google searching is to set the file's location as a Trusted Location. This did not work.
I have enough disk space. That can't be the issue.
I'm not sure exactly what is meant by "available memory," but if it in any way refers to the Physical Memory figure listed in Windows Task Manager, that figure is 75%. The ultimate CSV file itself tends to be about 1,500KB.
I am always able to save this worksheet as a CSV manually without encountering any error messages, but when I do it via this VBA macro, I get the error message.
Picture of error message
My excel VBA save-as-CSV macro:
Sub saveAsCSV()
Application.DisplayAlerts = False
ThisWorkbook.Sheets("Sheet1").Copy
ActiveWorkbook.SaveAs Filename:="dummyfilename.csv", FileFormat:=xlCSV, CreateBackup:=True
ActiveWorkbook.Close
Application.DisplayAlerts = True
End Sub
Try this, you don't have to use Copy or Activate. If your code is in the workbook that you want to save as a workbook you can use ThisWorkbook. Kudos to #Variatus for identifying need for a path.
ThisWorkbook.Sheets("Sheet1").SaveAs ThisWorkbook.Path & "/" & "dummyfilename" & ".csv", FileFormat:=6
So the code below functioned with out any issues before. Basically, I get this doc emailed to me, the code runs to extract the needed data, saves to the workbook to the specified file pathway to the specified filename, and the next part of the code puts all the data gathered on a summary doc.
Today, I tried to add an alert message box so that if certain conditions were met , a message to the user would be provided when there was an attempt to save. When I did that, I began getting a Runtime 1004 error and still get it even though I have removed the beforesave event on the worksheet. It was using ActiveWorkbook... and then I changed it to ThisWorkbook after reading about how ActiveWorkbook can cause errors.
I don't know what the file name will be when I get these docs, and would like to simply have the doc save and apply to specified file name when I run the macro. Any ideas on why I am suddenly getting this error?
'saves incident report to incident report folder
ThisWorkbook.SaveAs Filename:=("C:\Users\ashley.graham\Field Agent Folder\Incident Reports\Test folder\Test Incident report folder\" & IncidentReport & AgentName & ".xlsm")
Try adding this:
Dim wb As Workbook
Set wb = Workbooks(ActiveWorkbook.Name)
wb.SaveAs Filename:=("C:\Users\ashley.graham\Field Agent Folder\Incident Reports\Test folder\Test Incident report folder\" & IncidentReport & AgentName & ".xlsm")
I have a VBA macro which is called from a spreadsheet function (user defined function, UDF). When the spreadsheet is downloaded from the internet and the user has set "Trust Center" settings accordingly, the spreadsheet will open in so the called "Protected View". The function will not be called. A button "Enable Editing" is shown.
If the button is pressed, the spreadsheet is "trusted" and reopened normally, starting calculation, and hence calling the user defined function.
However, in that VBA function the value of Application.ActiveWorkbook is Nothing. This can be verified in the debugger.
Since I just need to read some properties (like path name) of the spreadsheet, I could alternatively inspect the availability of Application.ActiveProtectedViewWindow which should reference to the protected version of the workbook. In the debugger, this object can be inspected. However, running in release (without debug) the value of Application.ActiveProtectedViewWindow is also Nothing.
Both behaviors - especially the first one - appears to be a bug present in Excel 2010 and 2013 (see also a post at the MSDN forum ).
Question: Is there a way to get hold of properties of the active workbook after it has been enabled for editing?
PS: As a follow up to the nice observation of Siddharth Rout, that "ThisWorkbook" might work: In my case, the macro is not part of the Workbook being openend. The UDF is defined in an XLA. Hence, ThisWorkbook would reference the XLA. I do need to get the ActiveWorkbook (= the workbook calling the UDF) instead of ThisWorkbook (= the workbook running the UDF).
IMPORTANT REQUIREMENT:
My function is called as a user defined function, i.e., execution order is determined by Excel updating the cell.
The function is not part of the workbook being opened. It is part of an XLA.
I cannot add any code to the workbook which is opened.
Summary: The problem can be replicated and there are some possible workarounds. The most promising one - resulting from a chat - is to use ActiveWindow.Parent instead of ActiveWorkbook.
I was able to replicate the problem.
I tried
Private Sub Workbook_Open()
MsgBox "Application.ActiveWorkbook Is Nothing = " & _
CStr(Application.ActiveWorkbook Is Nothing)
End Sub
And I got True
However, then I tried this and it gave me False
Private Sub Workbook_Open()
MsgBox "Application.ActiveWorkbook Is Nothing = " & _
CStr(Application.ThisWorkbook Is Nothing)
End Sub
Now answering your question...
Question: Is there a way to get hold of properties of the workbook after it has been enabled for editing?
Yes. Use ThisWorkbook instead of ActiveWorkbook
Followup From Comments
Once the workbook completely loads after you exit the Protected Mode, you would be able to access the ActiveWorkbook object. To test this, put this code in the protected file.
Private Sub Workbook_Activate()
MsgBox "Application.ActiveWorkbook Is Nothing = " & _
CStr(Application.ActiveWorkbook Is Nothing)
End Sub
You will notice that you get a False
So once your workbook loads, your add-in can use ActiveWorkbook to interact with the opened file.
Here is another test
Private Sub Workbook_Activate()
MsgBox ActiveWorkbook.Path
End Sub
This is what I got the moment, I exit the Protected Mode
FOLLOWUP FROM CHAT
Using ActiveWindow.Parent.Path instead of ActiveWorkbook.Path would solve the problem.
I had this same issue today, and neither the accepted answer nor any other answer that I could find on this page or through searching the Google-verse worked for me. I'm using the version of Excel within Office 365, and I figured that was at the root of the problem.
I eventually came to a solution after finding a Microsoft Excel 2010 resource and hitting the old try-fail cycle for a few hours. Here's what I got:
Option Explicit
Public WithEvents oApp As Application
Private bDeferredOpen As Boolean
Private Sub Workbook_Open()
Set oApp = Application
End Sub
Private Sub oApp_WorkbookActivate(ByVal Wb As Workbook)
If bDeferredOpen Then
bDeferredOpen = False
Call WorkbookOpenHandler(Wb)
End If
End Sub
Private Sub oApp_WorkbookOpen(ByVal Wb As Workbook)
Dim oProtectedViewWindow As ProtectedViewWindow
On Error Resume Next
'The below line will throw an error (Subscript out of range) if the workbook is not opened in protected view.
Set oProtectedViewWindow = oApp.ProtectedViewWindows.Item(Wb.Name)
On Error GoTo 0
'Reset error handling
If oProtectedViewWindow Is Nothing Then
bDeferredOpen = False
Call WorkbookOpenHandler(Wb)
Else
'Delay open actions till the workbook gets activated.
bDeferredOpen = True
End If
End Sub
Private Sub WorkbookOpenHandler(ByVal Wb As Workbook)
'The actual workbook open event handler code goes here...
End Sub
The difference between the 2010 solution and mine is that I had to call Workbook_Open and explicitly set the oApp variable there, because without that assignment neither the oApp_WorkbookActivate nor oApp_WorkbookOpen functions would fire when I opened the file.
Figured that someone else might be able to benefit from this, so I posted it, despite the fact that the most recent update to this thread is better than 2 years old.
Best.
Try using Application.Caller.Parent.Parent instead of Application.Activeworkbook
This is not a complete answer to the original question, but a (dirty) workaround for a problem related to this.
I needed ActiveWorkbook to infer the workbooks path, that is ActiveWorkbook.Path.
An alternative to using ActiveWorkbook.Path is to check for Application.RecentFiles(1).Path which is the path of the most recently opened file. In many cases this will be the workbook for which the user just has "Enabled Editing". However, of course, this method may fail: In the case the used opened another sheet, then enabling the previously opened sheet.
(Note: ActiveWorkbook.Path give the path of the folder, while Application.RecentFiles(1).Path gives the complete path of the file, so there has to be some post-processing).
I know it's old thread, but i came across the same issue and i found solution ;)
The only way to go around it, is to use variable type Workbook
Dim wbk as Workbook
Set wbk = Application.ProtectedViewWindows(index).Workbook
Warning:
ActiveSheet returns Nothing when active window is protected too.
Dim wsh As Worksheet
Set wsh = wbk.Worksheets(index)
Try this code it works.
If (UCase(ActiveWorkbook.Name) = ucase("<YOUR XLA NAME WITH EXTENSION>")) Then
End
End If
Set wbObj = ActiveWorkbook
First time when you run the macro, it just ends without doing anything. Second time it picks up the proper file.