Rename opened workbook with incremental number without firstly closing it? - excel

Regarding this question link to rename opened workbook without firstly close it.
The provided answer works greatly ,But I faced cases if new name equal to old name or there is a file with same new name on same folder path.
I modified the code a bit ( as new name will be picked up without user intervention) and added function to check if a file with new name exists or not before rename.
I could not manage to add the incremental number ( added “New” instead).
Now, the code works properly only on first run:
e.g. file name Plan 12-Mar changed to Plan 12-Mar New and Plan 12-Mar deleted , then I closed it.
On second run on the renamed file (Plan 12-Mar New) I got the following message:
file named 'C:\Users\Waleed\Desktop\Plan 12-Mar New.xlsb' already exists in this location. Do you want to replace it?
If I clicked on Yes button , I got this Run-time error '70': Permission denied on this line of code Kill FilePath
Conclusion if I used the code today , if initial name is “Plan 12-Mar” ,then expected actions are (1) save as with rename to “Plan 12-Mar v2” (2) delete the old file “Plan 12-Mar”
and if also I used again today, then expected actions are (1) save as with rename to “Plan 12-Mar v3” (2) delete the old file “Plan 12-Mar v2”.
If I used the code tomorrow, then expected actions are (1) save as with rename to “Plan 13-Mar” (2) delete the old file “Plan 12-Mar v3” , and so on.
Appreciate for yours comments and answers.
Option Explicit
Option Compare Text
Sub Rename_Me()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim DotPosition As Long: DotPosition = InStr(1, wb.Name, ".")
If DotPosition = 0 Then Exit Sub
Dim ibDefault As String: ibDefault = Left(wb.Name, DotPosition - 1)
Dim NewBaseName As String
NewBaseName = "Plan " & Format(Date, "DD-MMM")
If Len(NewBaseName) = 0 Then Exit Sub
Dim FilePath As String: FilePath = wb.FullName
Dim FolderPath As String: FolderPath = wb.path & Application.PathSeparator
Dim Extension As String: Extension = Right(Extension, DotPosition)
Dim ErrNum As Long
On Error Resume Next
If Not Is_File_Exists(wb.FullName) Then
wb.SaveAs FolderPath & NewBaseName & Extension
ErrNum = Err.Number
Else
wb.SaveAs FolderPath & NewBaseName & " New" & Extension 'Instead of "New" ,I v2 ,v3,...
ErrNum = Err.Number
End If
On Error GoTo 0
If ErrNum = 0 Then
Kill FilePath
Else
Kill FilePath
MsgBox "Could not rename.", vbCritical, "Rename Me"
End If
End Sub
And this the function
Function Is_File_Exists(ByVal fName As String) As Boolean
'Returns TRUE if the provided name points to an existing file,
'FALSE if not existing or it's a folder
On Error Resume Next
Is_File_Exists = ((GetAttr(fName) And vbDirectory) <> vbDirectory)
End Function

To allocate a new name, based on the algorithm you try explaining, please use the next function:
Function NewName(strExisting As String) As String
Dim boolToday As Boolean, arrSuffix, arrName, nrSuffix As Long
arrName = Split(strExisting, "."): strExisting = arrName(0)
'check if the root name refers to today date:
If InStr(strExisting, "Plan " & Format(Date, "DD-MMM")) > 0 Then boolToday = True
If boolToday Then
If IsNumeric(Right(strExisting, 1)) Then
arrSuffix = Split(strExisting, " V"): nrSuffix = CLng(arrSuffix(1)) + 1
NewName = arrSuffix(0) & " V" & nrSuffix & "." & arrName(1): Exit Function
Else
NewName = strExisting & " V1." & arrName(1): Exit Function
End If
Else
NewName = "Plan " & Format(Date, "DD-MMM") & "." & arrName(1): Exit Function
End If
End Function
It will add a suffix incrementing the existing number after "V", in case of the name containing current day reference and a new name containing the current date, if a previous one. Then you can delete the workbook with the name sent to the function. It can be tested using the next sub:
Sub testNewName()
Static name As String
If name = "" Then name = "Plan 11-Mar.xlsb"
name = NewName(name): Debug.Print name
End Sub
Run the sub form some times and see the result in Immediate Window.
If, from unknow reasons, a full name identic to the built one can exist, the full name can be checked for its existence and send a message about that before saving As.

Related

VBA not finding the excel file even when file is present in the folder

