Merging two text files using Shell script in VBA - excel

I have three String varibales in my VBA code as below:
Dim FilePath As String
Dim FooterFilePath As String
Dim PlusChar As String
FilePath = Application.ActiveWorkbook.Path & "\Bin\file.txt"
FooterFilePath = Application.ActiveWorkbook.Path & "\Bin\footer.txt"
PlusChar = Chr(43) 'i.e. "+" sign
Now I am trying to merge FilePath and FooterFilePath and write the combined result in FilePath again i.e. overwriting it. For that I am using followng line which doesn't work:
Shell "cmd.exe copy /c & FilePath & PlusChar & FooterFilePath & FilePath", 0
I know I have syntaxing issue here but I just don't know how to pass three variables into Shell command.

You have to put the variables outside the enclosing double-quotes. also you should insert blanks between the different names so that your command does not get the names combined in one name. Try this:
Shell "cmd.exe copy /c " & FilePath & " " & PlusChar & " " & FooterFilePath & " " & FilePath, 0
But:
There's no reason to have a variable for the +
Your drive's name is missing in the paths
/C is an option for the cmd program, not for the copy command.
It is useful to print that expression in the immediate window to verify it before execution. To do so, you can put it in a String variable and debug.print it before execution:
This would be correct:
Dim FilePath As String, FooterFilePath As String, myCommand As String
FilePath = Application.ActiveWorkbook.Path & "C:\Bin\file.txt"
FooterFilePath = Application.ActiveWorkbook.Path & "C:\Bin\footer.txt"
myCommand = "cmd /c copy " & FilePath & " + " & FooterFilePath & " " & FilePath
Debug.Print myCommand
Shell myCommand, 0

Related

Using SaveAs Function, but periods change the fileformat

