Visual Basic in Word 2010 - Open Dir - Relative Path - vba

I'm creating a word document and I'm having trouble working out the code to open a specific directory.
Basically, I'll have a bunch of video files on a USB drive or a DVD in separate folders and when the command button is clicked, I would like it to open the relevant directory in a windows explorer window.
I did some Google searching and came up with the following code:
FolderName = "c:\windows"
TaskID = Shell("explorer.exe " & FolderName, vbNormalFocus)
The only problem now is that I need to change the path reference from absolute to relative, as I'll be running everything from either a USB drive or a DVD on multiple computers.
I have tried every possible iteration of relative path references, but I can't seem to get it to work. The folders are simply sub-directories of where the word document is.
Anyone got any clues as how I can change the above code to be relative rather than absolute path references?

I think something like this might be what you're looking for:
FolderName = ActiveDocument.Path & "\SubFolder"
TaskID = Shell("explorer.exe " & FolderName, vbNormalFocus)
Assuming that your document is the active one, otherwise you might need to search through the Documents collection for the correct one.

Related

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

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

What is the difference between Program and Argument directories when calling .exe using Shell in VBA?

My latest attempt to solve my problems when calling a .exe with an input argument from Excel-VBA uses this script:
Sub RunProgram()
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
ChDir "\\path\folder1\folder2\"
StartExeWithArgument
......
End Sub
Public Sub StartExeWithArgument()
Dim strProgramName As String
Dim strArgument As String
strProgramName = "program.exe "
strArgument = "datafile.gdp"
Call Shell("""" & strProgramName & """ """ & strArgument & """", vbNormalFocus)
End Sub
The path I set as the working directory is the working directory of the .exe program, and the location of the input file datafile.gdp. However, this current script calls the .exe without loading the argument file and the calculations the .exe is supposed to run do not occur. Instead the .exe launches to its main page as though I clicked a desktop shortcut to start a new project. When loaded correctly, the .gdp file should cause the calculation to initiate and run in the background without ever appearing to the user.
If I change the path of the input file to:
strArgument = "\\path\folder1\folder2\datafile.gdp"
But keep everything else the same, the .exe launches and calculates automatically, but wants to write files in the following duplicated directory, (all prefixed with the name of the input file):
\\path\folder1\folder2\PATH\FOLDER1\FOLDER2\
If I create the file path for it to operate in everything operates as it should, BUT the path is actually 6 folders deep in reality and this is all being duplicated, meaning the files are too deep to be backed up on our system. So I need to launch the program and have it operating without this duplication of the directory. It works fine when not launched from this VBA script, and worked fine before the .exe was updated by an external company.
Why can the Call Shell command find the .exe without a path, but I
need to provide a path for the argument?
strArgument = ... requires a path to find the argument file, despite the file being in the current directory, providing the path seems to pass a duplicated path to the .exe causing it to crash if I don't create the folders representing the duplicated directory so it can operate within them. Is there something very basic I am missing regarding directories?
My previous up-voted but unanswered question here provides more context.

VBA - Finding folder inside a directory and returning the path of that folder

I am using excel vba to make an application that acts as a job card. User will fill in relevant fields, press a button to update a running summary of costs, as well as generate a printable pdf of the job card. I have very limited experience in coding (a semester of java 4 years ago) so i am relatively new to this.
Currently, the application automatically updates the summary file and can open a word template file and fill it in with information from the input fields, so it mostly works. I have realised an issue in the way it is finding the summary files, in that as soon as a folder name does not align with the way i am constructing the folder paths in the app, it will return errors.
At the moment I am going into folders like this:
templatePath = "C:\SERVICE\Card Template.doc"
If cbxType.Text = "Plant" Then
savePath = "C:\SERVICE\0.1 PLANT\" & cbxNo.Text & " - " & txtMakeModel.Text & " " & txtRego.Text & "\0.2 SERVICE SHEETS\"
ElseIf cbxType.Text = "Vehicle" Then
savePath = "C:\SERVICE\0.2 VEHICLES\"
End If
The directory is constructed from text and combo boxes which are populated once the user chooses a type (plant, vehicle, etc.) and then ID, which fills in boxes for model name, registration number, hours etc.
I am after a piece of code that can iterate through a given directory, searching the folder names for a string and returning the path of that folder. Each folder begins with the ID number, so I figure I can search folder names for that but I am not sure how to construct the loop. Any help with this, or alternative ideas would be appreciated. If it isn't too much to ask I'd also like a little bit of an explanation on how it works.

Visual Basic.NET Saving Preferences in a .txt or .ini

I want to save my preferences for a program. I just want to know how to do it, since I cant get how to save this file at my documents, because every computer has a different name and username, but using the
My.User.Name
returns 'USERNAME-PC-USERNAME' which doesn't work.
For example, I want the program to create this text file 'CPreferences' at 'C:\Users\'username'\Documents'. And then when the program is re-opened it will automatically load this file into itself, the file will basically contain 2 lines:
Option1:<Value 1>
Option2:<Value 2>
The values will represent choices, ofcourse. So fundamentally, my question is:
1) How to save this file automatically at this user's documents WITHOUT showing a savefiledialog?
2) How to automatically load it if the file there exists?
Thanks,
VB.Net has built-in features for storing and retrieving the user's settings. Just use them. You won't have to worry about how the settings are stored or where the files are. It all just works.
Using something along the lines of string = "----------- " & CurrentTitle & " (" & Now.ToString() & ") User " & Environment.UserName & " on computer " & Environment.UserDomainName & "------------"
will result in
----------- Google - Google Chrome (3/12/2012 2:09:49 AM) User Drise on computer Drise-LAPTOP ------------
Using a streamwriter with filename "C:\users\" & Environment.UserName & "..." should do the trick.
To auto-load the file, check if the file exists and use a streamreader with the same path variable as above, or if not, then set default settings.
For saving to the "My Documents" folder for the current user, this will return the directory path:
My.Computer.FileSystem.SpecialDirectories.MyDocuments
You can also use other items in "special directories" if you want things like the "downloads" or "my pictures" folders, or anything else like that.
I think what you're looking for is user configuration.
You can store settings for users that will be unique to the logged in user.
Use this as a reference for getting started with it:
http://www.codeproject.com/Articles/12252/Application-settings-in-VB-NET-2-0-and-Visual-Stud

VBA How to get path to The Current Users Application data folder?

In general,
Using VBA, how do I determine where the Current users Application Data folder is?
The FileSystemObjects special folders only knows about 3 folders
WindowsFolder
SystemFolder
TemporaryFolder
Specifically, I need a Word Macro to copy a file to the a folder under the Application Data folder.
e.g. In VB.Net I can use My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData to do this
You can use Environ("AppData") to get this path. Environ will pull any system variable, which can be found by using the set command at the DOS prompt.
Using advapi32.dll, you can get the USERPROFILE via
Environ("USERPROFILE")
Connect this with the "Application Data" directory (which has a standard, specific name) to get what you want
CStr(Environ("USERPROFILE") & "\Application Data")
For more information, check out MSDN