msoFileDialogSaveAs not writing file Excel VBA - excel

Using the following code to copy some data on a master sheet, then add a new workbook, then paste the data. I then need to prompt using the msoFileDialogSaveAs because I need the user to be able to select different file types each time.
The problem is that when the box comes up to save the file, I can type a name then hit save, but it doesn't actually write the file.
Public Sub ArchiveSheet()
Dim NewBook As Workbook
Dim CopyRange As Range
Set CopyRange = ActiveSheet.UsedRange
Dim lngCount As Long
CopyRange.Cells.Copy
Set NewBook = Workbooks.Add
Range("A1").PasteSpecial Paste:=xlPasteValues
With NewBook
.Title = "Archive"
End With
With Application.FileDialog(msoFileDialogSaveAs)
.Show
End With
Application.CutCopyMode = False
End Sub

You are currently asking to user to indicate where he/she wants to save the file. But you are not using it. You need to save the return string like so:
dim strFileSelected as String
strFileSelected = Application.GetSaveAsFilename(FileFilter:="Excel Files (*.xls), *.xls", Title:="Save Excel file...")
Afterwards you can check if the user actually gave you a path and file name to save it to:
If strFileSelected = "False" Then
MsgBox "You have cancelled"
else
MsgBox "Saving file here:" & chr(10) & strFileSelected
ThisWorkbook.SaveAs Filename:=strFileSelected, FileFormat:=xlWorkbookNormal
End If
Note that you cannot save all Excel files using any kind of file extension. Example: if you have an open XML format Excel file open and try to save it using the .xls extension then you'll probably get an error message and you'll loose any kind of VBA code attached to the file (if you ignore the error message).
In short: you might want to elaborate on the above solution in order to make sure that the file format matches the selected extension using Debug.Print ThisWorkbook.FileFormat.

I know this is old but I had this issue today, have not seen this answer anywhere...
And the solution was very simply to add the .Execute line, as below.
Now the user hits Save (or Enter) and the selection executes.
With Application.FileDialog(msoFileDialogSaveAs)
.Show
.Execute
End With
My first post here, sorry about my obvious lack of skills. I am not an advanced user.
Thanks.

Related

vba routine to save workbook does not have desired result

