I use Excel VBA to create emails in Thunderbird using command line arguments, found here:
http://kb.mozillazine.org/Command_line_arguments_%28Thunderbird%29
Composing the mails works, but how can I send it automatically?
Alternatively, is there a button in Thunderbird to send all composed emails at once?
VBA code looks like this:
Option Explicit
Sub thunderbird()
Dim strTh As String
Dim strCommand As String
strTh = "C:\Program Files (x86)\Mozilla Thunderbird\thunderbird.exe "
strCommand = strCommand & " -compose " & "to=" & Chr(34) & "foo#bar.de" & Chr(34)
strCommand = strCommand & ",preselectid=id2"
strCommand = strCommand & ",subject=" & Chr(34) & "wow so email" & Chr(34)
strCommand = strCommand & ",body=" & Chr(34) & "anything" & Chr(10) & "more" & Chr(34)
Call Shell(strTh & strCommand, vbNormalFocus)
End Sub
Unfortunately, this is not possible as such. However, https://support.mozilla.org/questions/1144493 lists alternatives, in case they work for you.
From UI, File -> Send Unsent Messages should work (you may need to activate the menu bar) to send all composed messages.
Related
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
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)
Currently I can't use xlwings because I can't access Windows' cmd. But I can access PowerShell, so I tried to change xlwings specific VBA code that calls the cmd to call the PowerShell instead.
When calling PowerShell with commands from VBA, it does not work. If I paste the exact same commands in the PowerShell terminal, it works as expected.
I've tried to compare the (not working) command VBA passes to PowerShell with the (working) command I manually paste into PowerShells terminal. But they look exactly the same.
The original xlwings code that calls the cmd
RunCommand = PythonInterpreter & " -B -c ""import sys, os; sys.path[0:0]=os.path.normcase(os.path.expandvars(r'" & PYTHONPATH & "')).split(';'); " & PythonCommand & """ "
ExitCode = Wsh.Run("cmd.exe /C " & _
DriveCommand & RunCommand & _
"""" & WORKBOOK_FULLNAME & """ ""from_xl""" & " " & _
Chr(34) & Application.Path & "\" & Application.Name & Chr(34) & " " & _
Chr(34) & Application.Hwnd & Chr(34) & _
" 2> """ & LOG_FILE & """ ", _
WindowStyle, WaitOnReturn)
And my slightly modified version
RunCommand = "C:\ProgramData\Anaconda3\pythonw.exe -B -c ""import sys, os; sys.path[0:0]=os.path.normcase(os.path.expandvars(r'" & PYTHONPATH & "')).split(';'); " & PythonCommand & """ "
ExitCode = Wsh.Run("Powershell.exe -ExecutionPolicy ByPass -NoExit " & _
DriveCommand & RunCommand & _
"""" & WORKBOOK_FULLNAME & """ ""from_xl""" & " " & _
Chr(34) & Application.Path & "\" & Application.Name & Chr(34) & " " & _
Chr(34) & Application.Hwnd & Chr(34) & _
" 2> """ & LOG_FILE & """ ", _
WindowStyle, WaitOnReturn)
The resulting command from aboves code. Working when pasted into PowerShells terminal directly, not working when executed from VBA:
C:\ProgramData\Anaconda3\pythonw.exe -B -c "import sys, os; sys.path[0:0]=os.path.normcase(os.path.expandvars(r'C:\Users\<placeholder>\test1;')).split(';'); import test1;test1.hello_xlwings()" "C:\Users\<placeholder>\test1\test1.xlsm" "from_xl" "C:\Program Files (x86)\Microsoft Office\Office16\Microsoft Excel" "788640" 2> "C:\Users\<placeholder>\AppData\Roaming\xlwings.log"
I expect a simple "Hello, World!" in a specific Excel cell when clicking a button associated with the vba macro. Instead I get this error:
At line:1 char:213
+ ... X0RNZ\test1;')).split(';'); import test1;test1.hello_xlwings() C:\Use ...
+ ~
An expression was expected after "(".
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ExpectedExpression
If I paste the command in the PowerShell terminal directly I get my expected result, "Hello, World!" shows up in my specific Excel cell.
You are missing the -Command parameter. Depending on what DriveCommand contains, you should add -Command before DriveCommand or RunCommand.
Make sure there is a semicolon between de PowerShell commands and specify the command as a scriptblock, example:
powershell.exe -ExecutionPolicy ByPass -NoExit -Command { cd "c:\folder";c:\folder\run.exe "param1" "param2" }
Run powershell /? for more examples.
on my excel sheet the user can choose some video clips and arrange in different order to play as a vlc playlist. Unfortunately it can’t be guaranteed that the video file names haven’t any blanks.
To build the vlc playlist I use successfully:
Dim PL
PL = Shell("C:\Program Files\VideoLAN\VLC\VLC.exe " & certainPath & "\Movie6.flv" & " " & certainPath & "\Movie7.flv" & " " & certainPath & "\Movie8.flv ", 1)
'using "\Movie 6.flv" 'doesn't work of course
'using "\'Movie 6.flv'" 'doesn't work aswell
Is there another way to encapsulate file name with blanks?
thankfull for a hint.
Assuming that certainPath folder end with \ ( es. "C:\" ), this should work:
Dim PL
PL = Shell(chr(34) & "c:\Program Files\VideoLAN\VLC\vlc.exe " & chr(34) & chr(34) & certainPath & "Movie 6.flv" & chr(34) & " " & chr(34) & certainPath & "Movie 7.flv" & chr(34))
CHR is a function to returns the character from the ASCII table (the quotes in this case).
I have an issue, have an AutoCAD file with a ton of data links and would like to update only the data links related to a speciffic table.
Simmilar to the functionality of selecting a table with data links, right clicking and selecting Update Table Data Links.
i have the following code:
Private Sub Update_table_data_link(tblRef As AcadTable)
ThisDrawing.SendCommand "DATALINKUPDATE" & vbCr & "U" & vbCr & "K" & vbCr
End Sub
It works but updates all the data links in the drawing (which is a problem) so a perfect solution would either let me get what links are associated to tblRef
and change the line to:
ThisDrawing.SendCommand "DATALINKUPDATE" & vbCr & "U" & vbCr & "D" & vbCr & "datalink_name_from_tblRef" & vbCr
or directly send the command to update the links to tblRef
After much digging around and a lot of help, here is the answer:
Private Sub Update_table_data_link(tblRef As AcadTable)
ThisDrawing.SendCommand "DATALINKUPDATE " & vbCr & "U" & vbCr & Ent2lspEnt(tblRef) & vbCr & vbCr
End Sub
Public Function Ent2lspEnt(entObj As AcadEntity) As String
'Designed to work with SendCommand, which can't pass objects.
'This gets an objects handle and converts it to a string
'of lisp commands that returns an entity name when run in SendCommand.
Dim entHandle As String
entHandle = entObj.Handle
Ent2lspEnt = "(handent " & Chr(34) & entHandle & Chr(34) & ")"
End Function
note that "Update_table_data_link" has a table as input