Excel Macro | adding two together - excel

Complete New to this, I and trying to add 2 macros as one. One that exports Excel to CVS and has a dialog box for file Name save and another file Dialog folder picker. assistance would be greatly appreciated
Sub ExportAsCSV()
Dim MyFileName As String
Dim CurrentWB As Workbook, TempWB As Workbook
Set CurrentWB = ActiveWorkbook
ActiveWorkbook.ActiveSheet.UsedRange.Copy
Set TempWB = Application.Workbooks.Add(1)
With TempWB.Sheets(1).Range("A1")
.PasteSpecial xlPasteValues
.PasteSpecial xlPasteFormats
End With
MyFileName = CurrentWB.Path & "\" & Left(CurrentWB.Name, Len(CurrentWB.Name) - 5) & ".csv"
Application.DisplayAlerts = False
TempWB.SaveAs fileName:=InputBox("Enter file name here, : ", , xFileName), FileFormat:=xlCSV, CreateBackup:=False, Local:=True
TempWB.Close SaveChanges:=False
Application.DisplayAlerts = True
End Sub
'''''''''''''''
'Plus file dialog
'''''''''''''''''''''''
Sub SelectFolder()
Dim diaFolder As FileDialog
Set diaFolder = Application.FileDialog(msoFileDialogFolderPicker)
diaFolder.AllowMultiSelect = False
diaFolder.Show
ActiveSheet.Copy
ActiveWorkbook.SaveAs fileName:= _
diaFolder & ActiveSheet.[d2] & ".xlsx", FileFormat:= _
xlExcel8, Password:="", WriteResPassword:="", ReadOnlyRecommended:=False _
, CreateBackup:=False
Set diaFolder = Nothing
End Sub

Your question is a little awkward because of the structure you propose. Normally, the name would be supplied by a function and acted upon by the calling procedure. Try to implement this structure in your project. Here is the function.
Private Function FolderName() As String
Dim FilePicker As FileDialog
Set FilePicker = Application.FileDialog(msoFileDialogFolderPicker)
With FilePicker
.Title = "Select a target folder"
.AllowMultiSelect = False
.InitialFileName = Environ("UserProfile") & "\Documents\"
.ButtonName = "Confirm"
If .Show Then
FolderName = .SelectedItems(1)
End If
End With
End Function
And this is the part that should go into the calling procedure in some way.
Dim MyFolder As String
MyFolder = FolderName
If Len(MyFolder) Then MsgBox MyFolder
Of course, instead of the MsgBox your code would use the selected file name to actually save the workbook - code included in your SelectFolder procedure. The point is that no attempt to save the file is made if the user pressed Cancel. In that case the function returns an empty string which the calling procedure recognizes by the test of Len(MyFolder).

Related

VBA - Skip corrupted files

