I am novice to VBA shell. So i request an explanation to understand how things work.
Through EXCEL VBA, I would like to create a *.bat file and execute the same automatically. However my command lines ONLY creates the file and does not execute it. Please suggest.
Sub Create_Motor_Model()
Application.ScreenUpdating = False
CURRENT_SHEET = "Script"
Output_path = ActiveWorkbook.Path
InputData1 = Cells(1, 2)
file_output = Output_path & "\" & "Input.bat"
Open file_output For Output As #1
Print #1, Chr(34) & InputData1 & Chr(34) & " -b -i " & CURRENT_SHEET & ".mac -o Output.out"
Close #1
Shell ActiveWorkbook.Path & "\Input.bat"
End Sub
I am trying to execute some python scripts through VBA code.
.py files are working pretty well, but i am struggling with .ipynb files
running python script(.py) as following link :
https://stackoverflow.com/questions/73258152/how-to-exceute-ipynb-file-in-excel-vba-code),
but the same way doesn't work for ipynb files.
After quite long searching, i found this article
https://stackoverflow.com/a/62657958/19118788
and in this article, below code is suggested to run ipynb file in excel VBA.
Sub execute_notebook()
Dim objShell As Object
Dim new_cmd_window As String
Dim full_script As String
Dim activate_env As String
Dim change_dir_script As String
Dim convert_and_run_nb As String
Set objShell = VBA.CreateObject("Wscript.Shell")
new_cmd_window = "cmd /c"
activate_env = "cd /d [path to Anaconda\Scripts folder which on my machine is
C:\ProgramData\Anaconda3\Scripts] & activate [environment_name] &"
change_dir_notebook = "cd /d [path to folder where notebook is] &"
convert_and_run_nb = "jupyter nbconvert --to notebook --execute [notebook name].ipynb"
full_script = new_cmd_window & " " & Chr(34) & activate_env & " " & change_dir_script & " " & convert_and_run_nb & Chr(34)
objShell.run full_script
End Sub
Most of lines are understood, but i have no idea for [environment_name] in the above code.
(I am beginner to these things)
Please tell me, what should i do for [environment_name] ??
I have and Excel file which contains the data for a Python code. Python code is called from a .exe, and I can see in the PowerShell the results which that code is generating.
Sub Button()
Dim strPName As String
Dim strData As String
strPName = Range("H24").Text
strData = "--inputs"
Call Shell("""" & strPName & """ """ & strData & """", vbNormalFocus)
End Sub
When I have issues in the code or with the data input, the PowerShell is switch off and I cannot review which was the issue.
I want to include in the button code an automatic .txt file generation, which records the PowerShell text and let me review it after the stop.
I found here How to save the ouput of shell command into a text file in VBA the following command:
Shell "ftp -n -i -g -s:" & vPath & "abc.txt " & vFTPServ & " >> test.txt", vbNormalFocus
But I don't know how to connect it properly in my current button.
Could you give me some suggestions of how could I solve it?
I am using the following code to try and create a .txt file and upload it to my FTP server. I want to create a text file called Ref.txt and insert some cell values into the text file and then upload this to my FTP server. For some reason I do not get any errors but the text file doesn't get uploaded to my FTP server.
Could someone please show me where I am going wrong?
I want to create a temporary text file called Ref.txt on the users P:/ drive then print irange("A1").value.
Dim vPath As String
Dim vFile As String
Dim vFTPServ As String
Dim fNum As Long
vPath = "P:\"
vFile = Ref & ".txt"
vFTPServ = "********"
'Mounting file command for ftp.exe
fNum = FreeFile()
Open "P:\" & Ref & ".txt" For Output As #fNum
Print #1, "hewdenportal.co.uk" ' your login and password"
Print #1, "/public_html/ns_requests" 'change to dir on server
Print #1, "bin" ' bin or ascii file type to send
Print #1, "put " & vPath & "\" & vFile & " " & vFile ' upload local filename to server file
Print #1, "close" ' close connection
Print #1, "quit" ' Quit ftp program
Close
Shell "ftp -n -i -g -s:" & vPath & Ref & ".txt" & vFTPServ, vbNormalNoFocus
SetAttr vPath & Ref & ".txt", vbNormal
Kill vPath & Ref & ".txt"
In the code fNum is the handle to your file so you should use that when printing and closing the file. In your code change Print #1 to Print #fNum.
Also change Close to Close #fNum.
In the line Shell "ftp -n -i -g -s:" & vPath & Ref & ".txt" & vFTPServ, vbNormalNoFocus the -s parameter tells ftp to execute the contents of the file. So it looks like you are creating the file and then telling ftp to upload the file using the commands in the file?
If you want to write the value of a range to the file then Print #fNum Workbooks("book_name.xlsm").Worksheets("sheet_name").Range("A1").Value will do it. If you fully qualify the cell address in this way, you always know which workbook and worksheet you are using.
I wrote VBA code which creates a .txt file with Job-Code for an IBM host based on Excel data (Websphere MQ Define Job).
It would be cool to have the possibility to tranfer this file to the host automatically via FTP. At this point I do this manually via:
(comment: LPAR = Host-Name)
ftp <LPAR>
'user'
'password'
put 'dateiname'
It works quite fine. But I don't know how to tranfer this to the VBA code. I found a similiar question here and there this solution was posted:
Public Sub FtpSend()
Dim vPath As String
Dim vFile As String
Dim vFTPServ As String
Dim fNum As Long
vPath = ThisWorkbook.path
vFile = "path"
vFTPServ = "<LPAR>"
'Mounting file command for ftp.exe
fNum = FreeFile()
Open vPath & "\FtpComm.txt" For Output As #fNum
Print #1, "user *******" ' your login and password"
'Print #1, "cd TargetDir" 'change to dir on server
Print #1, "bin" ' bin or ascii file type to send
Print #1, "put " & vPath & "\" & vFile & " " & vFile ' upload local filename to server file
Print #1, "close" ' close connection
Print #1, "quit" ' Quit ftp program Close
Shell "ftp -n -i -g -s:" & vPath & "\FtpComm.txt " & vFTPServ, vbNormalNoFocus
SetAttr vPath & "\FtpComm.txt", vbNormal
Kill vPath & "\FtpComm.txt"
End Sub
I'm not sure if I understand the code completely. I think I create a dummy file, FtpComm.txt, with the user data and the content and use this file to open the connection and send the data.
It works, somehow, until the point
*SetAttr vPath & "\FtpComm.txt", vbNormal*
There I get the error
Runtime-Error: 55 - File already opened.
The connection to the LPAR is set at this point. But what does "SetAttr..." do? Is this the point where the Input is done? What should I do?
Two things.
First, you are opening a file under file number #fNum obtained from fNum = FreeFile(), and then just assuming that this will return 1, as in Print #1 etc.:
Open vPath & "\FtpComm.txt" For Output As #fNum
Print #1, "user *******" ' your login and password"
Change all your Print #1 to Print #fNum.
Second, you open your file for I/O, but never close it. So of course, when you try to modify its attributes or delete it, the system will complain that it's already open and in use. The solution is to close the file -- which you should always do as soon as you're done writing to/reading from a file.
Close #fNum ' add this line
' Can now manipulate the file without risking conflict
Shell "ftp -n -i -g -s:" & vPath & "\FtpComm.txt " & vFTPServ, vbNormalNoFocus
SetAttr vPath & "\FtpComm.txt", vbNormal
Kill vPath & "\FtpComm.txt"
As for what your code is doing on a high level: if you type ftp -help at the command line, you will see what those -n -i -g -s flags mean. So yes, you're writing FTP commands to file FtpComm.txt, and then supplying that file to ftp via the -s flag.
-s:filename Specifies a text file containing FTP commands; the
commands will automatically run after FTP starts.
You're on the right path and following Jean-François's answer should get you there.
If you want something you can cut and paste, you can try the code below. It's a variation of something I wrote several years ago.
The biggest caveat is that once you shell the FTP command, you have no idea if the file actually transferred until you manually check.
But, if you're limited to strict VBA, then this is the way to go:
Option Explicit
Const FTP_ADDRESS = "ftp.yourdestination.com"
Const FTP_USERID = "anon"
Const FTP_PASSWORD = "anon"
Sub Macro1()
If Not SendFtpFile_F() Then
MsgBox "Could not ftp file"
Else
MsgBox "Sent"
End If
End Sub
Function SendFtpFile_F() As Boolean
Dim rc As Integer
Dim iFreeFile As Integer
Dim sFTPUserID As String
Dim sFTPPassWord As String
Dim sWorkingDirectory As String
Dim sFileToSend As String
Const FTP_BATCH_FILE_NAME = "myFtpFile.ftp"
Const INCREASED_BUFFER_SIZE = 20480
SendFtpFile_F = False
sWorkingDirectory = "C:\YourWorkingDirectory\"
sFileToSend = "NameOfFile.txt"
On Error GoTo FtpNECAFile_EH
'Kill FTP process file if it exists
If Dir(sWorkingDirectory & FTP_BATCH_FILE_NAME) <> "" Then
Kill sWorkingDirectory & FTP_BATCH_FILE_NAME
End If
'Create FTP process file
iFreeFile = FreeFile
Open sWorkingDirectory & FTP_BATCH_FILE_NAME For Output As #iFreeFile
Print #iFreeFile, "open " & FTP_ADDRESS
Print #iFreeFile, FTP_USERID
Print #iFreeFile, FTP_PASSWORD
Print #iFreeFile, "mput " & sWorkingDirectory & sFileToSend
Print #iFreeFile, "quit"
Close #iFreeFile
'Shell command the FTP file to the server
Shell "ftp -i -w:20480 -s:" & sWorkingDirectory & FTP_BATCH_FILE_NAME
SendFtpFile_F = True
GoTo FtpNECAFile_EX
FtpNECAFile_EH:
MsgBox "Err", Err.Name
FtpNECAFile_EX:
Exit Function
End Function
Note: While stepping through code, you could type the following command in the immediate window and then copy/paste the results into a Command Window:
? Shell "ftp -i -w:20480 -s:" & sWorkingDirectory & FTP_BATCH_FILE_NAME
SetAttr is used to set the attributes of a file (or a folder). In your case it sets it back to Normal (so not hidden, readonly, etc.). However, since your file is still open from the 'Open For Output' call it will fail with the 'File already opened' error.
I don't see any reason why the SetAttr function is called though, as you are not changing the attributes anywhere else. So feel free to remove it and see if it still works.
In the first example, after the sentence
Print #1, "quit" ' Quit ftp program Close
you must close the file used for connection with the sentence:
Close #fNum
Because this file is currently used.