I have a workbook which is updated every 4 weeks with new data. When updated, it has to be saved with a specific name and with specific options. I already had a script which saves workbook to a new file for me so I used that script and modified it.
Sub save_workbook_name()
Dim workbook_Name As Variant
Dim location As String
location = "N:\IRi\"
workbook_Name = Application.GetSaveAsFilename
If workbook_Name <> False Then
ActiveWorkbook.SaveAs Filename:=Workbook.Name, WriteResPassword:="TM", FileFormat:=50
End If
End Sub
When I use this code and I press the button, a popup screen appears asking me how I want to save the file:
But there is not file format being set. The password for opening the file is set I noticed when opening the saved file. I know for myself that I have to add the .xslb extension when saving the file but I am not sure about any colleague whom also works with this file.
When I enter a filename and extension, I get an error:
error 424: object needed
my wished regarding to the options for saving:
filetype has to be set to .xlsb
to prevent the saved copy from being updated, I want it to be saved with password protection for opening
How can I make the routine to already add the .xlsb extension so only the file names has to be entered?
edit: with the answer from Marcucciboy2 I changed the script to:
Sub save_workbook_name()
Dim workbook_Name As Variant
Dim location As String
workbook_Name = Application.GetSaveAsFilename(fileFilter:="Excel binary sheet (*.xlsb), *.xlsb", InitialFileName:="N:\IRi\")
If workbook_Name <> False Then
ActiveWorkbook.SaveAs WriteResPassword:="TM", FileFormat:=50
End If
End Sub
And now it works perfectly for saving.
Additional question with regarding to this script and the entered name is posted in a new question:
vba script to save workbook overwrites entered filename
I think the issue might be that you're not filtering the filename that you receive from GetSaveAsFilename, so try:
Application.GetSaveAsFilename(fileFilter:="Excel binary sheet (*.xlsb), *.xlsb")

Don't know how program a button to open file explorer that can open any document

I have found code for this but have only found code that specifies excel files not one that allows me to open any document. Basically I have a button on a work sheet that needs to open a file explorer when clicked on. Once it has been clicked on it needs to direct the user to a specific file path that contains documents of various types. The user should then be able to open any of the documents.
Does anyone have a solution for this?
Thanks in advance!
Here is what I have so far from what I have found elswhere...
Private Sub Showfileexplorer_Click
Dim strFileToOpen As String
strFileToOpen = Application.GetOpenFilename _
(Title:="Please choose a file to open", _
FileFilter:="Excel Files *.xlsx* (*.xlsx*),")
If strFileToOpen = False Then
MsgBox "No file selected.", vbExclamation, "Sorry!"
Exit Sub
Else
Workbooks.Open Filename:=strFileToOpen
End If
End Sub
This code works to the point of choosing a document. I have tried picking the document I wanted (Specifically excel.xlsx files as is listed above) to open and then clicking open and it throws me an error. The thing is I don't want just excel files. If it could open any file that would be great.
Someone else was able to answer my question on another forum. Credit goes to Trebor76 from Ozgrid for the user friendly solution. This is the solution that was given to me. This was pretty plug and play.
Option Explicit
Sub Acessdocumentexplorer_Click()
'The following has been adapted from here:
'https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-
filedialog-property-excel
Dim lngCount As Long
'Open the file dialog
With Application.FileDialog(msoFileDialogOpen)
.AllowMultiSelect = True
.Show
'Display paths of each file selected
For lngCount = 1 To .SelectedItems.Count
'MsgBox .SelectedItems(lngCount)
CreateObject("Shell.Application").ShellExecute
.SelectedItems(lngCount)
Next lngCount
End With
End Sub
Just as I needed all this code does is Simply open the file explorer when I click on the "Access Document Explorer" button that I have on my worksheet. From there it has the capability of opening any document/program I need opened/run.
Ozgrid forum Link
You may want to use the FileDialog object
Sub SelectFiles()
Dim FSelect As FileDialog, sFile as Variant
Set FSelect = Application.FileDialog(msoFileDialogOpen)
FSelect.Show
For Each sFile In FSelect.SelectedItems
Debug.Print sFile
'
' do stuff with file, full path in sFile
'
Next sFile
End Sub
You can also set filter paths to let the user open files of only one or more types, let them select single or multiple files, or only folders ... all in all a very versatile beast worth exploring.

How to assign a specific button in excel sheet to do some specific task?

I would like to have a button on this excel sheet whose name should be “Save as PDF”.
When I press this button it should save the excel sheet’s all data into PDF at the path- M:\formats\ ‘File Name’
‘File Name’ should be the value of cell No H8.
In another words when I click “Save as PDF” button it should save the excel file in pdf form, into the above mentioned path and also with the name whichever is written in cell no H8.
For example, if the name ANDREW PITTERSON is written in H8 cell then it should save with the same name I.e. ANDREW PITTERSON.
Kindly look at this snapshot.
http://i.imgur.com/JJdlFSi.jpg
THANKS
Here's a link to a great simple article, to do this sort of thing. http://www.contextures.com/excelvbapdf.html
I've tested the code example in Excel 2013 and it works fine. The code asks the user what directory to save the PDF in.
But your question says that you also want to save to a specific location (without user intervention) and to get the filename from a cell.
Update - And you'd also like to save the file as an XLSM, once the PDF is created.
The code below does what you're after (all credit to the original author, but my own OCD led me change var names to a format that I like).
I'm guessing the OP would like to know HOW it was done, rather than just have the answer, so I've tried to make the example easy to follow, rather than trying to observe best practice - I'd appreciate not being down-voted for this.
Please note, you must first open the Excel Code window, got to Tools, then References and select 'Microsoft Scripting Runtime' then click Ok. This lets you use many useful functions.
I keep the directory path (hard coded) and the filename separate, so that I can get the 'BaseName' in a clearer way. Obviously this could be done in less lines, but at the risk of making it harder to follow.
Sub ExportAPDF_and_SaveAsXLSM()
Dim wsThisWorkSheet As Worksheet
Dim objFileSystemObject As New Scripting.FileSystemObject
Dim strFileName As String
Dim strBasePath As String
strBasePath = "M:\formats\"
strFileName = Range("H8")
On Error GoTo errHandler
Set wsThisWorkSheet = ActiveSheet
wsThisWorkSheet.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=strBasePath & strFileName, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
MsgBox "PDF file has been created."
' Now we need to get rid of the .PDF extension. Many ways to code round this, but here is a built in function.
strFileName = objFileSystemObject.GetBaseName(strFileName) & ".xlsm"
wsThisWorkSheet.SaveAs Filename:=strBasePath & strFileName, FileFormat:=xlOpenXMLWorkbookMacroEnabled
MsgBox "Workbook now saved in XLSM format."
exitHandler:
Exit Sub
errHandler:
MsgBox "Could not create PDF file"
Resume exitHandler
End Sub
Just add the button (ActiveX Button) to your worksheet and call this sub from the buttons code window (or just paste the code directly into the Button code window).
Hope that helps.
ADDED:
To save the file as an XLSX (No Macros), then replace the code toward the end of the SUB with:
Application.DisplayAlerts = False
strFileName = objFileSystemObject.GetBaseName(strFileName) & ".xlsx"
wsThisWorkSheet.SaveAs Filename:=strBasePath & strFileName, FileFormat:=xlOpenXMLWorkbook
Application.DisplayAlerts = False

Extract data from text and selfdestruct

I'm currently working at a Uni project using Excel VBA and I'm trying to find a way to create an excel that will self destruct if it doesn't find the "Key". And in the event it's entirely impossible, then at least ensure there's none of the data or VBA code left.
The idea is that, using
Private Sub Workbook_Open()
Dim direct As String, name As String
name = ActiveWorkbook.Name
ChDir ThisWorkbook.Path
direct = ThisWorkbook.Path
Call Checker(direct, name)
End Sub
Upon opening the excel, it will look for "Key.txt" which should be within the same folder as the excel and check if the one string of text inside the document matches with "Code" which is a "Public Const" inside the project.
I've been trying to find a way to read the "Key.txt" without opening it, but haven't turned up anything.
On the other hand, I've been testing out various ways of making the program delete the original excel file, varying levels of success. So a somewhat roundabout way I've been testing out is to have the excel SaveAs a ".xlsx" and erase the original file before closing itself, but it doesn't work out as I've hoped for.
This is the code I've used for the "Self-Destruct" method:
Option Explicit
Function Checker(MyPath As String, name As String)
On Error Resume Next
Application.DisplayAlerts = False
Dim myPath2 As String
Dim ws As Worksheet
Dim FSO As Object
myPath2 = MyPath
ActiveWorkbook.SaveAs Filename:=MyPath & "\0_0.xlsx", FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
Sheets.Add After:=Sheets(Sheets.Count)
ActiveSheet.Name = "1"
For Each ws In Worksheets 'Deletes all other sheets
If ws.Name <> "1" Then ws.Delete
Next
Set FSO = CreateObject("scripting.filesystemobject")
If Right(MyPath, 1) = "\" Then MyPath = Left(MyPath, Len(MyPath) - 1)
If FSO.FolderExists(MyPath) = False Then MsgBox MyPath & " doesn't exist"
FSO.deletefile MyPath & "\" & name, True 'Deletes original file
ActiveWorkbook.Save
ActiveWorkbook.Close
End Function
Having a self-destructing file is an interesting idea. The short answer is that you cannot delete a running VBA macro. Therefore, no VBA macro can essentially self destruct. Yet, there are two options I can think of:
(1) Remove everything but the running macro. The following code might be helpful to achieve that.
http://www.erlandsendata.no/english/index.php?d=envbavbedeleteallmacros
(2) Close the file and ask Windows to delete the file afterwards for you using the task planner. The following post on SO might be able to help with that.
Using Excel vba Macro to be run through Windows Schedule Task
Other tempting solutions might be to save the file as .xlsx or to create a new Excel file, copy the above code from option 1 into that file, call the newly created code, which essentially deletes the original file.
But the real questions I'd ask myself would be: How did this person got the self-destructing file? Was it by email and the file is still in the email? Has the file been duplicated along the way? Are there hidden copies in some Temp-Folders (remember Excel Auto-Safe every xx minutes in case of computer crash to preserve your work)? Is the person enabling macros when opening the file (to allow self-destruction)? Can the person resore the file with the many free programs out there to recover files from a Windows machine (extremely easy as Windows does not delete the file or writes cryptical data on top to ensure it cannot be recovered, but merely "marks" that space on the HD where the file was as free to use for the next file to come)?

Getting "method saveas of object _workbook failed" error while trying to save an XLSM as CSV

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.

Resources