I copied code from another site that opens every Excel file on a path and sets the password to "".
I have 480 Excel files on that path, and the code stops whenever it encounters a corrupted file.
Is there a way to identify every file that is corrupted?
Is there a way to avoid corrupted files?
Sub RemovePasswords()
Dim xlBook As Workbook
Dim strFilename As String
Const fPath As String = "C:\Path\" 'The folder to process, must end with "\"
Const strPassword As String = "openpassword" 'case sensitive
Const strEditPassword As String = "editpassword" 'If no password use ""
strFilename = Dir$(fPath & "*.xls") 'will open xls & xlsx etc
While Len(strFilename) <> 0
Application.DisplayAlerts = False
Set xlBook = Workbooks.Open(FileName:=fPath & strFilename, _
Password:=strPassword, _
WriteResPassword:=strEditPassword)
xlBook.SaveAs FileName:=fPath & strFilename, _
Password:="", _
WriteResPassword:="", _
CreateBackup:=True
xlBook.Close 0
Application.DisplayAlerts = True
strFilename = Dir$()
Wend
End Sub
On the other hand, whenever the code encounters a corrupted file it just stops and doesn't let me know which file is corrupted.
I know that there is a way to put a "if" to skip this errors, but I don't know how to do it.
Please, try the next adapted code:
Sub RemovePasswords()
Dim xlBook As Workbook, strFilename As String
Const fPath As String = "C:\Path\" 'The folder to process, must end with "\"
Const strPassword As String = "openpassword" 'case sensitive
Const strEditPassword As String = "editpassword" 'If no password use ""
strFilename = dir$(fPath & "*.xls") 'will open xls & xlsx etc
While Len(strFilename) <> 0
On Error Resume Next 'skip the error, if the case
Set xlBook = Workbooks.Open(fileName:=fPath & strFilename, _
password:=strPassword, _
WriteResPassword:=strEditPassword)
If err.Number = 0 Then 'if no error:
Application.DisplayAlerts = False
xlBook.saveas fileName:=fPath & strFilename, _
password:="", _
WriteResPassword:="", _
CreateBackup:=True
xlBook.Close 0
Application.DisplayAlerts = True
End If
On Error GoTo 0 'restart raising errors when the case
strFilename = dir$()
Wend
End Sub
I would change the code suggested by FaneDuru a little, in order to comply to your first demand. This code will output corrupt filenames in the debug panel.
Sub RemovePasswords()
Dim xlBook As Workbook
Dim strFilename As String
Const fPath As String = "C:\Path\" 'The folder to process, must end with "\"
Const strPassword As String = "openpassword" 'case sensitive
Const strEditPassword As String = "editpassword" 'If no password use ""
strFilename = Dir$(fPath & "*.xls") 'will open xls & xlsx etc
Application.DisplayAlerts = False
On Error Resume Next
While Len(strFilename) <> 0
Set xlBook = Workbooks.Open(FileName:=fPath & strFilename, _
Password:=strPassword, WriteResPassword:=strEditPassword)
If err.Number = 0 Then
xlBook.SaveAs FileName:=fPath & strFilename, _
Password:="", WriteResPassword:="", CreateBackup:=True
xlBook.Close 0
Else
Debug.Print strFilename 'This will output corrupt filenames in the debug pane
err.Clear
End If
strFilename = Dir$()
Wend
On Error GoTo 0
Application.DisplayAlerts = True
End Sub

Converting multiple xlsl files to xls (97-2003 Worksheet) extension without changing the names