I am opening the excel file in VBA using
Set Workbook = Application.Workbooks.Open(File)
Where
File = "C:\GSTR Automation\GSTR2\February\1000\ReverseCharge\Outputs\ReverseChargeZonic_1000.xlsx"
I am getting the vba error that it could'nt find the file.
But file is present there , I have verified the path manually – karan arora 33 mins ago
I have copied the file location and name from the file still getting the same error – karan arora 30 mins ago
This is not an answer but may help you identify where could be the problem in such a scenario.
Logic:
This code (not fully tested) will take a path and folder by folder will check if it exists. I created the same structure in my C: so that you can see how it works
Code:
Option Explicit
Sub Sample()
Dim sFile As String
Dim Ar As Variant
Dim i As Long
Dim DoesFileExist As Boolean
sFile = "C:\GSTR Automation\GSTR2\February\1000\ReverseCharge\Outputs\ReverseChargeZonic_1000.xlsx"
Ar = Split(sFile, "\")
If UBound(Ar) = 1 Then
MsgBox "File Exists: " & FileFolderExists(sFile)
Else
sFile = Ar(0)
For i = 1 To UBound(Ar)
sFile = sFile & "\" & Ar(i)
DoesFileExist = FileFolderExists(sFile)
If DoesFileExist = False Then
MsgBox sFile & " not found"
Exit Sub
Else
MsgBox sFile & " found"
End If
Next i
End If
End Sub
'~~> Function to check if file/folder exists
Private Function FileFolderExists(strFullPath As String) As Boolean
On Error GoTo Whoa
If Not Dir(strFullPath, vbDirectory) = vbNullString Then FileFolderExists = True
Whoa:
On Error GoTo 0
End Function
In Action:
Now I changed February to January in the above path
Now see how the above code responds

Protecting Excel worksheets - Impossible?

I'm trying to share an Excel workbook, but with limited access to only a couple of visible sheets. This have proven to be much harder than first anticipated due to security loopholes with Excel and password protection of worksheets.
My problem arises due to some hidden sheets that needs to stay hidden and the contents inaccessible, but are required for calculations were the result is shown in the visible sheets.
So far I have tried to "super hide" the sheets in the VBA window and lock the VBA project. The idea is that the user then can't unhide the "super hidden" sheets without the VBA project password.
I have tried to add additional VBA code to counter certain "attacks", but I keep coming back to a known flaw that circumvents all my efforts:
Step 1:
Save or make sure that the Excel workbook is saved as .xlsx or .xlsm
Step 2:
Run the following code from a different workbook or your personal.xlsb that removes passwords from sheets and structure protection
(I would have linked to the post where I found the code, but I can't find it right now...).
Sub RemoveProtection()
Dim dialogBox As FileDialog
Dim sourceFullName As String
Dim sourceFilePath As String
Dim SourceFileName As String
Dim sourceFileType As String
Dim newFileName As Variant
Dim tempFileName As String
Dim zipFilePath As Variant
Dim oApp As Object
Dim FSO As Object
Dim xmlSheetFile As String
Dim xmlFile As Integer
Dim xmlFileContent As String
Dim xmlStartProtectionCode As Double
Dim xmlEndProtectionCode As Double
Dim xmlProtectionString As String
'Open dialog box to select a file
Set dialogBox = Application.FileDialog(msoFileDialogFilePicker)
dialogBox.AllowMultiSelect = False
dialogBox.Title = "Select file to remove protection from"
If dialogBox.show = -1 Then
sourceFullName = dialogBox.SelectedItems(1)
Else
Exit Sub
End If
'Get folder path, file type and file name from the sourceFullName
sourceFilePath = Left(sourceFullName, InStrRev(sourceFullName, "\"))
sourceFileType = Mid(sourceFullName, InStrRev(sourceFullName, ".") + 1)
SourceFileName = Mid(sourceFullName, Len(sourceFilePath) + 1)
SourceFileName = Left(SourceFileName, InStrRev(SourceFileName, ".") - 1)
'Use the date and time to create a unique file name
tempFileName = "Temp" & Format(Now, " dd-mmm-yy h-mm-ss")
'Copy and rename original file to a zip file with a unique name
newFileName = sourceFilePath & tempFileName & ".zip"
On Error Resume Next
FileCopy sourceFullName, newFileName
If Err.Number <> 0 Then
MsgBox "Unable to copy " & sourceFullName & vbNewLine _
& "Check the file is closed and try again"
Exit Sub
End If
On Error GoTo 0
'Create folder to unzip to
zipFilePath = sourceFilePath & tempFileName & "\"
MkDir zipFilePath
'Extract the files into the newly created folder
Set oApp = CreateObject("Shell.Application")
oApp.Namespace(zipFilePath).CopyHere oApp.Namespace(newFileName).Items
'loop through each file in the \xl\worksheets folder of the unzipped file
xmlSheetFile = Dir(zipFilePath & "\xl\worksheets\*.xml*")
Do While xmlSheetFile <> ""
'Read text of the file to a variable
xmlFile = FreeFile
Open zipFilePath & "xl\worksheets\" & xmlSheetFile For Input As xmlFile
xmlFileContent = Input(LOF(xmlFile), xmlFile)
Close xmlFile
'Manipulate the text in the file
xmlStartProtectionCode = 0
xmlStartProtectionCode = InStr(1, xmlFileContent, "<sheetProtection")
If xmlStartProtectionCode > 0 Then
xmlEndProtectionCode = InStr(xmlStartProtectionCode, _
xmlFileContent, "/>") + 2 '"/>" is 2 characters long
xmlProtectionString = Mid(xmlFileContent, xmlStartProtectionCode, _
xmlEndProtectionCode - xmlStartProtectionCode)
xmlFileContent = Replace(xmlFileContent, xmlProtectionString, "")
End If
'Output the text of the variable to the file
xmlFile = FreeFile
Open zipFilePath & "xl\worksheets\" & xmlSheetFile For Output As xmlFile
Print #xmlFile, xmlFileContent
Close xmlFile
'Loop to next xmlFile in directory
xmlSheetFile = Dir
Loop
'Read text of the xl\workbook.xml file to a variable
xmlFile = FreeFile
Open zipFilePath & "xl\workbook.xml" For Input As xmlFile
xmlFileContent = Input(LOF(xmlFile), xmlFile)
Close xmlFile
'Manipulate the text in the file to remove the workbook protection
xmlStartProtectionCode = 0
xmlStartProtectionCode = InStr(1, xmlFileContent, "<workbookProtection")
If xmlStartProtectionCode > 0 Then
xmlEndProtectionCode = InStr(xmlStartProtectionCode, _
xmlFileContent, "/>") + 2 ''"/>" is 2 characters long
xmlProtectionString = Mid(xmlFileContent, xmlStartProtectionCode, _
xmlEndProtectionCode - xmlStartProtectionCode)
xmlFileContent = Replace(xmlFileContent, xmlProtectionString, "")
End If
'Manipulate the text in the file to remove the modify password
xmlStartProtectionCode = 0
xmlStartProtectionCode = InStr(1, xmlFileContent, "<fileSharing")
If xmlStartProtectionCode > 0 Then
xmlEndProtectionCode = InStr(xmlStartProtectionCode, xmlFileContent, _
"/>") + 2 ''"/>" is 2 characters long
xmlProtectionString = Mid(xmlFileContent, xmlStartProtectionCode, _
xmlEndProtectionCode - xmlStartProtectionCode)
xmlFileContent = Replace(xmlFileContent, xmlProtectionString, "")
End If
'Output the text of the variable to the file
xmlFile = FreeFile
Open zipFilePath & "xl\workbook.xml" & xmlSheetFile For Output As xmlFile
Print #xmlFile, xmlFileContent
Close xmlFile
'Create empty Zip File
Open sourceFilePath & tempFileName & ".zip" For Output As #1
Print #1, Chr$(80) & Chr$(75) & Chr$(5) & Chr$(6) & String(18, 0)
Close #1
'Move files into the zip file
oApp.Namespace(sourceFilePath & tempFileName & ".zip").CopyHere _
oApp.Namespace(zipFilePath).Items
'Keep script waiting until Compressing is done
On Error Resume Next
Do Until oApp.Namespace(sourceFilePath & tempFileName & ".zip").Items.count = _
oApp.Namespace(zipFilePath).Items.count
Application.Wait (Now + TimeValue("0:00:01"))
Loop
On Error GoTo 0
'Delete the files & folders created during the sub
Set FSO = CreateObject("scripting.filesystemobject")
FSO.deletefolder sourceFilePath & tempFileName
'Rename the final file back to an xlsx file
Name sourceFilePath & tempFileName & ".zip" As sourceFilePath & SourceFileName _
& "_" & Format(Now, "dd-mmm-yy h-mm-ss") & "." & sourceFileType
'Show message box
MsgBox "The workbook and worksheet protection passwords have been removed.", _
vbInformation + vbOKOnly, Title:="Password protection"
End Sub
Step 3:
Run the following code to unhide all sheets
Sub UnhideAllSheets()
For Each Worksheet In ActiveWorkbook.Sheets
Worksheet.Visible = -1
Next Worksheet
End Sub
The workbook is now clean of passwords on sheets and structure protection, and any "counter" VBA code is gone by saving the workbook as a .xlsx file.
I have thought about adding a user-defined function that checks if the extension of the workbook file is ".xlsb". The function would return "1" if the extension is ".xlsb" and then multiplying it on something important. This would cause the calculations to fail if the workbook is saved as something else, or if the VBA project is entirely removed to saving as .xlsx.
However, I do not like this approach as I don't think it is a long-term solution...
My question is therefore:
Is there a way to securely share an Excel workbook with only access to a couple of sheets without risking the user can access hidden sheets and/or unwanted contents?
In the VBE you can change the Visible property of a specific sheet to xlSheetVeryHidden.
This will remove it from the front end completely.
You can then add a password to protect the VBA project in the VBE to prevent a user from changing that property (if they even know about it).
Additionally, you will still be able to access these sheets with your VBA code.
EDIT:
What I also add to the above is a password to the specific sheet, as normal. But also a custom UserForm the UserForm gets triggered on the Worksheet_Activate event if they had to unhide it. If they enter the incorrect password or close the UserForm the sheet gets hidden away again. You can add all sorts to this event handler such as reprotect the worksheet, reprotect the project, protect the workbook with an encrypted password and close the workbook as a "breach" in security.
The possibilities are endless. Not an exact prevention, but hopefully this helps.

Saveas function excel. with name from cell

I am trying to make the following code work for saving a file name in a certain format. I would like it to save in the folder the file was opened up in. the file would change it's name to a new month name. I have got most of it working, such as directory selection and filename and for it to save, however, if there is already a file with the same name or if someone selects no or cancel it gives an error. I have tried various ways of trying to get around it but now I'm at a loss. I have 2 codes they both are supposed to do the same thing, just variations.
Sub saving1()
' Saves the file under a new name based on the new month date.
Dim NewFilename As String
Dim tempnm
Dim loc ' variable for file location
loc = Application.ThisWorkbook.Path 'loads the file location on the loc variable
MsgBox loc
' creates the file name for saving includes the current path.
NewFilename = loc + "\" + Range("NewFileName").Value & ".xlsm"
'tempmm = Application.GetSaveAsFilename initialfilename
ActiveWorkbook.SaveAs NewFilename, FileFormat:=52
'Application.DisplayAlert = False
'On Error Resume Next 'to omit error when cancel is pressed
' MsgBox "Not saved"
'ActiveWorkbook.Save
'If Err.Number <> 1004 Then 'optional, to confirmed that is not saved
' MsgBox "Not saved"
'End If
' On Error GoTo 0 'to return standard error operation
End Sub
Sub saving()
' Saves the file under a new name based on the new month date.
Dim NewFilename As String
Dim loc ' variable for file location
loc = Application.ThisWorkbook.Path 'loads the file location on the loc variable
' creates the file name for saving includes the current path.
NewFilename = loc + "\" + Range("NewFileName").Value & ".xlsm"
ActiveWorkbook.SaveAs NewFilename, FileFormat:=52
End Sub
I also added message boxes to try see what it is doing during testing. I have also tried the Getsaveasfilename in order to give the user an option to choose his/her own filename and possibly folder. The file location will change once a year.
If Your are looking at overwriting existing file, when there's already a file with same name try below.
NewFilename = loc + "\" + Range("NewFileName").Value & ".xlsm"
Application.DisplayAlerts = False
ActiveWorkbook.SaveAs NewFilename, FileFormat:=52
Application.DisplayAlerts = True

Save numbered versions of excel files based on folder contents

I need code that saves incrementally numbered versions of a file based on whether similarly named files already exist in a specified folder.
For example,
Check for the prescence of currently open file, say named
"Inv_Dec_2015.xlsx" in a folder named "Reports".
If file exists, check for "Inv_Dec_2015_v1.xlsx" in "Reports".
If file exists, check for "Inv_Dec_2015_v2.xlsx" in "Reports".
If file exists, check for "Inv_Dec_2015_v3.xlsx" in "Reports".
If file does NOT exist, Save currently open file as "Inv_Dec_2015_v3.xlsx"
and so on till any number of versions......
I found the following two pieces of code on Ron de Bruin's website that can be used for something like this and modified it a bit to my purpose, but I don't know how use it to check for pre-existing files.
Would deeply appreciate any help with this.
Sub Rename_Store_Wbk()
Dim sPath As String
' Enter the path at which file is to be stored
sPath = ActiveSheet.Range("K1").Value & ActiveSheet.Range("K2").Value & ".xlsx"
' Check whether the file already exists by calling the FileExist function
If FileExist(sPath) = False Then
ActiveWorkbook.SaveAs Filename:=sPath, _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
End If
End Sub
Function FileExist(FilePath As String) As Boolean
Dim TestStr As String
'Test File Path (ie "C:\Users\Chris\Reports\Inv_Dec_2015.xlsm")
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
See if the loop I added in here works for you:
Sub Rename_Store_Wbk()
Dim sPath As String
' Enter the path at which file is to be stored
sPath = ActiveSheet.Range("K1").Value & ActiveSheet.Range("K2").Value & ".xlsx"
If Not FileExists(sPath) Then
i = 1
Do
sPath = Left(sPath, Len(sPath) - 5) & "_v" & i & ".xlsx"
i = i + 1
Loop Until FileExists(sPath)
End If
ActiveWorkbook.SaveAs Filename:=sPath, _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
End Sub

ActiveWorkbook.SaveAs excel 2013 1004 error

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

Resources