I open an Excel file, fill some cells and then save it in a new folder.
The generated files include today's date that includes periods.
If the filename for example is "Template_Name_01.01.2022" the fileformat changes to .2022
Dim OriginalFileName As String
fileName = "Template_" & Nz(rs!Street, "Address") & "_" & Date
OriginalFileName = fileName
Dim fileNumber As Integer
fileNumber = 1
Do Until nameFree = True
nameCheck = Dir("G:\Argus\_Deal Tracker 3.0\Deals_Inv Mgmt\" & fileName)
If nameCheck = "" Then
xlBook.SaveAs fileName:="G:\Argus\_Deal Tracker 3.0\Deals_Inv Mgmt\" & fileName, FileFormat:=xlOpenXMLStrictWorkbook
nameFree = True
Else
fileName = OriginalFileName
fileName = fileName & " (" & fileNumber & ")"
fileNumber = fileNumber + 1
End If
Loop
Even though I determine the fileFormat it saves the file as .2022
Saved files
If I add an ".xlsx" extension to the filename it works for me but not on other PCs, I am guessing it is because they have file extensions hidden.
If they run the function they get this error.
Is there a way to prevent the file format changing if periods appear in the name?
You need to format the Date to remove the forward slashes / from the file name as they're not allowed. You also need to supply the file extension in the path.
So, change this:
fileName = "Template_" & Nz(rs!Street, "Address") & "_" & Date
to this:
fileName = "Template_" & Nz(rs!Street, "Address") & "_" & Format(Date, "dd.mm.yyyy") & ".xlsx" 'change to your extension
Performing the Save As from script, you have to contruct the whole filename, including the extension.
Basically you have to add something like:
fileName = "Template_" & Nz(rs!Street, "Address") & "_" & Date & ".csv"

Sending a string that contains quotations to a file with VBA

I am trying to use VBA build a .jet file, but when I try to append, two possible problems appear. Either it includes all double quotes including the double double quotes like you would normally do in, say, a msgbox, or the string wont work if i remove the double double quotes because the first instance of quotes terminates the string. An example of my code is below (note, the commented/indented areas in the main sub are various possibilities I have tried but without success:
Sheets("Sheet1").Range("A1").Select
Dim MyStr As String
'MyStr = "{" & Chr(34) & "myid" & Chr(34) & ":345," & Chr(34) & "content" & Chr(34) & ":["
'MyStr = "{""myid"":345,""content"":["
'appendToFile ("{""myid"":345,""content"":[")
'appendToFile (MyStr)
End Sub
Sub appendToFile(MyStr As String)
Dim fileName As String
fileName = "MyFile.jet"
Open Application.ActiveWorkbook.Path & "\" & fileName For Append As #1
Write #1, MyStr
Close #1
End Sub
If you want to avoid the extra quotes appearing in your .jet, you can append using the Print # statement, and not the Write # statement.
Unlike the Print # statement, the Write # statement inserts commas between items and quotation marks around strings as they are written to the file.
For example, this code:
Option Explicit
Sub ject()
Dim MyStr As String
MyStr = "{" & Chr(34) & "myid" & Chr(34) & ":345," & Chr(34) & "content" & Chr(34) & ":["
appendToFile (MyStr)
End Sub
Sub appendToFile(MyStr As String)
Dim fileName As String
fileName = "MyFile.jet"
Open Application.ActiveWorkbook.path & "\" & fileName For Append As #1
Print #1,
Close #1
End Sub
will result in:
{"myid":345,"content":[
when opening the .jet file with a text editor.
Is that what you want?

Compile error: expected list separator or ) excel VBA

I have got this command line in VBA:
Call Shell("cmd.exe /S /k " & ""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """", vbNormalFocus)
When I remove the quotations the error appears in VBA:
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.
When I add the quotations the error appears in VBA:
Compile error: expected list separator or )
How can I solve the error?
The quotation is wrong, you must put another pair of quotes around the javaw.exe path, because in VBA, a literal " must be specified as "":
Call Shell("cmd.exe /S /K " & """C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """", vbNormalFocus)
But this is still not going to work, because cmd removes the outer-most quotation marks and leaves behind an invalid command line. Therefore, you must provide another pair of (literal) quotation marks around the whole expression behind /K, which may be removed by cmd:
Call Shell("cmd.exe /S /K " & """""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """""", vbNormalFocus)
Finally, let me recommend to enclose the DPath value within (literal) quotation marks as well:
Call Shell("cmd.exe /S /K " & """""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar """ & DPath & """ """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """""", vbNormalFocus)
Please learn how to make your life easy. Just because you can represent a " in a VBA string using """ doesn't mean you should except in the most trivial instance.
Here is a native VBA method for making life simpler.
Dim qDPath As String
Dim qinp1 As String
Dim qinp2 As String
Dim qsPath As String
Dim qFilePath As String
Dim qCommand As String
qDPath = MakeQuotedString(Path)
qinp1 = MakeQuotedString(inp1)
qinp2 = MakeQuotedString(inp2)
qsPath = MakeQuotedString(sPath)
qFilePath = MakeQuotedString(FilePath)
qCommand = MakeQuotedString("C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe")
qCommand = MakeQuotedString("cmd.exe /S /k " & qCommand & "-Jar " & qDPath & qinp1 & qinp2 & qsPath & qFilePath)
Call Shell(qCommand, vbNormalFocus)
Whilst the above is much more verbose it at least allows you to use single stepping via F8 to check at each stage that you are constructing the final command string correctly.
As you can see the above is a bit verbose which is why many other programming languages have the ability to embed variable and formatting markers in a string. This can also be done in VBA using a Module to hide the relevant code. Please have a look at the Fmt method in my Layout Module for VBA. Its available in GitHub from here. Its a very simple library module to allow the embedding of variable fields and formatting markers in strings
This will allow you to write
Call Shell("cmd.exe /S /k " & ""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe" -jar " & DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & FilePath & """", vbNormalFocus)
In a much more concise way, which is also friendly to the human eye.
Dim ShellCmd as String
ShellCmd = Fmt("cmd.exe /S /k {dq}{dq}C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe{dq} -jar {dq}{0}{dq} {dq}{1}{dq} {dq}{2}{dq} {dq}{3}{dq} {dq}{4}{dq}{dq}", dpath, inp1, inp2, sPath, FilePath)
Call Shell(ShellCmd, vbNormalFocus)
Apologies in advance if I've still managed to get the {dq} mismatched.
Call Shell("cmd.exe /S /k ""C:\Program Files\Java\jre1.8.0_171\bin\javaw.exe"" -jar " & _
DPath & " """ & inp1 & """ """ & inp2 & """ """ & sPath & """ """ & _
FilePath & """ ", vbNormalFocus)
...depending on the various values of your concatenated variables

Call .com file with parameters using VBA WScript.Shell

I'm using Excel to upload some files onto an server with WinSCP.
This example works:
Sub FTP_upload()
Dim logfile, ftp_login, file_to_upload, upload_to_folder As String
logfile = "D:\temp\ftp.log"
ftp_login = "ftp://ftp_mydomain:mypassword#mydomain.com/"
file_to_upload = "D:\tmep\myfile.txt"
upload_to_folder = "/myfolder/"
'upload the file
Call Shell("C:\Program Files (x86)\WinSCP\WinSCP.com /log=" & logfile & " /command " & """open """ & ftp_login & " " & """put " & file_to_upload & " " & upload_to_folder & """ " & """exit""")
End Sub
I now want Excel to wait until the shell has closed.
Using the information from Wait for shell command to complete, I put it together this code:
Sub FTP_upload_with_wait()
Dim wsh As Object
Set wsh = VBA.CreateObject("WScript.Shell")
Dim waitOnReturn As Boolean: waitOnReturn = True
Dim windowStyle As Integer: windowStyle = 1
Dim errorCode As Integer
Dim logfile, ftp_login, file_to_upload, upload_to_folder As String
logfile = "D:\temp\ftp.log"
ftp_login = "ftp://ftp_mydomain:mypassword#mydomain.com/"
file_to_upload = "D:\tmep\myfile.txt"
upload_to_folder = "/myfolder/"
execute_string = "C:\Program Files (x86)\WinSCP\WinSCP.com /log=" & logfile & " /command " & """open """ & ftp_login & " " & """put " & file_to_upload & " " & upload_to_folder & """ " & """exit"""
errorCode = wsh.Run(execute_string, windowStyle, waitOnReturn)
End Sub
Unfortunately, this doesn't work. Excel reports:
run-time error '-2147024894 (80070002)'
Automation error
The system cannot find the file specified
When I replace the string this way, it works:
execute_string = "notepad.exe"
It seems that wsh.Run doesn't like the quotation marks.
How can I make this work?
The path to WinSCP contains spaces, so you need to wrap it to double-quotes (which need to be doubled to escape them in VBA string):
execute_string = """C:\Program Files (x86)\WinSCP\WinSCP.com"" ..."
But that's only the first set of quotes that is wrong in your command.
The correct command would be like:
execute_string = """C:\Program Files (x86)\WinSCP\WinSCP.com"" " & _
"/log=" & logfile & " /command " & _
"""open " & ftp_login & """ " & _
"""put " & file_to_upload & " " & upload_to_folder & """ " & _
"""exit"""
Assuming that none of logfile, ftp_login, file_to_upload and upload_to_folder contains spaces, in which case would would need a way more double-quotes.
Read ore about WinSCP command-line syntax
The Call Shell must have some heuristics that adds the quotes around C:\Program Files (x86)\WinSCP\WinSCP.com. Though it's just a pure luck that the rest of the command-line works, the quotes are wrong there too. So even your first code is wrong. It runs the following command:
"C:\Program Files (x86)\WinSCP\WinSCP.com" /log=D:\temp\ftp.log /command "open "ftp://ftp_mydomain:mypassword#mydomain.com/ "put D:\tmep\myfile.txt /myfolder/" "exit"
(Note the misplaced quotes around open)

VBA Shell command with variables and spaces

In a Microsoft Outlook macro, I'm trying to use a Shell() call to open an Excel spreadsheet (whose filepath is referenced by my templatePath variable). I keep getting syntax errors from the editor and "file not found" errors when executing it.
I started with the following line:
Shell ("""C:\Program Files (x86)\Microsoft Office\Office16\EXCEL.EXE"" ""C:\Users\My_Username\Desktop\My_Folder\Request Template.xlsx"""), vbNormalFocus
It opens the appropriate file just fine; I just don't know the proper syntax to use the templatePath variable instead of hard-coding the path to the spreadsheet. I've seen questions similar to this, but none seemed to fit my situation closely enough. Any help would be greatly appreciated!
This should work:
Dim templatePath As String
templatePath = "C:\Users\My_Username\Desktop\My_Folder\RequestTemplate.xlsx"
Shell ("""C:\Program Files (x86)\Microsoft Office\Office16\EXCEL.EXE"" """ & templatePath & """"), vbNormalFocus
If your template resides in the Application.TemplatesPath and you just want to specify the filename then use:
templatePath = Application.TemplatesPath & "RequestTemplate.xlsx"
A more adjustable version:
Dim templatePath As String
Dim programPath As String
Dim templateName As String
templateName = "RequestTemplate.xlsx"
templatePath = Application.TemplatesPath
programPath = "C:\Program Files (x86)\Microsoft Office\Office16\EXCEL.EXE"
Shell ("""" & programPath & """" & " " & """" & templatePath & templateName & """"), vbNormalFocus

Resources