I am trying to loop through all the 'xlsx' files in a folder and convert them to 'xls' ( Excel 97-2003 Worksheet) format. I use the following codes but then the output files are still saved as 'xlsx' instead of 'xls'. I am a beginner and looking to learn more from others. Thanks for your help!
Sub Convert()
Dim strPath As String
Dim strFile As String
Dim strfilenew As String
Dim xWbk As Workbook
Dim xSFD, xRFD As FileDialog
Dim xSPath As String
Dim xRPath As String
Set xSFD = Application.FileDialog(msoFileDialogFolderPicker)
With xSFD
.Title = "Please select the folder contains the xls files:"
.InitialFileName = "C:\"
End With
If xSFD.Show <> -1 Then Exit Sub
xSPath = xSFD.SelectedItems.Item(1)
Set xRFD = Application.FileDialog(msoFileDialogFolderPicker)
With xRFD
.Title = "Please select a folder for outputting the new files:"
.InitialFileName = "C:\"
End With
If xRFD.Show <> -1 Then Exit Sub
xRPath = xRFD.SelectedItems.Item(1) & "\"
strPath = xSPath & "\"
strFile = Dir(strPath & "*.xlsx")
strfilenew = Dir(strPath & "*.xls")
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Do While strFile <> ""
If Right(strFile, 4) = "xlsx" Then
Set xWbk = Workbooks.Open(Filename:=strPath & strfilenew)
xWbk.SaveAs Filename:=xRPath & strfilenew, _
FileFormat:=xlExcel18
xWbk.Close SaveChanges:=True
End If
strFile = Dir
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
There was a bit of a mix-up in your file naming, basically as evidenced by the several double-declarations that I removed. The really big mistake was here, Set xWbk = Workbooks.Open(Filename:=strPath & strfilenew) where you tried to open the old workbook by the new name. I think the confusion started here "Please select the folder contains the xls files:". Of course, this is the folder with the XLSX files. The recommended antidote is to use "meaningful" variable names but you chose to speak in riddles (like xSFD) which makes coding more difficult.
However, the code below is largely yours, and it does work.
Sub Convert()
' 230
Dim Spath As String ' path to read from (XLSX files)
Dim Rpath As String ' path to write to (XLS files)
Dim strFile As String ' loop variable: current file name
Dim Wbk As Workbook ' loop object: current workbook(strFile)
Dim Sp() As String ' split array of strFile
Dim strFileNew As String
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select the folder contains the XLSX files:"
.InitialFileName = "C:\"
If .Show <> -1 Then Exit Sub
Spath = .SelectedItems.Item(1) & "\"
End With
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Please select a folder for outputting the new files:"
.InitialFileName = "C:\"
If .Show <> -1 Then Exit Sub
Rpath = .SelectedItems.Item(1) & "\"
End With
With Application
.ScreenUpdating = False
.DisplayAlerts = False
End With
strFile = Dir(Spath & "*.xlsx")
Do While strFile <> ""
If Right(strFile, 4) = "xlsx" Then
Sp = Split(strFile, ".")
Sp(UBound(Sp)) = "xls"
strFileNew = Join(Sp, ".")
Set Wbk = Workbooks.Open(Filename:=Spath & strFile)
Wbk.SaveAs Filename:=Rpath & strFileNew, FileFormat:=xlExcel8
Wbk.Close SaveChanges:=True
End If
strFile = Dir
Loop
With Application
.ScreenUpdating = True
.DisplayAlerts = True
End With
End Sub
Observe that the new file name is created by splitting the old name on periods, changing the last element, and reassembling the modified array.

Loop Freezing Excel After Printing

