Word VBA Documents.Open deleting files in folder when falsely passing that folder's path instead of file path - vba

I encountered the following issue:
When accidentally passing a folder path to the Documents.Open function in VBA Word I get the runtime error 5174 as one would expect.
However all files with names that begin with an underscore get deleted in that moment from that folder.
To replicate:
Assume folder C:/Test/
In said folder have two files:
test.txt
_test.txt
In Word VBA execute the command:
Documents.Open("C:/Test/")
(As part of a subroutine or in the immediate window.)
Result: Runtime Error 5174 and _test.txt is now missing.
Note: Passing a nonexisting file like "C:/Test/abc.txt" or a wrong folder path like "C:/Test" (without the last slash) will not have this effect and won't cause the runtime error.
I have only tested this on one system on a network drive under windows 10 with Microsoft Professional Plus 2019. It's entirely possible that it's an issue with the file system. Does anyone have any suggestions as to why is this happening? I now included the workaround to check if I'm passing a folder, but it's still unnerving.

The Documents.Open method opens the specified document and adds it to the Documents collection. It is designed to take the file path, not a folder. If you want to allow users to pick file(s) you may consider using the file open dialog. The FileOpenDialog triggered by your code which opens a folder for picking files allows specifying file formats that should be supported and visible via the dialog window.
Set dlgSaveAs = Application.FileDialog(msoFileDialogFilePicker)
dlgSaveAs.Filter = "Text Files (.txt)|*.txt|Word Documents (.docx)|*.docx|Word Template (.dotx)|*.dotx|All Files (*.*)|*.*"
dlgSaveAs.ValidateNames = true
Res = dlgSaveAs.Show

Related

How to check for any files with FileExists(String) method

I'm trying to automate a document handling process, and I need to check if there are any files inside a certain folder. The process itself removes the files from the folder once it finishes, so I need it to loop back and check if there are any files left.
So far I've been using a sample file like this:
File.Exists("C:\Users\gcaor\Desktop\OC\150.pdf")
150.pdf is the sample file it's searching for, but is there a way to search for any file at all? So that it returns true if there is a file in the folder and false if there isn't
You can use Directory.EnumerateFiles + Any:
Dim anyFileExist = Directory.EnumerateFiles(path).Any()
This is using standard .NET methods and also stops at the first file found.

VB.NET open a Text File within the same folder as my Forms without writing Full Path

