I'm trying to have Excel save a file with a unique name whenever it's saved.
This will mostly be used within Excel 2003, but must also work on 2010.
The idea is that the user opens a template file and if they click 'Save' or just close the workbook it will save as template_1, template_2, etc.
This works fine if they click 'Save', but if they close the file it will ask if you want to save changes on the original file, saves it under the new name and then ask if the user wants to save changes... and then saves and asks if the user wants to save changes, and so on. Obviously, I only want it to save the once and then close - but it doesn't.
I've tried setting the Saved
property to TRUE. I've tried Cancel = True
after the save but this causes Excel to crash with a Excel has encountered a problem and really needs to screw your day up type message.
In the code below I've tried removing the Saved=TRUE
and the Cancel=TRUE
, I've tried moving them around - Cancel before the Save, Cancel after the Save but within the If...End If
block, before and after the EnableEvents
code:
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Dim NewFileName As String
On Error GoTo ERROR_HANDLER
NewFileName = GenerateUniqueName(ThisWorkbook.FullName)
If NewFileName <> "" Then
Application.EnableEvents = False
ThisWorkbook.SaveAs NewFileName, ThisWorkbook.FileFormat
ThisWorkbook.Saved = True
Application.EnableEvents = True
End If
FastExit:
Cancel = True
On Error GoTo 0
Exit Sub
ERROR_HANDLER:
MsgBox "Error " & Err.Number & vbCr & _
" (" & Err.Description & ") in procedure ThisWorkbook.Workbook_BeforeSave." & vbCr & vbCr & _
"DOCUMENT NOT SAVED.", vbCritical + vbOKOnly
Application.EnableEvents = True
Resume FastExit
End Sub
The GenerateUniqueName
code is below - this assumes the file name doesn't contain an underscore character and appends the number to the file name as _1, _2, etc:
'----------------------------------------------------------------------
' GenerateUniqueName
'
' Generates a file name that doesn't exist by appending a number
' inbetween the base name and the extension.
' Example: GenerateUniqueName("c:\folder\file.ext") = "c:\folder\file_4.ext"
'----------------------------------------------------------------------
Function GenerateUniqueName(FullFileName As String, Optional fAlwaysAddNumber As Boolean) As String
Dim oFSO As Object
Set oFSO = CreateObject("Scripting.FileSystemObject")
If Not oFSO.FileExists(FullFileName) And Not fAlwaysAddNumber Then
GenerateUniqueName = FullFileName
Else
Dim strExt As String
Dim strNonExt As String
Dim strBaseName As String
Dim strNewName As String
Dim i As Integer
strExt = oFSO.GetExtensionName(FullFileName)
If strExt <> "" Then
strBaseName = oFSO.GetBaseName(FullFileName)
If InStrRev(strBaseName, "_") > 0 Then
i = Val(Mid(strBaseName, InStrRev(strBaseName, "_") + 1, Len(strBaseName)))
strBaseName = Left(strBaseName, InStrRev(strBaseName, "_") - 1)
End If
strNonExt = oFSO.buildpath(oFSO.GetParentFolderName(FullFileName), strBaseName)
Do
i = i + 1
strNewName = strNonExt & "_" & i & "." & strExt
Loop While oFSO.FileExists(strNewName)
GenerateUniqueName = strNewName
Else
MsgBox "File name must contain a file extension." & vbCr & _
"e.g. .xls or .xlsx", vbCritical + vbOKOnly
GenerateUniqueName = ""
End If
End If
Set oFSO = Nothing
End Function
I've updated my
BeforeSave
code slightly - I'm still not sure ifThisWorkbook.Saved = True : Cancel = True
is correct, but I do know it crashes if I don't put in theCancel = True
:This will Save the file with a new name, but not close it.
As Absinthe and Mr.Burns said - look at the close event.
This looks to see if the workbook has been saved. If it hasn't then the close event is cancelled, the workbook is saved and then it's closed otherwise it will just close without saving.
Can anyone spot any pitfalls here?
Edit: I've found one pitfall - you can't use
Save As
.Please try this and see if your problems are solved? I have not included your function below as that remains unchanged.