I have a spreadsheet that creates a CSV file and deposits the CSV file in a folder next to the original file. The spreadsheet seems to work fine. When you have your data entered, you click export, and a CSV file is put in a folder called "Uploads" that is next to the original file.
The issue is when I use the quick print button on my Excel quick access toolbar. When I click the quick print button, everything seems to print fine. However, as soon as I close the file, (EDIT: ALL Printing seems to be freezing the file. As soon as the file is closed) Excel then goes into a freeze where it looks like it is trying to run some code? I am a novice in VBA so I am not sure what is happening, all I know is that after my file is closed, Excel freezes up and I have to restart Excel. I do not even have any macros or VBA for an Excel close or Excel open trigger.
Can anyone recreate the issue and give me insight into how my code might be doing this?
Private Sub Export_Click()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim MyPath As String
Dim MyFileName As String
'The path and file names:
MyPath = ActiveWorkbook.Path & "\Uploads"
MyFileName = "" & Range("a2") & "_Upload"
On Error GoTo Ending
'Makes sure the path name ends with "\":
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
'Makes sure the filename ends with ".csv"
If Not Right(MyFileName, 4) = ".csv" Then MyFileName = MyFileName & ".csv"
'Copies the sheet to a new workbook:
Sheets("UploadData").Copy
'The new workbook becomes Activeworkbook:
With ActiveWorkbook 'Saves the new workbook to given folder / filename:
.SaveAs FileName:= _
MyPath & MyFileName, _
FileFormat:=xlCSV, _
CreateBackup:=False 'Closes the file
.Close False
End With
ChDir MyPath
Workbooks.Open FileName:= _
MyPath & "\" & MyFileName & """"
ActiveWorkbook.Save
ActiveWorkbook.Close
GoTo Skip
Ending:
MsgBox ("ERROR! Please make sure you have a folder named Uploads next to the template file")
ActiveWorkbook.Close
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Skip:
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
This actually shouldn't work at all, regardless of what you do before you run it. First, you ensure that MyPath ends with a \ here...
'Makes sure the path name ends with "\":
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
...but then when you (re)build the same path below you're inserting a second \:
Workbooks.Open FileName:= _
MyPath & "\" & MyFileName & """"
This should always fail. You can avoid this entire problem with paths by using the Scripting.FileSystemObject's .BuildPath function:
'Requires a reference to Microsoft Scripting Runtime.
Dim filePath As String, fso As New Scripting.FileSystemObject
filePath = fso.BuildPath(ThisWorkbook.Path, MyFileName)
You can also use this for the file extension:
If LCase$(fso.GetExtensionName(MyFileName)) <> "csv" Then
MyFileName = MyFileName & ".csv"
End If
Note that this test will never be true...
If Not Right(MyFileName, 4) = ".csv" Then MyFileName = MyFileName & ".csv"
...because MyFileName will always end with "load":
MyFileName = "" & Range("a2") & "_Upload"
Also, you should remove all the references to ActiveWorkbook. I have no idea why printing would effect this, but there isn't anything else I can identify that should be an issue. I'd structure it more like this (error handler removed for clarity - don't put it back until you're finished debugging it):
'Add a reference to Microsoft Scripting Runtime.
Private Sub Export_Click()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
With New Scripting.FileSystemObject
Dim filePath As String
Dim targetDir As String
targetDir = .BuildPath(ThisWorkbook.Path, "Uploads")
If Not .FolderExists(targetDir) Then
MsgBox ("ERROR! Please make sure you have a folder named Uploads next to the template file")
Exit Sub
End If
filePath = .BuildPath(targetDir, ActiveSheet.Range("A2").Value & "_Upload.csv")
End With
'Copies the sheet to a new workbook:
Dim csv As Workbook
Set csv = Application.Workbooks.Add
With csv
ThisWorkbook.Sheets("UploadData").Copy .Sheets(1)
.SaveAs Filename:=filePath, _
FileFormat:=xlCSV, _
CreateBackup:=False 'Closes the file
.Close xlDoNotSaveChanges
End With
'Reopen and re-save to fix formatting.
Set csv = Workbooks.Open(filePath)
csv.Close xlSaveChanges
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

Export sheet as new Excel file (values only)

I found code in this discussion which has been extremely helpful for exporting Excel sheets as a new workbook. I've posted the version of the code that I currently use below.
As this code stands, it copies the content of the desired sheet to a new workbook, formulas and all.
Is it possible to modify this code to copy values only to this new workbook?
I appreciate any insight anyone can lend.
Sub ExportXLSX()
'exports desired sheet to new XLSX file
Dim MyPath As String
Dim MyFileName As String
Dim DateString As String
DateString = Format(Now(), "yyyy-mm-dd_hh_mm_ss_AM/PM")
MyFileName = DateString & "_" & "Whatever You Like"
If Not Right(MyFileName, 4) = ".xlsx" Then MyFileName = MyFileName & ".xlsx"
Sheets("Desired Sheet").Copy
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Where should we save this?"
.AllowMultiSelect = False
.InitialFileName = "" '<~~ The start folder path for the file picker.
If .Show <> -1 Then GoTo NextCode
MyPath = .SelectedItems(1) & "\"
End With
NextCode:
With ActiveWorkbook
.SaveAs Filename:=MyPath & MyFileName, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
.Close False
End With
End Sub
See revised NextCode section for solution:
NextCode:
With ActiveWorkbook
.ActiveSheet.UsedRange.Value = ActiveSheet.UsedRange.Value '<~~ converts contents of XLSX file to values only
.SaveAs Filename:=MyPath & MyFileName, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
.Close False
End With

How to browse for save directory?