I found a similar question but it was 5 years 8 months old, had 2 replies and neither worked for me (VB.Net Read txt file from current directory)
My issue is that when I use the following code:
Dim fileReader As String
fileReader = My.Computer.FileSystem.ReadAllText(Application.StartupPath & "\Username_And_Password_Raw.txt")
Dim usernameAndPassword = Split(fileReader, ",")
I get an error saying:
System.IO.FileNotFoundException: 'Could not find file 'C:\Users\wubsy\source\repos\NEA Stock Page System\NEA Stock Page System\bin\Debug\net6.0-windows\Username_And_Password_Raw.txt'.'
I have tried using all the different Applications.BLANKPath options I can find (ie; StartupPath, CommonAppDataPath, etc.) and they all return essentially the same error only with a different location.
This is the folder layout of my TXT File - I know it's a terrible, incredibly insecure and generally awful way of storing login information but this is just for a NEA so will never ever actually be used
This is the actual path of the TXT File if it helps
C:\Users\wubsy\source\repos\NEA Stock Page System\NEA Stock Page System\Username_And_Password_Raw.txt
The startup path is where your exe is located. That and all supporting files get copied to a binary directory when you compile in visual studio, in your case
C:\Users\wubsy\source\repos\NEA Stock Page System\NEA Stock Page System\bin\Debug\net6.0-windows
But what you're trying to do, reference the file where it sits in your solution, is probably not the best way to do it, and your code above will work (with a change, will mention later) if you change the properties of the file in the solution.
Right click on the file in the Solution Explorer Username_And_Password_Raw.txt, select Properties. Modify Copy to Output Directory to either Copy always / Copy if newer, depending on your requirement. Now that file will copy to the same directory your exe is in, and the code above should work.
Note, when creating a path, don't use string concatenation because you may have too many or too few \; use Path.Combine:
Dim filePath = Path.Combine(Application.StartupPath, "Username_And_Password_Raw.txt"
Dim fileContents = My.Computer.FileSystem.ReadAllText(filePath)

Check if file exists in OneDrive via VBA

I'm trying to check if an Excel file exists in OneDrive using Dir(Filename) (without opening it):
strFilePath = "https://d.docs.live.net/ce59asdf4hj34h5k/Folder 1/Folder 2/File.xlsm"
If Dir(strFilePath) <> "" Then
'do something
End If
but Dir(Filename) give me an error: Run-time error '52': Bad filename or number
I tried to do a workaround and check if the URL itself is valid (using the code sample from here) unfortunately the URL is always valid regardless if the file exists or not (if the file in question does not exist One Drive seems to return a default file, at least that's what it does if you test it in a browser, see screenshot below)
Any other ideas on how to solve the problem would be appreciated (I'm trying to do this without actually opening the file since this will create other problems I'm trying to avoid).
Note: I have OneDrive (Sync) installed, but using a local path unfortunately is out of solution's scope. The Soultion has to work with files that are not synced locally.

VBA code (if needed) to save new Word document in same directory as other Word doc

Many users, myself included, begin editing a Word document, create a new Word doc, and wish to save the second doc in the same directory as the first doc. This is the default behavior in an editor such as emacs. Word 2013, alas, makes me pick the directory ("Folder") where I wish to save the new file, forcing me to select among various network folders and then select multiple subdirectories before I reach the one containing my first document. I used to have a simple VBA script that would find the directory of the first file and then save the new file in that directory, or at least it would set the directory of the first file as the default directory for saving files. Does anyone have code to do what I'm looking for? Thanks!
This will the working directory to the directory of the first file you were working on:
ChDir(Application.Documents(Application.Documents.Count).Path)
If you want to save the most recent opened document to the same location as the first file you were working on, then try the following
Sub SaveWithFirstFile()
NewFileName = "filename1.docx
Application.Documents(1).SaveAs2 FileName:=Application.Documents(Application.Documents.Count).Path & "\\" & NewFileName
End Sub
Change "filename1.docx" to what you want it to

VBA fails to find a file

I have a VBA script used to process Word documents. The first thing the program does is to create an index of the documents in a defined set of folders. It then goes through the list processing each of the indexed documents.
The problem I am having is that it will sometimes decide that a particular document cannot be found, even though it previously indexed the document and a quick spot check shows the document to be in the correct place.
Can anyone shed some light on why VBA should display this behaviour?
The script is using the Dir$ function to index the files, and the Documents.Open function to open each word document for processing.
Sample code:
ChangeFileOpenDirectory (folderName)
inputFileName = Dir$(folderName & "*.doc")
Do While inputFileName <> ""
... call various functions here ...
inputFileName = Dir$
Loop
One of the functions called in the block has the following line:
Set currentDoc = Documents.Open(fileName:=docFileName, AddToRecentFiles:=False, Visible:=False)
This is the point at which the code is failing.
One of the most annoying things I have found is that recent files links are returned as the files themselves with Dir. You can use the FileSystemObject to check the file type.
I copy/paste your code and it works correctly.
However, it leaves all the files open (and hidden), and when you run it in another directory, additional files are opened and added to the open projects (take a look in the VBA editor).
My only guess is that after a while you're hitting the maximum allowable number of open files.
Try adding
currentdoc.Close
just before
inputFileName = Dir$
A few reasons, some duplicated from other answers:
If the path+ filename is long enough ... (you already answered in a comment)
If you are writing new files to same directory, Dir$ may get corrupted (happened to me)
If you have filenames with non-std chars (ex. "#")
Files locked by other processes
Files deleted while the macro is running
You may also try this code ...
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(file) Then ....
First enable the Microsoft Scripting reference in the VBE