I am trying to write a macro in VBA that saves the original workbook as a macro free workbook and then re-open the original macro enabled file, but ehat I have written is bugging out when it tries to open code (which is the last line of code). The error I get is a dialogue box that states that the file is unable to be found, however the file path provided is correct. Is the issue that I am trying to finish running the macro, while the workbook that is open is a generic Excel workbook (not macro enabled)? Code is below:
Sub SaveReport()
' SaveReport Macro
Dim strFileName As String, strOpen As String
strFileName = Application.Range("Attach").Value
strOpen = Application.Range("Open").Value
ActiveWorkbook.Save
Sheets("Email").Visible = False
ActiveWorkbook.SaveAs (ThisWorkbook.Path & "\" & strFileName & ".xlsx"), FileFormat:=xlOpenXMLWorkbook
Workbooks.Open strOpen
End Sub
I have a huge Excel spreadsheet that I need to allow access to a large set of users so they can manipulate it for their customers, but I don't want them to be able to overwrite the original file (a variable easily set in Excel) or save their file outside the current folder - so I want to force them in a "saveas" mode, and force the file to be saved in that folder. Otherwise, they won't be able to save. I'm not much of a VBA person, and I've found a lot of examples that may work, but nothing seems to be exactly what I need or maybe I'm not smart enough to figure it out. I found this code, but I'm not sure it FORCES the issue. Help?
I've tried to manage this in GPOs but everything seems to give them access to download the folder and save in other places.
Sub ExampleToSaveWorkbookSet()
Dim wkb As Workbook
'Adding New Workbook
Set wkb = Workbooks.Add
'Saving the Workbook
wkb.SaveAs "C:\WorkbookName.xls"
'OR
'wkb.SaveAs Filename:="C:\WorkbookName1.xls"
End Sub
Expected output is the amended Excel file saved in the original directory with a different name, or not at all.
Here's a macro that runs on open and immediately saves as .xlsx to a user location you can specify. Unfortunately the original needs to be .xlsm to store a macro.
This macro is to be located in the "ThisWorkbook" object. It will exit before making a copy when you open the workbook.
Private Sub Workbook_Open()
Dim wb As Workbook
Set wb = ActiveWorkbook
vWbName = wb.Name
vUserProf = Environ("USERPROFILE")
vx = InStr(1, vUserProf, "Users\")
If "<Use your own profileID>" = Mid(vUserProf, vx + 6) Then Exit Sub
vDir = vUserProf & "\Downloads\"
vWbName = Left(vWbName, Len(vWbName) - 5) & ".xlsx"
wb.SaveAs vDir & vWbName, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
MsgBox "You are now using a copy of the original"
End Sub
I am writing a piece of code in Excel VBA in which I needed to create a macro which allows the user to click the ActiveX button as a result of which the file is then saved to a specified location. Once this new file is created, I wanted to code so the new file (which successfully saves in the alternate specified location) does not have the ActiveX Command Button is not present. Also, once the button is clicked from the original file, I wanted to somehow make the master file close and the newly saved file to automatically open. Please can someone help?
Code so far:
Sub CommandButton1_Click()
ActiveSheet.Copy
Dim SaveName As String
SaveName = ActiveSheet.Range("C1").Text
With ActiveWorkbook
.SaveAs "File path Specified" & _
SaveName & ".xls"
.Close 0
End With
End Sub
My first solution (depending on what you really need to do) is the following:
Firstly you will need this:
Me.SaveCopyAs "<full_Path>"
See more on this here: https://msdn.microsoft.com/en-us/library/office/ff835014.aspx
This will create a copy of the file to the specified path with whatever name you want. Before you do that, you could hide your button and then use save as copy to save it with the button hidden.
Finally if you want to close the original and open the copy then you have to give to the copy a different name. Then open the new file and close the original.
Your code should look similar to this:
Sub CommandButton1_Click()
ActiveSheet.Copy
Dim SaveName As String
SaveName = ActiveSheet.Range("C1").Text
With ActiveWorkbook
.Worksheets("<your_worksheet>").CommandButton1.visible = False
.SaveCopyAs "File path Specified" & SaveName & ".xls"
End With
Workbooks.Open ("File path Specified" & SaveName & ".xls")
Workbooks("<Original_name.xlsm>").close False
End Sub
Another Solution could be saving the workbook with SaveAs. Before that save the orginal. Hide the button. And saveas will close the original and open the new one automatically.
Your code should look something like that:
Sub CommandButton1_Click()
ActiveSheet.Copy
Dim SaveName As String
SaveName = ActiveSheet.Range("C1").Text
With ActiveWorkbook
.Save
.Worksheets("<your_worksheet>").CommandButton1.visible = False
.SaveAs "File path Specified" & SaveName & ".xls"
End With
End Sub
I am new to coding (learning on my own and as I go) and have a small problem I just don't get. I have a code that has been working for a while and now seems to not work. I created a Service work order sheet to help keep accurate tabs on jobs for our service department. The code is pretty simple, they user enters all information in the cells they need. When finished they can press a button that updates a separate file. Press another and it saves a copy of the active work sheet to a specified networked location, prints copies, saves the work sheet according to a specified cell, then clears specified cells and updates the PO# cell.
The code has worked well until it stopped saving the file copies to the directory indicated and I don't know why it changed.
Sub SaveWorkOrderByAddress()
ChDir "\\BG-PC\SharedDocs\Service work orders\Service work orders"
Dim NewFN As Variant
Dim stFileName As String
'Save a new copy
NewFN = Range("C2").Value & ".xlsx"
stFileName = Range("C2").Value & ".xlsx"
If Dir(stFileName) <> "" Then
MsgBox "File already exists, please rename."
Else
ActiveSheet.Copy
ActiveWorkbook.SaveAs NewFN, FileFormat:=xlOpenXMLWorkbook
ActiveWorkbook.Close
PrintCurrentWO
NextWorkOrderNumber
ThisWorkbook.Save
End If
Any help would be most appreciated and again I am new so I am sorry if it's a newb mistake.
Changing the working directory doesn't help here. Just combine the path with the filename when calling ActiveWorkbook.SaveAs.
Like this:
NewFN = "\\BG-PC\SharedDocs\Service work orders\Service work orders\" & Range("C2").Value & ".xlsx"
I'm trying to save a macro-enabled Excel workbook as a csv file, overwriting the old one (below I had to change the name of the folder and the Sheet, but that doesn't seem to be the issue).
Sub SaveWorksheetsAsCsv()
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
SaveToDirectory = "\MyFolder\"
Application.DisplayAlerts = False
Application.AlertBeforeOverwriting = False
Sheets("My_Sheet").Copy
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV
ActiveWorkbook.Close SaveChanges:=False
ThisWorkbook.Activate
ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
Application.DisplayAlerts = True
Application.AlertBeforeOverwriting = True
End Sub
Sometimes it fails with
Runtime Error 1004: method saveas of object _workbook failed**)
The debugger points out:
ActiveWorkbook.SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV
I googled and some of the solutions I tried were:
Specifiying that the directory is a string
Avoid any special character in the file name or folder (seen here)
Copy paste the worksheet as value before saving it as .csv (seen here)
Specifying the FileFormat with the .csv code number (seen here)
Disabling/Re-enabling some of the alerts
Adding other fields in the ActiveWorkbook.SaveAs row, regarding passwords, creating backups etcetc
Still, it might run correctly up to 50-60 times in a row, and then at some point fail again.
Any suggestion, except stop using VBA/Excel for this task, which will happen soon, but I can't for now.
EDIT: Solved thanks to Degustaf suggestion. I made only two changes to Degustaf's suggested code:
ThisWorkbook.Sheets instead of CurrentWorkbook.Sheets
FileFormat:=6 instead of FileFormat:=xlCSV (apparently is more robust
to different versions of Excel)
Sub SaveWorksheetsAsCsv()
Dim SaveToDirectory As String
Dim CurrentWorkbook As String
Dim CurrentFormat As Long
Dim TempWB As Workbook
Set TempWB = Workbooks.Add
CurrentWorkbook = ThisWorkbook.FullName
CurrentFormat = ThisWorkbook.FileFormat
SaveToDirectory = "\\MyFolder\"
Application.DisplayAlerts = False
Application.AlertBeforeOverwriting = False
ThisWorkbook.Sheets("My_Sheet").Copy Before:=TempWB.Sheets(1)
ThisWorkbook.Sheets("My_Sheet").SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=6
TempWB.Close SaveChanges:=False
ThisWorkbook.SaveAs Filename:=CurrentWorkbook, FileFormat:=CurrentFormat
ActiveWorkbook.Close SaveChanges:=False
Application.DisplayAlerts = True
Application.AlertBeforeOverwriting = True
End Sub
I generally find that ActiveWorkbook is the problem in these cases. By that I mean that somehow you don't have that workbook (or any other) selected, and Excel doesn't know what to do. Unfortunately, since copy doesn't return anything (the copied worksheet would be nice), this is a standard way of approaching this problem.
So, we can approach this as how can we copy this sheet to a new workbook, and get a reference to that workbook. What we can do is create the new workbook, and then copy the sheet:
Dim wkbk as Workbook
Set Wkbk = Workbooks.Add
CurrentWorkbook.Sheets("My_Sheet").Copy Before:=Wkbk.Sheets(1)
Wkbk.SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV
Wkbk.Close SaveChanges:=False
Or, there is an even better approach in a situation like this: WorkSheet supports the SaveAs method. No copy necessary.
CurrentWorkbook.Sheets("My_Sheet").SaveAs Filename:=SaveToDirectory & "My_Sheet" & ".csv", FileFormat:=xlCSV
I will warn you to resave the workbook to its original name afterwards, if it is staying open, but you already have that in your code.
This is a year old, but I'll add something for future readers
You won’t find a lot of documentation in Excel help for Run-time error 1004 as Microsoft doesn't consider it to be an Excel error.
The answers above are 100% valid but sometimes it helps to know what is causing the problem so you can avoid it, fix it earlier or fix it more easily.
The fact that this is an intermittent fault, and it is fixed by saving with the full path and file name tells me that either your macro may be trying to save an .xlsb file to the autorecover directory after an auto file recovery.
Alternatively, you may have edited the file's path or filename yourself.
You can check the path and filename with:-
MsgBox ThisWorkbook.FullName
You should see something like this in the message box.
C:\Users\Mike\AppData\Roaming\Microsoft\Excel\DIARY(version 1).xlxb
If so the solution is (as stated above by others) to save your file to its correct path and file name. This can be done with VBA or manually.
I am now in the habit of manually saving the file with its correct path and filename as a matter of course after any autorecover action as it takes seconds and I find it quicker (if this is not a daily occurrence). Thus, the macros will not encounter this fault you run it. Remember that while my habit of manually saving .xlxb files to .xlsm files immediately after a recovery won't help a novice that you give the worksheet to.
A note on Hyperlinks
After this error: If you have hyperlinks in your worksheet created with Ctrl+k in all likelihood, you will have something like "AppData\Roaming\Microsoft\", "\AppData\Roaming\", "../../AppData/Roaming/"or "....\My documents\My documents\" in multiple hyperlinks after file recovery. You can avoid these by attaching your hyperlinks to a text box or generating them with the HYPERLINK function.
Identifying and Repairing them is a little more complicated
First, examine the hyperlinks and determine the erroneous strings and the correct string for each error. Over time, I have found several.
Excel doesn't provide a facility in the 'Go To Special' menu to search for hyperlinks created with Ctrl+k.
You can automate the identification of erroneous hyperlinks in a helper column, say column Z and using the formula
=OR(ISNUMBER(SEARCH("Roaming", Link2Text($C2),1)),ISNUMBER(SEARCH("Roaming", Link2Text($D2),1)))
where Link2Text is the UDF
Function Link2Text(rng As Range) As String
' DO NOT deactivate.
' Locates hyperlinks containing 'roaming' in column Z.
' Identify affected hyperlinks
If rng(1).Hyperlinks.Count Then
Link2Text = rng.Hyperlinks(1).Address
End If
End Function
My VBA to correct the errors is as follows
Sub Replace_roaming()
' Select the correct sheet
Sheets("DIARY").Select
Dim hl As Hyperlink
For Each hl In ActiveSheet.Hyperlinks
hl.Address = Replace(hl.Address, "AppData\Roaming\Microsoft\", "")
Next
For Each hl In ActiveSheet.Hyperlinks
hl.Address = Replace(hl.Address, "AppData\Roaming\", "")
Next
For Each hl In ActiveSheet.Hyperlinks
hl.Address = Replace(hl.Address, "../../AppData/Roaming/", "..\..\My documents\")
Next
For Each hl In ActiveSheet.Hyperlinks
hl.Address = Replace(hl.Address, "..\..\My documents\My documents\", "..\..\My documents\")
Next
Application.Run "Recalc_BT"
' Move down one active row to get off the heading
ActiveCell.Offset(1, 0).Select
' Check active row location
If ActiveCell.Row = 1 Then
ActiveCell.Offset(1, 0).Select
End If
' Recalc active row
ActiveCell.EntireRow.Calculate
' Notify
MsgBox "Replace roaming is now complete."
End Sub
I also recommend you get in the habit of doing regular backups and not relying on autorecover alone. If it fails, you have nothing since your last full backup.
While the worksheet is being fragile backup often, like every hour or after any significant import of new data.
The following shortcuts will backup your worksheet in seconds: Ctrl+O, [highlight the filename], Ctrl+C, Ctrl+V, [ X ]. Regular backups allow you to go immediately to your most recent backup without having to restore from last night's backup file especially if you have to make a request of another person to do this.
It's been a while since the last answer here, but I want to share my experience from today:
After weeks of reliable operation, I ran into the same error all of a sudden without having anything changed in the code section where the workbook is saved.
Thanks to the previous answers I updated my saveas statement from a simple
wb.saveas strfilename
to
wb.saveas Filename:=strfilename, Fileformat:= xlWorkbookDefault
et voilà: it worked again.
Sometimes the Microsoft applications behave really strange...
Try combining the Path and the CSV file name into a string variable and drop the .csv; that is handled by the FileFormat. Path must be absolute starting with a drive letter or Server Name:
Dim strFullFileName as String
strFullFileName = "C:\My Folder\My_Sheet"
If on a Server then it would look something like this:
strFullFileName = "\\ServerName\ShareName\My Folder\My_Sheet"
Substiture ServerName with your Server name and substitute ShareName with the your network Share name e.g. \\data101\Accounting\My Folder\My_Sheet
ActiveWorkbook.SaveAs Filename:=strFullFileName,FileFormat:=xlCSVMSDOS, CreateBackup:=False
I had a similar issue however for me the problem was I was creating the Filename based on strings extracted from a workbook and sometimes these strings would have characters that can't be in a filename.
Removing these characters did the trick for me!
For me there was an issue with not all formulas being calculated, despite having it on "Automatic". I pressed calculate on the bottom left 100 times and then it magically worked.