By clicking a button in Excel, the user exports a specific sheet to a csv with a dynamic filename and the csv is saved in a pre-determined directory.
Instead of saving to a predetermined directory, can users have the browse window to choose a directory to save to?
Sub Export()
Dim MyPath As String
Dim MyFileName As String
MyPath = "C:\importtest"
MyFileName = "MR_Update_" & Sheets("Monthly Review").Range("D3").Value & "_" & Format(Date, "ddmmyyyy")
If Not Right(MyPath, 1) = "\" Then MyPath = MyPath & "\"
If Not Right(MyFileName, 4) = ".csv" Then MyFileName = MyFileName & ".csv"
Sheets("Export Data").Copy
With ActiveWorkbook
.SaveAs Filename:= _
MyPath & MyFileName, _
FileFormat:=xlCSV, _
CreateBackup:=False
.Close False
End With
End Sub
Excel has an inbuilt FileSave Dialog. It is called .GetSaveAsFilename. Use that.
Syntax
expression.GetSaveAsFilename(InitialFilename, FileFilter, FilterIndex, Title, ButtonText)
Usage
Dim fileSaveName As Variant
fileSaveName = Application.GetSaveAsFilename( _
fileFilter:="Excel Files (*.csv), *.csv")
If fileSaveName <> False Then
'
'~~> Your code to save the file here
'
End If
As Patrick suggested, you're looking for the .FileDialog property.
To implement it, try this:
Sub Export()
Dim MyPath As String
Dim MyFileName As String
MyFileName = "MR_Update_" & Sheets("Monthly Review").Range("D3").Value & "_" & Format(Date, "ddmmyyyy")
If Not Right(MyFileName, 4) = ".csv" Then MyFileName = MyFileName & ".csv"
Sheets("Export Data").Copy
With Application.FileDialog(msoFileDialogFolderPicker)
.Title = "Select a Folder"
.AllowMultiSelect = False
.InitialFileName = "" '<~~ The start folder path for the file picker.
If .Show <> -1 Then GoTo NextCode
MyPath = .SelectedItems(1) & "\"
End With
NextCode:
With ActiveWorkbook
.SaveAs Filename:=MyPath & MyFileName, FileFormat:=xlCSV,CreateBackup:=False
.Close False
End With
End Sub
Try This......
Sub Export()
Dim MyPath As String
Dim MyFileName As String
MyPath = "C:\importtest"
MyFileName = "MR_Update_" & Sheets("Monthly Review").Range("D3").Value & "_" & Format(Date, "ddmmyyyy")
If Not Right(MyFileName, 4) = ".csv" Then MyFileName = MyFileName & ".csv"
Sheets("Export Data").Copy
With ActiveWorkbook
.SaveAs Filename:= _
MyFileName, _
FileFormat:=xlCSV, _
CreateBackup:=False
.Close False
End With
End Sub
Here's a script I've been using lately that I like a lot. Thought I would leave this here:
Sub ExportCSV()
Dim FlSv As Variant
Dim MyFile As String
Dim sh As Worksheet
Dim MyFileName As String
Dim DateString As String
DateString = Format(Now(), "yyyy-mm-dd_hh_mm_ss_AM/PM") '<~~ uses current time from computer clock down to the second
MyFileName = DateString & "_" & "Whatever you like"
Set sh = Sheets("Sheet you'd like to export")
sh.Copy
FlSv = Application.GetSaveAsFilename(MyFileName, fileFilter:="CSV (Comma delimited) (*.csv), *.csv", Title:="Where should we save this?")
If FlSv = False Then GoTo UserCancel Else GoTo UserOK
UserCancel: '<~~ this code is run if the user cancels out the file save dialog
ActiveWorkbook.Close (False)
MsgBox "Export canceled"
Exit Sub
UserOK: '<~~ this code is run if user proceeds with saving the file (clicks the OK button)
MyFile = FlSv
With ActiveWorkbook
.SaveAs (MyFile), FileFormat:=xlCSV, CreateBackup:=False
.Close False
End With
End Sub

Resources