ActiveWorkbook.SaveAs excel 2013 1004 error - excel

I am getting a
Run-time error '1004' Method 'SaveAs' of object '_Workbook' failed.
The code works in excel 2010. I only get this error message in excel 2013.
The error message appears after trying to run the follow line.
ActiveWorkbook.SaveAs FolderPath & SaveName & NewSaveExt, 52
Background:
The spreadsheet is an .xls
When using the Saveas I am changing it to .xlsm
I have tried it with a .xls extension and fileformat 56 and it still falls over.
I am using code from the resources listed in the code.
I am saving the file to the same folder the workbook is in.
The orignal file name is: Financial Report as at month N.xls
The new filename is : Financial Report 1516 as at month 8.xlsm
Sub SaveNewVersion_Excel()
'PURPOSE: Save file, if already exists add a new version indicator to filename
'SOURCE: www.TheSpreadsheetGuru.com/The-Code-Vault
Dim FolderPath As String
Dim myPath As String
Dim SaveName As String
Dim SaveExt As String
Dim NewSaveExt As String
Dim VersionExt As String
Dim Saved As Boolean
Dim x As Long
TestStr = ""
Saved = False
x = 0
NewSaveExt = ".xlsm"
'Version Indicator (change to liking)
VersionExt = "_v"
'Pull info about file
On Error GoTo NotSavedYet
myPath = ActiveWorkbook.FullName
myFileName = "Financial Report " & FileFinancialYear & " as at month " & MonthNumber
FolderPath = Left(myPath, InStrRev(myPath, "\"))
SaveExt = "." & Right(myPath, Len(myPath) - InStrRev(myPath, "."))
On Error GoTo 0
'Determine Base File Name
If InStr(1, myFileName, VersionExt) > 1 Then
myArray = Split(myFileName, VersionExt)
SaveName = myArray(0)
Else
SaveName = myFileName
End If
'Test to see if file name already exists
If FileExist(FolderPath & SaveName & SaveExt) = False Then
ActiveWorkbook.SaveAs FolderPath & SaveName & NewSaveExt, 52
Exit Sub
End If
'Need a new version made
Do While Saved = False
If FileExist(FolderPath & SaveName & VersionExt & x & SaveExt) = False Then
ActiveWorkbook.SaveAs FolderPath & SaveName & VersionExt & x & NewSaveExt, 52
Saved = True
Else
x = x + 1
End If
Loop
'New version saved
MsgBox "New file version saved (version " & x & ")"
Exit Sub
'Error Handler
NotSavedYet:
MsgBox "This file has not been initially saved. " & _
"Cannot save a new version!", vbCritical, "Not Saved To Computer"
End Sub
Function FileExist(FilePath As String) As Boolean
'PURPOSE: Test to see if a file exists or not
'RESOURCE: http://www.rondebruin.nl/win/s9/win003.htm
Dim TestStr As String
'Test File Path (ie "S:\Reports\Financial Report as at...")
On Error Resume Next
TestStr = Dir(FilePath)
On Error GoTo 0
'Determine if File exists
If TestStr = "" Then
FileExist = False
Else
FileExist = True
End If
End Function

Error reproduction: I was able to reproduce the error when trying to save a workbook with a FileName that already exist.
This could happen because the code checks the existence of a file named with extension SaveExt (using Function FileExist) but then try to save it as a file named with extension NewSaveExt. If these extensions are not the same then it’s possible that the file named with extension NewSaveExt already exist raising the
Run-time error ‘1004’: Method ‘SaveAs’ of object ‘_Workbook’ failed.
However this alert:
A file ‘Financial Report as month .xlsm’ already exist in this
location. Do you want to replace it?.
Should have been displayed before the error 1004
Unfortunately I cannot test the code posted in Excel 2010, but I personally think this behavior is not exclusive of Excel 2013.
Solution: If the objective is to always save the file as xlsm (value of NewSaveExt) then the code should validate the existence of a filename with that extension.
Additional comments about the code posted:
It’s a best practice to declare all variables. These variables are not declared:
TestStr, FileFinancialYear, MonthNumber, myFileName, myArray
These lines are redundant as no need to initialize variables that have not been used as yet, so they are already holding their initialized value.
TestStr = ""; Saved = False; x = 0
Suggest to use constant instead of variables for these (see Variables & Constants)
NewSaveExt = ".xlsm"; VersionExt = "_v"
New workbooks are not detected as the error handler NotSavedYet which is supposed to be triggered when the ActiveWorkbook has not been saved before (i.e. a new workbook) never gets fired as none of the commands between the On Error statements generate an error when dealing with new workbooks (see On Error Statement). If the intention is not to save New Workbooks, as implied by the error handler NotSavedYet, then validate the Path of the ActiveWorkbook, it will be empty if the workbook has not has been saved before.
The FileFinancialYear and MonthNumber variables never get populated.
Suggest to use specific workbook properties for Path and Name instead of FullName (see Workbook Object (Excel))
About the piece referred as Determine Base File Name
a. Programming: There is no need for IF statement, just use the Split function and take the item 0. The Split function returns ”a single-element array containing the entireexpression” when the delimiter is not present in the expression” (i.e. VersionExt and myFileName respectively).
b. Practicality: This piece seems to be redundant, as it’s meant to extract from variable myFileName the filename excluding the version and extension, however there is no such information in the variable as it has been populate just few lines above as:
myFileName = "Financial Report " & FileFinancialYear & " as at month " & MonthNumber
Therefore SaveName is always equal to myFileName
The first version of the file is indexed as 0 instead of 1.
The new indexed version will not always be the last index number + 1. If any of the previous versions is deleted or moved out to another folder as this version is missing the code will assign the missing version index to the latest file saved (see Fig. 1, note that time of the version 3 is newer than versions 4 & 5). Correction of this point requires a more complex approach as such it is not included in the revised code below.
Requirements: Based on the above a revised code is written that complies with the following requirements:
The procedure resides in a standalone workbook.
Files are always saved as xlOpenXMLWorkbookMacroEnabled (Extension xlsm)
New workbooks will not be saved as new versions.
Variables FileFinancialYear and MonthNumber are hardcoded as there is no indication of how they get populated (change as required).
The first time a file is saved and it does not exist in the source folder the file will be saved without version number.
The index of the first version should be 1 (change to 0 if required).
Option Explicit
Sub Wbk_SaveNewVersion_Xlsm()
Const kExt As String = ".xlsm"
Const kVrs As String = "_v"
Dim WbkAct As Workbook
Dim iYear As Integer, bMnth As Byte, sWbkStd As String
Dim sWbkPthNme As String, bVrs As Byte
Rem Set Standard Workbook Name
iYear = 2015 'Update Financial Year as required
bMnth = 9 'Update Month as required
sWbkStd = "Financial Report " & iYear & " as at month " & Format(bMnth, "00")
Rem Validate Active Workbook
Set WbkAct = ActiveWorkbook
If WbkAct.Name = ThisWorkbook.Name Then GoTo HdeThs
If WbkAct.Path = Empty Then GoTo NewWbk
Rem Get Workbook Properties
sWbkPthNme = WbkAct.Path & "\" & sWbkStd
Rem Validate Base File Existance
If Not (Fil_FileExist(sWbkPthNme & kExt)) Then
WbkAct.SaveAs sWbkPthNme & kExt, xlOpenXMLWorkbookMacroEnabled
MsgBox "A new workbook has been created: " & _
vbLf & vbLf & Chr(34) & sWbkStd & kExt & Chr(34), _
vbApplicationModal + vbInformation, "Workbook - Save a New Version - Xlsm"
Exit Sub
End If
Rem Save a New Version
bVrs = 1
sWbkPthNme = sWbkPthNme & kVrs
Do
If Fil_FileExist(sWbkPthNme & bVrs & kExt) Then
bVrs = 1 + bVrs
Else
WbkAct.SaveAs sWbkPthNme & bVrs & kExt, xlOpenXMLWorkbookMacroEnabled
Exit Do
End If
Loop
MsgBox "Version """ & bVrs & """ of workbook: " & _
vbLf & vbLf & Chr(34) & sWbkStd & Chr(34) & " has been created.", _
vbApplicationModal + vbInformation, "Workbook - Save a New Version - Xlsm"
HdeThs:
Call Wbk_Hide(ThisWorkbook)
Exit Sub
NewWbk:
MsgBox "Active Workbook """ & WbkAct.Name & """ has not been saved as yet." & vbLf & _
"A new version cannot be saved!", _
vbApplicationModal + vbCritical, "Workbook - Save New Version - Xlsm"
End Sub
Private Function Fil_FileExist(sFullName As String) As Boolean
Dim sDir As String
Fil_FileExist = (Dir(sFullName) <> Empty)
End Function
Private Sub Wbk_Hide(Wbk As Workbook)
Dim Wnd As Window
For Each Wnd In Wbk.Windows
Wnd.Visible = False
Next
End Sub

Related

How do I add a network path to a name in excel name manager

I have code that works to add a path to a name in the name manager, but only for local paths. When I try to use a network path, the name manager adds a colon before the first single backslash, which keeps the path from working. I have added code to debug, to remove colons, which it seems wasn't necessary. The File open dialog does return the correct path. VBA writes it like this with debug.print:
`="\\win10box3\business\... ..." `
When excel stores it in the name manager it stores it like this
`="\\Win10Box3:\Business\... ..." `
I wrote code to remove the colon before adding the name, but I'm finding the path debug.prints correct before it is stored in the Name Manager, even before the loop to remove the colon.
The only solution I have found is to manually edit the path in the name manager to remove the colon
Sub GetPath()
Debug.Print "Start GetPath routine"
'This sub gets the path to a File defined by the user within the routine
'It then calls another sub that applies that path to a name in the worksheet.
' Before calling this routine, The name should first be searched for, and then verified, then opportunity given to change the name.
Dim MyPath As String 'String to hold the path to an excel spreadsheet exported from quickbooks
Dim NametoChange As String 'String that holds the name manager name to store the path under
Dim NameComment As String 'Comment to identify the name in the name manager
Dim PathLength As Long
Dim PathTemp As String
NametoChange = "PathToEmployeeWithholding"
NameComment = "This Name contains the Path to the 'Employee Withholding' worksheet exported from quickbooks using VBA"
MyMessage = "If you have not already exported and" & vbCrLf & "saved the employee withholding data from Quickbooks," & vbCrLf & "Please choose cancel and export it now"
DoIt = MsgBox(MyMessage, vbOKCancel)
Debug.Print DoIt
If DoIt = vbCancel Then
Exit Sub
End If
With Application.FileDialog(msoFileDialogFilePicker)
If .Show <> 0 Then
MyPath = .SelectedItems(1)
End If
End With
Debug.Print MyPath 'NOTE:This is producing the correct path. It has no colon here...
'Where is the colon coming from?
'IT SEEMS NECESSARY TO REMOVE A COLON IF THE PATH IS A NETWORK PATH
'FIRST VERIFY IT IS NOT A DRIVE PATH... SHOULD BE IN THE FORM OF D:\
'WHAT IS UNIQUE IS THE COLON IS THE 2ND CHARACTER IN THE PATH IF A LOCAL DRIVE.
'TEST TO SEE IF THE INCREMENT IS 2. IF IT IS, SKIP IT, AND REMOVE ALL OTHER COLONS
PathLength = Len(MyPath)
For i = 1 To PathLength
If Not i = 2 Then
If Not Mid(MyPath, i, 1) = ":" Then
PathTemp = PathTemp & Mid(MyPath, i, 1)
End If
Else
PathTemp = PathTemp & Mid(MyPath, i, 1)
End If
Debug.Print "i = " & i & " The current Character is " & _
Mid(MyPath, i, 1) & xlcrlf & "the current PathTemp is " & PathTemp
Next
MyPath = PathTemp
Debug.Print MyPath
Debug.Print "Calling ChangeValueOfName Routine"; vbCrLf & vbCrLf
Call ChangeValueOfName(NametoChange, MyPath, NameComment) 'this routine stores the retrieved text string in the name manager
Debug.Print "Exit GetPath Routine" & vbCrLf & vbCrLf
End Sub
Sub ChangeValueOfName(NametoChange As String, NewNameValue As String, Comment As String)
Debug.Print "Start changeValueOfName routine"
' ChangeValueOfNameManagerName Macro
' Changes the Value of a defined name in the Name Manager
'This should be used to change the name.
'Once the file is selected data needs to be imported to an array, and the
'Employee name values need to be checked against the worksheets in the workbook and against the recap sheet
'If changes are needed, it needs to write them into the workbook, including changing recap sheet and adding
'worksheets for any new employees
With ThisWorkbook.Names(NametoChange)
.Name = NametoChange
.Comment = Comment
RefersToR1C1 = _
"=" & Chr(34) & NewNameValue & Chr(34)
End With
Debug.Print "The New Path added is " & "=" & Chr(34) & NewNameValue & Chr(34)
Debug.Print "Return from ChangeValueOfName routine" & vbCrLf & vbCrLf
End Sub

Pulling file names from SharePoint and saving to SharePoint, using VBA

I'm trying to adapt an Excel form I created that uses drive locations to save copies of the form, to work with SharePoint in a similar manner. Currently, the first macro is set up such that it will search the contents of a particular folder to determine the next available number in the queue (i.e. if 1, 2 and 4 already exist, it will assign 3) and save the sheet as that next available number. When the sheet is complete, the second macro will save the file with a specified name based on data within the sheet, in another specified location (again based on data defined within the sheet). The drive is in the process of being retired in our company and everything moved to Cloud-based storage, so I would like a way to complete the same actions but using SharePoint directories.
The code for the first macro is as follows:
Dim strDir As String
Dim file As Variant
Dim savename As Integer
Dim savename_string As String
strDir = "R:\Queue\"
savename = 1
savename_string = CStr(savename)
file = Dir(strDir)
While (CInt(savename_string) = savename)
If file <> (savename & ".xlsm") Then
If file = "" Then
savename = savename + 1
Else
file = Dir
End If
ElseIf file = (savename & ".xlsm") Then
savename = savename + 1
savename_string = CStr(savename)
file = Dir(strDir)
End If
Wend
ActiveWorkbook.SaveAs ("R:\Queue\" & savename_string & ".xlsm")
And then the code for the second macro is as follows:
Dim answer As Integer
Dim error As Integer
Dim delete As String
answer = MsgBox("Are you sure you want to save sheet & close?", vbYesNo + vbQuestion, "WARNING")
If answer = vbYes Then
'Define PWO, assembly, terminal, strand, and gauge As Strings, and define which cells they are on the sheet
delete = ActiveWorkbook.Name
ActiveWorkbook.SaveAs ("R:\" & terminal & assembly & Space(1) & gauge & strand & Space(1) & PWO & Space(1) & Format(Now(), "MM-DD-YYYY") & ".xlsm")
Kill ("R:\Queue\" & delete)
ActiveWorkbook.Close
Else
Exit Sub
End If
Currently the second macro works correctly when replacing the locations with the SharePoint URL locations, but when doing the same with the first macro, it returns an error message "Bad file name or number" at the line file = Dir(strDir). Can I get this code in working order, or is there a better way I should go about this? Thanks!

VBA: SaveCopyAs Method Outputting Cannot Find File Error

I'm modifying a Gantt chart excel template I found online by Vertex42 for added functionality.
One of these modifications is a checkbox inside a sheet called "Config" that, when ticked, creates a backup of the Gantt chart whenever the document is opened.
For some reason, I cannot get this simple task to work.
I've tried using both the Form control and ActiveX control check boxes, with different error messages. As far as I can tell, the Form controls are unrecommended, so I'm using the code below in the ThisWorkbook excel object, based on what I've seen online.
Private Sub Workbook_open()
Dim backupFilename As String
Dim formattedDateTime As String
If Sheets("Config").OLEObjects("AutoBackupCheckbox").Object.Value = True Then
formattedDateTime = Format(Now, "d-MMMM-yyyy, h:mm:ss")
backupfilename = Replace(ActiveWorkbook.Name, ".xlsm", " - backup " & DateTime & ".xlsm")
ActiveWorkbook.SaveCopyAs (backupfilename)
End If
End Sub
This code is getting me the error message whenever I open the document or run the debugger,
Run-time error '1004':
Sorry, we couldn't find the <filename> - backup <day>-<month>-<year>, <hour>:<minute>:<seconds>.xlsm. Is it possible it was moved, renamed or deleted?
Any ideas?
UPDATE: After running the debugger, it's complaining on the ActiveWorkbook.SaveAs line.
UPDATE 2: Changed format of 'backupFilename' to remove the '.xlsm' in the middle.
UPDATE 3: Replaced Date with date/time without slashes, and replaced SaveAs with SaveCopyAs. Updated error message.
The argument for the SaveCopyAs call is missing the path of the file.
Replace code with
Private Sub Workbook_open()
Dim backupFilename As String
Dim formattedDate As String
Dim tempFilename As String
Dim workingPath As String
Dim i As Integer
i = 1
If Sheets("Config").OLEObjects("AutoBackupCheckbox").Object.Value = True Then
formattedDate = Format(Date, "d-MMMM-yyyy, ver " & i)
workingPath = Application.ActiveWorkbook.FullName
backupFilename = Replace(workingPath, ".xlsm", " - backup " & formattedDate & ".xlsm")
tempFilename = Dir(backupFilename)
While tempFilename <> "" ' if file already exists
i = i + 1
formattedDate = Format(Date, "d-MMMM-yyyy, ver " & i)
backupFilename = Replace(workingPath, ".xlsm", " - backup " & formattedDate & ".xlsm")
tempFilename = Dir(backupFilename)
Wend
ActiveWorkbook.SaveCopyAs (backupFilename)
End If
End Sub

Excel VBA Check if directory exists error

I have a spreadsheet that upon clicking a button will duplicate itself by copying/pasting everything to a new workbook and save the file with a name that is dependent upon some variable values (taken from cells on the spreadsheet).
My current goal is to get it to save the sheet in different folders depending on the name of client name (cell value held in variable), while this works on the first run, I get an error after.
The code checks if the directory exists and creates it if not.
This works, but after it is created, running it a second time throws the error:
Runtime Error 75 - path/file access error.
My code:
Sub Pastefile()
Dim client As String
Dim site As String
Dim screeningdate As Date
screeningdate = Range("b7").Value
Dim screeningdate_text As String
screeningdate_text = Format$(screeningdate, "yyyy\-mm\-dd")
client = Range("B3").Value
site = Range("B23").Value
Dim SrceFile
Dim DestFile
If Dir("C:\2013 Recieved Schedules" & "\" & client) = Empty Then
MkDir "C:\2013 Recieved Schedules" & "\" & client
End If
SrceFile = "C:\2013 Recieved Schedules\schedule template.xlsx"
DestFile = "C:\2013 Recieved Schedules\" & client & "\" & client & " " & site & " " & screeningdate_text & ".xlsx"
FileCopy SrceFile, DestFile
Range("A1:I37").Select
Selection.Copy
Workbooks.Open Filename:= _
"C:\2013 Recieved Schedules\" & client & "\" & client & " " & site & " " & screeningdate_text & ".xlsx", UpdateLinks:= _
0
Range("A1:I37").PasteSpecial Paste:=xlPasteValues
Range("C6").Select
Application.CutCopyMode = False
ActiveWorkbook.Save
ActiveWindow.Close
End Sub
You'll have to excuse my lack of knowledge in this area, I am still learning.
I have a very strong feeling it has something to do with the directory checking logic, as when the error is thrown the MkDir line is highlighted.
To check for the existence of a directory using Dir, you need to specify vbDirectory as the second argument, as in something like:
If Dir("C:\2013 Recieved Schedules" & "\" & client, vbDirectory) = "" Then
Note that, with vbDirectory, Dir will return a non-empty string if the specified path already exists as a directory or as a file (provided the file doesn't have any of the read-only, hidden, or system attributes). You could use GetAttr to be certain it's a directory and not a file.
Use the FolderExists method of the Scripting object.
Public Function dirExists(s_directory As String) As Boolean
Dim oFSO As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
dirExists = oFSO.FolderExists(s_directory)
End Function
To be certain that a folder exists (and not a file) I use this function:
Public Function FolderExists(strFolderPath As String) As Boolean
On Error Resume Next
FolderExists = ((GetAttr(strFolderPath) And vbDirectory) = vbDirectory)
On Error GoTo 0
End Function
It works both, with \ at the end and without.
I ended up using:
Function DirectoryExists(Directory As String) As Boolean
DirectoryExists = False
If Len(Dir(Directory, vbDirectory)) > 0 Then
If (GetAttr(Directory) And vbDirectory) = vbDirectory Then
DirectoryExists = True
End If
End If
End Function
which is a mix of #Brian and #ZygD answers. Where I think #Brian's answer is not enough and don't like the On Error Resume Next used in #ZygD's answer
If Len(Dir(ThisWorkbook.Path & "\YOUR_DIRECTORY", vbDirectory)) = 0 Then
MkDir ThisWorkbook.Path & "\YOUR_DIRECTORY"
End If
This is the cleanest way... BY FAR:
Public Function IsDir(s) As Boolean
IsDir = CreateObject("Scripting.FileSystemObject").FolderExists(s)
End Function
You can replace WB_parentfolder with something like "C:\". For me WB_parentfolder is grabbing the location of the current workbook.
file_des_folder is the new folder i want. This goes through and creates as many folders as you need.
folder1 = Left(file_des_folder, InStr(Len(WB_parentfolder) + 1, file_loc, "\"))
Do While folder1 <> file_des_folder
folder1 = Left(file_des_folder, InStr(Len(folder1) + 1, file_loc, "\"))
If Dir(file_des_folder, vbDirectory) = "" Then 'create folder if there is not one
MkDir folder1
End If
Loop

Writing text from Excel 2007 to a .txt file on a Sharepoint Site causes Run-Time error'76' Path not found

I have this VBA sub in an Excel 2007 project. It records user name, report name, date, and version on a .txt file in a Sharepoint site. Some of my users are getting a Run-Time error'76' Path not found issue.
Here's my code:
Sub logReport(ReportName As String)
Call AppendTxt("//myaviall/teamsites/AviallReportingSolutions/Airplane_Usage_Log/Airplane_ACT.txt", UNameWindows & ";" & ReportName & ";" & Now & ";" & VersionNum)
Dim oFS, TS, FileObj
'Get text stream
'Set oFS = CreateObject("Scripting.FileSystemObject")
'Set FileObj = oFS.GetFile("//myaviall/teamsites/AviallReportingSolutions/Airplane_Usage_Log/Airplane_ACT.txt")
'Set TS = FileObj.OpenAsTextStream(8, -2) 'ForWriting, TristateUseDefault)
' Write to file
'TS.WriteLine UNameWindows & ";" & ReportName & ";" & Now & ";" & VersionNum
'TS.Close
'Set TS = Nothing
'Set FileObj = Nothing
'Set oFS = Nothing
End Sub
Function AppendTxt(sFile As String, sText As String)
On Error GoTo Err_Handler
Dim FileNumber As Integer
FileNumber = FreeFile ' Get unused file number
Open sFile For Append As #FileNumber ' Connect to the file
Print #FileNumber, sText ' Append our string
Close #FileNumber ' Close the file
Exit_Err_Handler:
Exit Function
Err_Handler:
MsgBox "The following error has occured" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: AppendTxt" & vbCrLf & _
"Error Description: " & Err.Description, vbCritical, "An Error has Occured!"
GoTo Exit_Err_Handler
End Function
If there is only one user that is getting the issue the first thing that I would look at it access, as Scott points out.
I run a very similar procedure which writes a line to a csv file from outlook based on the code here
http://www.devhut.net/2011/06/06/vba-append-text-to-a-text-file/
This is probably not your answer but if the access is ok then it couldnt hurt to try another method.
Update
I also include this into my code to test if the file exists
exists = Dir$(sFile) <> fileName
Where fileName = "Airplane_ACT.txt" But I would maybe try this with a msgBox to see what it returns.
Also try try changing your string to Airplane_ACT_test.txt and run the code, this should create a new txt file, if this is the case then the issue may be related to your initial txt file.
Last thing: try with a different path eg: to the user's desktop.

Resources