Excel Macro saving file to the wrong directory - excel

I have looked at quite a lot of similar questions, but none of them seem to work for my specific issue.
I have a macro that saves my file with a new name if it encounters a file with the same name.
What keeps happening is that it saves the original file to the correct folder, but then when it encounters the file name the next time I save it, the instanced file gets saved to the same folder as the template rather than the folder that they should go to.
In the example below, my template file is saved in the "M:\Excel\" directory.
It saves the first "TEST" file into the "M:\Excel\SavedVersions\" directory since the file name doesn't exist yet.
Then when I run the macro again to have it automatically save an instanced version (ie - "TESTrev1"), it keeps saving the instanced versions to the "M:\Excel\" directory instead of saving it to the "SavedVersions" subfolder.
Not sure what needs to be changed or done differently to get the instanced versions to save to the correct folder.
Any help would be greatly appreciated!
Thanks in advance! :)
Sub TEST()
ActiveWorkbook.Save
ActiveWorkbook.SaveAs Filename:= _
GetNextAvailableName("M:\Excel\SavedVersions\TEST.xlsm")
End Sub
Function GetNextAvailableName(ByVal strPath As String) As String
With CreateObject("Scripting.FileSystemObject")
Dim strFolder As String, strBaseName As String, strExt As String, i As Long
strFolder = .GetParentFolderName("M:\Excel\SavedVersions\")
strBaseName = .GetBaseName("TEST")
strExt = .GetExtensionName(".xlsm")
Do While .FileExists(strPath)
i = i + 1
strPath = .BuildPath(strFolder, strBaseName & "rev" & i & "." & strExt)
Loop
End With
GetNextAvailableName = strPath
End Function

Your code was unnecessarily complex.
Try this simpler version.
Sub TEST()
ActiveWorkbook.Save
ActiveWorkbook.SaveAs fileName:= _
GetNextAvailableName("M:\Excel\SavedVersions\TEST.xlsm")
End Sub
Function GetNextAvailableName(ByVal strPath As String) As String
Dim i as Interger: i = 0
Do Until Len(Dir(strPath)) = 0
i = i + 1
strPath = "M:\Excel\SavedVersions\TESTrev" & i & ".xlsm"
Loop
GetNextAvailableName = strPath
End Function

Keep your code simple. If your path is constant then might as well define a variable for it so that it can be used whenever and whereever you want. This way if there is any change in the path, you have to make the change at only one place.
While saving the file, also specify the FileFormat parameter to avoid problems. You might want to read more about it HERE
Is this what you are trying?
Option Explicit
Const sPath As String = "M:\Excel\SavedVersions\"
Sub Sample()
Dim flName As String
flName = sPath & GetNextAvailableName()
ActiveWorkbook.Save
ActiveWorkbook.SaveAs Filename:=flName, _
FileFormat:=xlOpenXMLWorkbookMacroEnabled
End Sub
Function GetNextAvailableName() As String
Dim i As Integer: i = 1
Dim newFile As String
newFile = "TestRev" & i & ".xlsm"
Do Until Dir(sPath & newFile) = ""
i = i + 1
newFile = "TestRev" & i & ".xlsm"
Loop
GetNextAvailableName = newFile
End Function

Related

VBA opening a file with partial name

I am trying to open a file which will be updated periodically. The current name is "GDE Portfolio Characteristics 12.31.2021" and the idea is to instruct the code to open it, no matter the date (i.e. the last 10 characters). I should only have one file in the folder with such a partial name.
The code I use is the following:
Workbooks.Open Filename:=ThisWorkbook.Path & "\Parametric GDE Portfolio Characteristics*.xlsx"
When running it, it seems it does not find the file. It works if I instead use the entire name of the file.
Newbie problem, but scratching my head in frustration!
Many thanks
There is no way to use a wildcard in the Open-statement. However, you can use the
Dir-command to get the real file name as it allows wildcards:
Dim fileName As String
fileName = Dir(ThisWorkbook.Path & "\Parametric GDE Portfolio Characteristics*.xlsx")
If fileName <> "" Then
Workbooks.Open Filename:=ThisWorkbook.Path & "\" & fileName
End If
Here is a more generic approach:
Sub OpenFiles()
Dim Files As Collection
Set Files = ListFiles(ThisWorkbook.Path, "Parametric GDE Portfolio Characteristics*.xlsx")
Dim Filename As Variant
For Each Filename In Files
Workbooks.Open Filename:=Filename
Next
End Sub
Function ListFiles(FolderName As String, SearchString As String) As Collection
Set ListFiles = New Collection
Dim Filename As String
Filename = Dir(FolderName & "\" & SearchString)
If Len(Filename) = 0 Then Exit Function
Do While Filename <> ""
ListFiles.Add Filename
Filename = Dir()
Loop
End Function

How to make folder path universal?

New to VBA and have an assignment to create a sub that pastes from one workbook into a new workbook. A requirement for saving the file is that "the folder path be universal so other people can create this folder too". What amendment would I make to the ActiveWorkbook.SaveAs method to fulfill this? Thanks
Sub pasteTable()
Dim formatting As Variant 'create variable to hold formatting2 workbook path
formatting = Application.GetOpenFilename() 'user is prompted and selects path to formatting2 workbook and assigns to formatting variable
Workbooks.Open formatting 'formatting2 workbook is now active
Worksheets("Formatting").Range("B3:R13").Copy 'copies table from formatting2 workbook
Workbooks.Add 'add new workbook
Worksheets(1).Range("B3:R13").Select 'selects range on worksheet of new workbook to paste table
Selection.PasteSpecial xlPasteAll 'pastes table
Columns("B:R").ColumnWidth = 20 'ensures table has proper row and column heights/widths
Rows("3:13").RowHeight = 25
Worksheets(1).Name = "Table Data" 'renames worksheet
ActiveWorkbook.SaveAs "C:\Users\name\Desktop\names Excel Assessment VBA\names Excel Assessment VBA " & Format(Date, "dd/mmm/yyyy"), FileFormat:=xlOpenXMLWorkbookMacroEnabled
'saves workbook according to desired specifications
End Sub
Change your Save line to this:
ActiveWorkbook.SaveAs "C:\Users\" & Environ("Username") & "\Desktop\Excel Assessment VBA\Excel Assessment VBA " & Format(Date, "dd-mmm-yyyy") & ".xlsm", FileFormat:=xlOpenXMLWorkbookMacroEnabled
The Username system variable will adjust depending on the Windows account that is in use. Just make sure each user has those folders existing on their desktop too, or you will get an error. I also removed names from the folder names as i assume you were trying to do something with the username there as well. You can adjust that to your needs.
Your Date format needed to change too as it was including illegal characters.
You also forgot to include a file extension, so I added that as well.
There is a lot going on with that line, including a lot of mistakes, so you are going to have to play with it a bit until you get exactly what you need. You may want to simplify it a bit until you get the hang of all those things.
I think you have to add some more checks
The script expects the name of the tool-path-folder as constant ToolFolder.
Plus a second constant ToolBaseFolder that could be set to the parent-path `ToolFolder, e.g. a network path. If the const is empty, users desktop will be used.
If this path does not yet exist it will be created.
Option Explicit
Private Const ToolBaseFolder As String = "" 'if ToolBaseFolder is an empty string desktop will be used instead
Private Const ToolFolder As String = "MyNameForToolFolder"
Public Sub testWbToToolFolder()
'this is just for testing
Dim wb As Workbook: Set wb = ActiveWorkbook
saveWbToToolFolder wb, "test.xlsx"
End Sub
Public Sub saveWbToToolFolder(wb As Workbook, filename As String)
'you don't need this sub - but have the same code line in your main routine
wb.SaveAs getToolFolder & filename
End Sub
Public Function getToolFolder() As String
'this returns the toolfolder e.g. C:\Users\xyz\Desktop\MyNameForToolFolder
Dim basepath As String
basepath = ToolBaseFolder & "\"
If existsFolder(basepath) = False Then
If LenB(ToolBaseFolder) > 0 Then
MsgBox ToolBaseFolder & " does not exist." & vbCrLf & _
"File will be saved to " & ToolFolder & " on desktop ", vbExclamation
End If
basepath = getDesktopFolderOfUser
End If
Dim fullpath As String
fullpath = basepath & ToolFolder & "\"
If existsFolder(fullpath) = False Then
makeFolder fullpath
End If
getToolFolder = fullpath
End Function
Private Function existsFolder(path As String) As Boolean
If Len(path) < 2 Then Exit Function 'can't be a valid folder
existsFolder = LenB(Dir(path, vbDirectory)) > 0
End Function
Private Function getDesktopFolderOfUser() As String
getDesktopFolderOfUser = CreateObject("WScript.Shell").SpecialFolders("Desktop") & "\"
End Function
Private Function makeFolder(path As String)
'https://stackoverflow.com/a/26934834/16578424 plus comment from rayzinnz
CreateObject("WScript.Shell").Run "cmd /c mkdir """ & path & """", 0, True
End Function

How do you open a pdf file with VBA code for a relative file path?

I am trying to find the command and correct coding to open a PDF file with a relative file path to the active excel file. The code below works fine as a link directly to the file. However, I just need this code snippet to find the PDF file that is sitting in the same file as the opened excel file and open accordingly.
Sub OpeningPDF()
'ThisWorkbook.FollowHyperlink "C:\Users\Michael\My Documents\totals\copy.pdf"
End Sub
I tried working with ThisWorkbook.path but nothing I tried with that worked or seemed to be outdate. Any help in this matter would be much appreciated.
I have found two solutions to this:
The first one is using the built-in Shell() function. This should automatically resolve the relative path (relative to the applications current working directory):
Public Sub StartExeWithArgument()
Dim strFilename As String
strFilename = "../folder/file.pdf"
Call Shell(strFilename, vbNormalFocus)
End Sub
The second one uses the Shell.Application COM Object and will basically do the same as the first one.
Sub runit()
Dim Shex As Object
Set Shex = CreateObject("Shell.Application")
tgtfile = "../folder/file.pdf"
Shex.Open (tgtfile)
End Sub
If you start with ThisWorkbook.Path and your relative-reference, then trim a layer off for every "..\" in the relative reference, you'll get the path.
Function RelativeToAbsolutePath(ByVal RelativePath As String) AS String
Dim TempStart AS String, TempEnd AS String
TempStart = ThisWorkbook.Path
TempEnd = RelativePath
If Left(TempEnd,1) = "\" Then TempEnd = Mid(TempEnd,1)
RelativeToAbsolutePath = ""
On Error GoTo FuncErr
While Left(TempEnd,3)="..\" AND InStrRev(TempStart,"\")>0
TempStart = Left(TempStart,InStrRev(TempStart,"\")-1) 'Remove 1 layer from Workbook path
TempEnd = Mid(TempEnd,4) 'Remove 1 instance of "..\"
Wend
RelativeToAbsolutePath = TempStart & "\" & TempEnd 'Stitch it all together
FuncErr: 'You may want a DIR(..) check to see if the file actually exists?
End Function
You can then open it with Shell

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

Open FileDialog using VBA

I download reports on a daily/weekly basis but when downloading the system auto generates the file name with a date at the end although the basic file name is the same. ie ANAPOS - 20141001. I'm using a simple open command (Workbooks.OpenText Filename:="C:\Users\903270\Documents\Excel\ANAPOS.txt") to do some other stuff but before doing so I need to rename the file to ANAPOS.txt before I can run it.
Is there any code that will allow my macro to search for ANAPOS with out all the other info at the end?
Any help appreciated.
Set filePath to where you want to search
Sub getANAPOS()
Dim Filter As String, filePath As String
filePath = "C:\Data\VBA\SO\"
Filter = "ANAPOS files (*.txt), filepath & ANAPOS*.txt"
ANAPOSSelectedFile = Application.GetOpenFilename(Filter)
End Sub
EDIT FOLLOWING CLARIFICATION BY OP
Sticking with the same theme, this should give you some scope to work with. It essentially 'automatically' renames the selected file in situ, unless it already exists. Acknowledgements to #Gary's Student for his neat ideas to parse the GetOpenFileName result, here.
Sub renameANAPOS()
Dim Filter As String, filePath As String, newName As String
'filter txt file names containing 'ANAPOS'
Filter = "ANAPOS files (*.txt), filepath & ANAPOS*.txt"
'the 'rename' name
newfName = "ANAPOS"
'navigate to original ANAPOS file and location details
ANAPOSSelectedFile = Application.GetOpenFilename(Filter)
'parse selected file details
fullArr = Split(ANAPOSSelectedFile, "\")
detArr = Split(fullArr(UBound(fullArr)), ".")
fullArr(UBound(fullArr)) = ""
fPath = Join(fullArr, "\")
fName = detArr(0)
fExt = detArr(1)
'rename file in not already exixts
If Len(Dir(fPath & newfName & "." & fExt)) > 0 Then
MsgBox newfName & "." & fExt & " already exists in this folder."
Exit Sub
Else
Name ANAPOSSelectedFile As fPath & newfName & "." & fExt
End If
End Sub

Resources