How to indicate a directory path using variables? - vba

I have to implement the use of a certain .exe file in VBA. The .exe takes as input a specific type of file and outputs a .txt file.
When I write the whole directory of both the input and output files, the code works. When I split the directory and store the parts in variables, it doesn't.
I need to split it because I am going to use this .exe with different directories so the user could choose the wanted directory.
Sub convert()
Dim directory As String
Dim Filename As String
directory = "C:\Users\user1\Desktop\reporting\201703161224"
Filename = "\input.set"
Shell "cmd /c""C:\Users\user1\Desktop\reporting\appli.exe
C:\Users\user1\Desktop\reporting\201703161224\input.set>
C:\Users\user1\Desktop\reporting\201703161224\output.txt"
'this works well
file = directory & Filename
Shell "cmd /c""C:\Users\user1\Desktop\reporting\appli.exe file>
C:\Users\user1\Desktop\reporting\201703161224\output.txt"
'this doesn't work
End Sub

You need to break out of the quotes and Concatenate to use your file string variable
Shell = "Hard_Coded_String_1" & file & "Hard_Coded_String_2"

Related

Missing txt file from Visual Basic

I am working in Visual Basic 2017. I have tried to add the file to the Debug folder, but then it just shows that the txt file ienter image description heres missing. I don't have the option under the "Word Solution".. How can I make the file show up? It keeps telling me it doesn't exist.
Dim inFile As IO.StreamReader
Const FileName As String = "words.txt"
Dim subscript As Integer
You can get the path of the directory (Debug or Release or any other) of the *.exe file with:
Dim directory as String = My.Application.Info.DirectoryPath
Using this information, you can then construct the full path with
Dim path As String = IO.Path.Combine(directory, FileName)
If IO.File.Exists(path) Then
...
You can check in Windows File Explorer to see where the file actually is (notice the Copy Path on the ribbon). In File Explorer you will see that the .exe you are running is down 2 directories from the Words Project directory. The double dots in the path is an old DOS way to navigating around directories without having to type out the whole path. This tells the compiler to find the file up 2 directories from the current directory.
For testing purposes this will work. For a release version you could add the file to Resources and access it the same way in any version.
You don't need a stream for a text file. .ReadAllLines returns an array of the lines in the text file
Private Sub OpCode()
Dim words = File.ReadAllLines("..\..\words.txt")
End Sub

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.

Read File name and put it into Variable

I am trying to find a way to read a specific file name in a directory and then put the file name into a variable. In my program I have a batch file that zips a folder called logs and then changes the name of zip to username_date_time.zip.
So basically if the filename was jobs_03152015_1315.zip I would want the entire file name but not the path stored into a variable. The file starts off on the user's local machine. It is then uploaded into a network share.
The network path will be uploaded to a database for others to view. I want to just add the unique file name to the end of a pre set path. Here is the code I am using.
Dim filePath As String = "c:\temp\logs\"
If (System.IO.Directory.Exists(filePath)) Then
For Each file As String In filePath
If file.Contains(".zip") Then
Dim zip As String = file
testbox.Text = zip
Exit For
End If
Next
End If
You can enumerate all files using the GetFiles() method of the static (shared in VB) Directory class, see msdn.
Assuming you have more then 1 file I add the files to a listbox control. But you could change that if you wish. I get the filename using the Path class. You will find a lot other helpful functions in this class.
Dim searchPath = "C:\temp\logs"
Dim files = Directory.GetFiles(path, "*.zip")
For Each file In files
listbox1.Items.Add(path.GetFileName(file))
Next
This should do it.
Your loop doesn't read anything. The string variable filePath is just the name of the directory, not a list of the files in that directory. Calling For Each over a string simply enumerates each character contained in the string
To get a list of files contained in that folder you need Directory.EnumerateFiles() and pass the filePath variable and the extension required.
It seems that you are interested only to find if that folder contains at least one file with zip extension. If this is the case then you could remove the explicit loop and write simply
Dim file = Directory.EnumerateFiles(filePath, "*.zip").FirstOrDefault()
If file IsNot Nothing Then
testbox.Text = Path.GetFileName(file)
End If
Using Path.GetFileName will return just the file without the path part
Try this code :
Dim FilePath As String = "c:\temp\logs\"
If (System.IO.Directory.Exists(FilePath)) Then
For Each File As String In System.IO.Directory.EnumerateFiles(FilePath)
If File.Contains(".zip") Then
Dim info As New System.IO.FileInfo(File)
zip = info.Name
testbox.Text = zip
Exit For
End If
Next
End If

How to perform "mkdir" and "move" operations in VB.NET?

just wondering if anyone could show me how to do a couple simple commands with VB.net syntax that I can do with DOS or batch files.
For example...
What would be the equivalent of
SET date="%date:~10,4%-%date:~4,2%-%date:~7,2%"
mkdir E:%date%
move C:\folder *.png E:\%date%
Thats just a simple DOS or batch command to make a directory with the date, and to move all .png files into that folder.
I need to know how to do mkdir and move. The part where I create the dated folder would be cool, but isn't necessary.
This chunk of code should match your script.
Dim dateText As String = Date.Now.ToString("yyyy-MM-dd")
Dim toPath As String = Path.Combine("E:", dateText)
Directory.CreateDirectory(toPath)
For Each (filename As String In Directory.GetFiles("C:\folder", "*.png"))
File.Move(filename, toPath)
Next
Have a look at the System.IO namespace. In particular the File and Directory classes.
To get the current date in a string you can use in the directory name have a look at the ToString method on the DateTime struct.

How to use Process.Start

I'm using process.Start to run Convert.exe. This program's purpose is to convert all files which are in the exe's folder. So when I normally use it, I copy paste a file into the same folder as Convert.exe and then run Convert.exe. Convert.exe will create a new "converted" file in the same folder.
I'm trying to automate this tedious process. A User selects a file which needs to be converted from FolderA, I copy it to the same folder where Convert.exe is and I'm using process.start(Convert.exe) to run it.
Just to be clear, this "Convert.exe" accepts NO arguments.
The problem: "Convert.exe" is not converting the files in its folder. Instead it's converting all the files in FolderA for some weird reason. I don't know why it picked that folder, I never even try to send it as an argument or nothing.
Here's the code I have:
Dim techInfo As New System.IO.FileInfo(itm.strFilePath)
techInfo.CopyTo(ConverterPath & techInfo.Name)
Dim procInfoConvert As New ProcessStartInfo
procInfoConvert.CreateNoWindow = False
procInfoConvert.Arguments = ""
procInfoConvert.FileName = ConverterPath & "Convert.exe"
Dim procConvert As Process = Process.Start(procInfoConvert)
I did a test where I copy pasted a file into the "Convert.exe" folder and then just run this code:
process.start(ConverterPath & "Convert.exe")
The exe returns nothing, same as if there was no files in the folder.
The only thing I can think of is that when process.Start is run, it copies the file to another location and runs it from there.
Any ideas anyone?
Try this:
procInfoConvert.WorkingDirectory = ConverterPath
That'll set the process up to start in the directory it's contained in, instead of the current directory.