So i have a VBA script that takes user input via userform then creates an output workbook to contain the data and saves it as a .csv. The issue im having is when i want to create the folder that the files will be saved into the directory is not the same for each workstation because my company uses Microsoft One Drive which changes the file path for the desktop. I have gotten this to work on my machine but every time i send my form to a user for testing they receive a runtime error and the application cannot create the folder on the desktop. on one occasion the folder was saved in "My Documents" when that is nowhere in my code. Hope you can help.
i have changed my code several times using if statements to verify the file path but i still see the same issue
User = Environ("Username") 'set the current users username to the User variable
WBpath = "C:\Users\" & User & "\OneDrive - CompanyName\Desktop" 'windows directory where the file will go
WBpath2 = "C:\Users\" & User & "\Desktop" 'windows directory where the file will go
WBName = "BulkUpload" & UserForm1.TextBox5.value & ".csv" 'the name of the file
WBFile = WBpath & "\BulkUploadFiles\" & WBName 'full file path we will be saving the file in
WBFile2 = WBpath2 & "\BulkUploadFiles\" & WBName 'full file path we will be saving the file in
For Each wb In Workbooks 'loop through each open excel workbook and perform the below action
If wb.Name = WBName Then 'perform the below action only if the currently selected workbook has the same name as the output workbook
Workbooks(WBName).Close 'close the selected excel workbook
End If 'done checking if the file is already open
Next 'go to the next open excel workbook
'make the directory to save the bulkupload file to. create it if it doesnt already exist.
If Dir(WBpath, vbDirectory) <> "" Then 'check is the folder already exists
ChDir WBpath 'change the directory to WBPath
If Dir(WBpath & "\BulkUploadFiles\", vbDirectory) = "" Then
MkDir "BulkUploadFiles" 'create the output folder
End If
Set NewBook = Workbooks.Add 'create the output workbook
With NewBook 'set the properties for the output workbook
.Title = WBName 'add the workbook title
.Subject = WBName 'add the workbook subject
.SaveAs filename:=WBFile, FileFormat:=xlCSV, local:=True 'save the output workbook to the assigned directory as a CSV file
End With 'done setting file properties
End If
If Dir(WBpath2, vbDirectory) <> "" Then 'check is the folder already exists
ChDir WBpath2 'change the directory to WBPath2
If Dir(WBpath2 & "\BulkUploadFiles\", vbDirectory) = "" Then
MkDir "BulkUploadFiles" 'create the output folder
End If
Set NewBook = Workbooks.Add 'create the output workbook
With NewBook 'set the properties for the output workbook
.Title = WBName 'add the workbook title
.Subject = WBName 'add the workbook subject
.SaveAs filename:=WBFile2, FileFormat:=xlCSV, local:=True 'save the output workbook to the assigned directory as a CSV file
End With 'done setting file properties
End If
Workbooks(WBName).Sheets("BulkUpload" & UserForm1.TextBox5.value).Name = "Sheet1" 'rename the first sheet in the output workbook back to Sheet1 so we can reference it correctly later
Workbooks(WBName).Sheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Sheet3" 'add a new sheet to the output workbook
Workbooks(WBName).Sheets("Sheet3").Visible = xlSheetHidden 'hide the new sheet we just made (Sheet3)
on my workstation (with one drive installed) this works fine but on other users pcs i receive an error when attempting to create the folder and fil
Instead of this:
ChDir WBpath 'change the directory to WBPath
If Dir(WBpath & "\BulkUploadFiles\", vbDirectory) = "" Then
MkDir "BulkUploadFiles" 'create the output folder
End If
You can skip the ChDir and just use something like this:
fPath = WBpath & "\BulkUploadFiles"
If Dir(fPath, vbDirectory) = "" Then
MkDir fPath
End If
ChDir does not set the working folder if the user's current working folder is on a different drive
EDIT: this worked for me but I'm not sure what you want to do when adding multiple sheets to a CSV-format file, since a CSV can have only one "sheet"
Dim deskTop, wbName As String, folderName As String, newBook As Workbook
Dim txtVal As String
txtVal = UserForm1.TextBox5.Value
deskTop = CreateObject("Wscript.Shell").specialfolders("Desktop")
wbName = "BulkUpload" & txtVal & ".csv" 'the name of the file
'close the workbook if it's open
On Error Resume Next 'ignore error if the file is not open
Workbooks(wbName).Close
On Error GoTo 0 'stop ignoring errors
folderName = deskTop & "\BulkUploadFiles\"
If Len(Dir(folderName, vbDirectory)) = 0 Then MkDir folderName
Set newBook = Workbooks.Add 'create the output workbook
With newBook
.Title = wbName
.Subject = wbName
.SaveAs Filename:=folderName & wbName, FileFormat:=xlCSV, local:=True
.Sheets(1).Name = "Sheet1"
'??? a csv file can't have multiple sheets...
'.Sheets.Add(After:=.Worksheets(.Worksheets.Count)).Name = "Sheet3"
'.Worksheets(.Worksheets.Count).Visible = xlSheetHidden
End With
Here is my updated code. I tried using if statements to validate the path but this is still failing on every workstation except mine.
Dim NewBook As Variant
Dim WBpath, WBpath2, WBName, WBFile, WBFile2, WBDir, WBDir2, Fpath, Fpath2 As String
Dim User As String
Dim WS As Worksheet
Dim wb As Workbook
User = Environ("Username") 'set the current users username to the User variable
WBpath = "C:\Users\" & User & "\OneDrive - CompanyName\Desktop" 'windows directory where the file will go
WBpath2 = "C:\Users\" & User & "\Desktop" 'windows directory where the file will go
WBName = "BulkUpload" & UserForm1.TextBox5.value & ".csv" 'the name of the file
WBFile = WBpath & "\BulkUploadFiles\" & WBName 'full file path we will be saving the file in
WBFile2 = WBpath2 & "\BulkUploadFiles\" & WBName 'full file path we will be saving the file in
For Each wb In Workbooks 'loop through each open excel workbook and perform the below action
If wb.Name = WBName Then 'perform the below action only if the currently selected workbook has the same name as the output workbook
Workbooks(WBName).Close 'close the selected excel workbook
End If 'done checking if the file is already open
Next 'go to the next open excel workbook
'make the directory to save the bulkupload file to. create it if it doesnt already exist.
Fpath = WBpath & "\BulkUploadFiles\"
If Dir(WBpath2, vbDirectory) <> "" Then
If Dir(Fpath, vbDirectory) = "" Then
MkDir Fpath
Set NewBook = Workbooks.Add 'create the output workbook
With NewBook 'set the properties for the output workbook
.Title = WBName 'add the workbook title
.Subject = WBName 'add the workbook subject
.SaveAs filename:=WBFile, FileFormat:=xlCSV, local:=True 'save the output workbook to the assigned directory as a CSV file
End With 'done setting file properties
End If
End If
Fpath2 = WBpath2 & "\BulkUploadFiles\"
If Dir(WBpath2, vbDirectory) <> "" Then
If Dir(Fpath2, vbDirectory) = "" Then
MkDir Fpath
Set NewBook = Workbooks.Add 'create the output workbook
With NewBook 'set the properties for the output workbook
.Title = WBName 'add the workbook title
.Subject = WBName 'add the workbook subject
.SaveAs filename:=WBFile2, FileFormat:=xlCSV, local:=True 'save the output workbook to the assigned directory as a CSV file
End With 'done setting file properties
End If
End If
Workbooks(WBName).Sheets("BulkUpload" & UserForm1.TextBox5.value).Name = "Sheet1" 'rename the first sheet in the output workbook back to Sheet1 so we can reference it correctly later
Workbooks(WBName).Sheets.Add(After:=Worksheets(Worksheets.Count)).Name = "Sheet3" 'add a new sheet to the output workbook
Workbooks(WBName).Sheets("Sheet3").Visible = xlSheetHidden 'hide the new sheet we just made (Sheet3)
Related
I tried this script to convert xlsx files to csv.
I want the old files to be in the folder and the name on csv file to be exact as xlsx file.
I am getting . extra on the csv extension like filename..csv.
Sub ConvertCSVToXlsx()
Dim myfile As String
Dim oldfname As String, newfname As String
Dim workfile
Dim folderName As String
Application.DisplayAlerts = False
Application.ScreenUpdating = False
' Capture name of current file
myfile = ActiveWorkbook.Name
' Set folder name to work through
folderName = "C:\Test\"
' Loop through all CSV filres in folder
workfile = Dir(folderName & "*.xlsx")
Do While workfile <> ""
' Open CSV file
Workbooks.Open Filename:=folderName & workfile
' Capture name of old CSV file
oldfname = ActiveWorkbook.FullName
' Convert to XLSX
newfname = folderName & Left(ActiveWorkbook.Name, Len(ActiveWorkbook.Name) - 4) & ".CSV"
ActiveWorkbook.SaveAs Filename:=newfname, FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
ActiveWorkbook.Close
' Delete old CSV file
Kill oldfname
Windows(myfile).Activate
workfile = Dir()
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Pretty close.
Your comments are a bit confusing in the code.
If you are going to use left(len()-4 then you need to change the part to add csv without the period.
newfname = oldfname & "CSV"
Just a bit of an edit with the saveas line
You don't kill the original workbook, that deletes it from the folder.
The original workbook is no longer opened because you saved it as a new filename.
Sub ConvertCSVToXlsx()
Dim myfile As String
Dim oldfname As String, newfname As String
Dim workfile
Dim folderName As String
Dim wb As Workbook
Application.DisplayAlerts = False
Application.ScreenUpdating = False
' Capture name of current file
myfile = ActiveWorkbook.Name
' Set folder name to work through
folderName = "C:\New folder\"
' Loop through all CSV filres in folder
workfile = Dir(folderName & "*.xlsx")
Do While workfile <> ""
' Open CSV file
Workbooks.Open Filename:=folderName & workfile
Set wb = ActiveWorkbook
' Capture name of old CSV file
oldfname = Left(wb.FullName, Len(wb.FullName) - 4)
' Convert to XLSX
newfname = oldfname & "CSV"
wb.SaveAs Filename:=newfname, FileFormat:=xlCSV, CreateBackup:=False
wb.Close
workfile = Dir()
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
I'm trying to apply different macros to every excel file present in a folder adding several sheets to them, and to do so I'm looping over all the files in the folder and opening them one by one.
However, I stumbled upon the issue that, every workbook I open is in read only mode, thus preventing me from saving it after having modified it.
Setting the ReadOnly parameter to False, and the IgnoreReadOnlyRecommended parameter to True doesn't change anything, and the workbook still opens as a read only workbook.
Sub RunOnAllFilesInFolder()
Dim folderName As String, fileName As String
Dim wb As Workbook
folderName = "H:\mypath"
fileName = Dir(folderName & "\*.xlsx")
Debug.Print (fileName)
Do While fileName <> ""
Set wb = Workbooks.Open(fileName:=folderName & "\" & fileName, ReadOnly:=False, IgnoreReadOnlyRecommended:=True)
MsgBox (wb.ReadOnly)
wb.Activate
Call my_sub
Application.DisplayAlerts = False
wb.SaveAs (folderName & "\" & fileName)
wb.Close SaveChanges:=False
Set wb = Nothing 'clean up
Application.DisplayAlerts = True
Debug.Print "Processed " & folderName & "\" & fileName
fileName = Dir()
Loop
End Sub
Would anyone know why the file opens as a read only file (despite being just a regular excel file), or another way to modify these files and save the changes?
I have an Excel file with a .PPTM embedded into a sheet (nothing else is on the sheet). I want to run a macro that is in the PPTM file.
The problem is the last line of code to run the macro. The cell in worksheet "PPTM" that has the embedded file has a formula of "=EMBED("Presentation","")"
Sub run_ppt_macro()
fName = ActiveWorkbook.Name
Path = ActiveWorkbook.Path
Worksheets("PPTM").OLEObjects("PPT_Temp_19").Verb 0
Dim PPTObj As Object
Set myPP = GetObject(, "PowerPoint.Application")
Set PPTObj = myPP.ActivePresentation
PPTObj.Run PPTObj.Name & "!Main", fName, Path
End Sub
Thanks Shyam, that was part of the problem. Because the file is opened through IE or Email, it opens in a very odd place that errors the macro. I solved the problem by saving both the data (XLSM) file and the template (PPTM) file to the temp directory, before creating the new report.
Sub auto_open()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
fName = ActiveWorkbook.Name
tempath = IIf(Environ$("tmp") <> "", Environ$("tmp"), Environ$("temp")) 'finds the temporary evironment on the current machine
ActiveWorkbook.SaveAs Filename:=(tempath & "\" & fName)
MsgBox "Your report " & tempath & "\" & fName & " should be completed within 5 minutes." & Chr(10) & Chr(10) & "Please check your PowerPoint application at that time." & Chr(10) & Chr(10) & "Thank you.", vbInformation
Dim PPTObj As Object
Worksheets("PPTM").OLEObjects("PPT_Temp_19").Verb 3 'opens the embedded object
Set myPP = GetObject(, "PowerPoint.Application") 'get the PowerPoint object
Set PPTObj = myPP.ActivePresentation 'Get the presentation that was opened
tempath = IIf(Environ$("tmp") <> "", Environ$("tmp"), Environ$("temp")) 'finds the temporary evironment on the current machine
Template = tempath & "\template.pptm" 'creates path and name for temp file
PPTObj.SaveAs Filename:=(Template) 'saves temp file
myPP.Presentations.Open (Template) 'opens the saved file
Worksheets("PPTM").OLEObjects("PPT_Temp_19").Object.Close
myPP.Run Template & "!Main", fName, tempath 'runs the macro
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
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
I have a small script allowing me to traverse through all xslx files in the current folder, and saving them all as xml worksheets.
That works fine, but I'd like to save them in a subfolder, and that's where things go wrong as I'm always saving the same file again. I'm not too familiar with the Dir syntax, so if someone could help me out a bit I would be really grateful.
This part works as expected :
Sub XLS2XML()
Application.DisplayAlerts = False
Dim folderPath As String
Dim Report As String
Dim ReportName As String
Dim XMLLocation As String
Dim XMLReport As String
Dim WB As Workbook
'set path to current location
folderPath = ThisWorkbook.Path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
'loop through all xlsx files
Report = Dir(folderPath & "*.xlsx")
Do While Report <> ""
Set WB = Workbooks.Open(folderPath & Report)
'get the file name without path
ReportName = Split(Report, ".")(0)
XMLLocation = folderPath
XMLReport = XMLLocation & ReportName & ".xml"
'save the file as xml workbook
ActiveWorkbook.SaveAs filename:=XMLReport, _
FileFormat:=xlXMLSpreadsheet, ReadOnlyRecommended:=False, CreateBackup:=False
'close and next
WB.Close False
Report = Dir
Loop
MsgBox "All XML files have been created"
Application.DisplayAlerts = True
End Sub
and this one fails on me :
Sub XLS2XML()
Application.DisplayAlerts = False
Dim folderPath As String
Dim Report As String
Dim ReportName As String
Dim XMLLocation As String
Dim XMLReport As String
Dim WB As Workbook
'set path to current location
folderPath = ThisWorkbook.Path
If Right(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
'loop through all xlsx files
Report = Dir(folderPath & "*.xlsx")
Do While Report <> ""
Set WB = Workbooks.Open(folderPath & Report)
'get the file name without path and save it in xml folder
ReportName = Split(Report, ".")(0)
XMLLocation = folderPath & "xml"
XMLReport = XMLLocation & "\" & ReportName & ".xml"
'create xml folder if it doesn't exist yet
If Len(Dir(XMLLocation, vbDirectory)) = 0 Then
MkDir XMLLocation
End If
'save the file as xml workbook
ActiveWorkbook.SaveAs filename:=XMLReport, _
FileFormat:=xlXMLSpreadsheet, ReadOnlyRecommended:=False, CreateBackup:=False
'close and next
WB.Close False
Report = Dir
Loop
Any idea where my syntax goes wrong ? Also, is it possible to do the same thing in silent mode ? So without opening the workbooks ?
Thanks !
Your issue is that you are using a second Dir within your initial Dir loop to test and create the xml subdirectory.
You can - and should move this outside the loop - especially as it is a one-off test and shouldn't be looped to begin with. Something like this below
(You otherwise used Dir fine, as per my simple wildcard code example in Loop through files in a folder using VBA?)
Sub XLS2XML()
Application.DisplayAlerts = False
Dim folderPath As String
Dim Report As String
Dim ReportName As String
Dim XMLlocation As String
Dim XMLReport As String
Dim WB As Workbook
'set path to current location
folderPath = ThisWorkbook.Path
XMLlocation = folderPath & "xml"
If Len(Dir(XMLlocation, vbDirectory)) = 0 Then MkDir XMLlocation
If Right$(folderPath, 1) <> "\" Then folderPath = folderPath + "\"
'loop through all xlsx files
Report = Dir(folderPath & "*.xlsx")
Do While Len(Report) > 0
Set WB = Workbooks.Open(folderPath & Report)
'get the file name without path and save it in xml folder
ReportName = Split(Report, ".")(0)
XMLReport = XMLlocation & "\" & ReportName & ".xml"
'save the file as xml workbook
WB.SaveAs Filename:=XMLReport, _
FileFormat:=xlXMLSpreadsheet, ReadOnlyRecommended:=False, CreateBackup:=False
'close and next
WB.Close False
Report = Dir
Loop
End Sub