VBA that runs shell command works only in debug mode - vba

I wrote some VBA code that calls ftp.exe via shell command. When the code runs, the shell command does not execute. However, if I step through the code in debug mode, it works every time. Here is the code:
Sub FTPFile(sSrc As String)
Dim sHost As String
Dim sUser As String
Dim sPass As String
Dim sDest As String
Dim sFTPCmds As String
Dim strConnect As String
'Build up the necessary parameters
sHost = "<redacted>"
sUser = "<redacted>"
sPass = "<redacted>"
sDest = "\"
'Write the FTP commands to a text file
iFNum = FreeFile
sFTPCmds = "<path redacted>" & "FTPCmd.tmp"
Open sFTPCmds For Output As #iFNum
Print #iFNum, "op " & sHost
Print #iFNum, "user " & sUser & " " & sPass
Print #iFNum, "cd " & sDest
Print #iFNum, "put " & sSrc
Print #iFNum, "bye"
Close #iFNum
Shell Environ("WINDIR") & "\System32\ftp.exe -n -s:" & sFTPCmds
End Sub
The only possible idea I came up with is that the user permissions that call this command differ based on whether the call occurs in debug mode or running, but I am unsure how to change the command.

Perhaps I can shed some light on this. I was experiencing a similar issue where I was creating a temporary pdf file and then using a shell command and pdftk to combine the temporary pdf file with another pdf and output the result. It was working perfectly when I stepped through the code, but during runtime I wasn't getting the output. As #Smandoli mentioned above, it is likely to be a timing issue.
My code was;
Dim wsh As Object
Set wsh = CreateObject("WScript.Shell")
wsh.Run "pdftk.exe """ & pdf1 & """ """ & pdf2 & """ output """ & ActiveWorkbook.Path & "\" & outputFile & """"
After the shell command was initiated I was removing the temporary file using
Kill ActiveWorkbook.Path & "\" & pdf1
It turns out this was occurring before the shell command could execute.
Forcing the shell command to wait for return solved the issue, as shown in this post: Wait for shell command to complete. This post recommends using WSScript.Shell over Shell as it has a wait on return option.

I had a piece of VBA macro code where:
1) The macro prepares some data in the Excel spreadsheet,
2) Opens another Excel file,
3) Writes data to the opened file spreadsheet cells,
4) Saves and closes the opened file
The macro ran perfectly in the debugger.
...but not in real time from the application. It opened the other file and then stopped working. Nothing happened, the opened file was not updated nor saved and closed. Excel was not stuck.
I tried the delay loops and application.wait after a hint from a fried. No help.
But then, I found DoEvents. Voila, it solved the problem. I put DoEvents before and after the file open and now it runs perfectly!

Usually this is a timing issue and it can be difficult to trace.
See some approaches here and here.
As a first step, add the DoEvents command at different spots. This prompts Windows to work on pending tasks outside the Access process.
Adding a timed loop to stave off a time-out is sometimes the answer, even though it seems unbearably kludgey.

Related

VBA unable to move on to next file in Directory, instead picking file named ".."

I am having a little issue with the Loop function to open files within a Directory. Find the code below:
'Build the complete folder path:
strTargetFolder_Batch = "I:\PerfTeam"
strTargetFolder_Batch = strTargetFolder_Batch & strMonthNo & " " & strMonthName & " " & strYear & "\" & "Attribution - Draft"
If Right(strTargetFolder_Batch, 1) <> "\" Then
strTargetFolder_Batch = strTargetFolder_Batch & "\"
End If
If Not CreateFolder(strTargetFolder_Batch) Then
MsgBox "Unable to create the folder:" & vbCrLf & strTargetFolder_Batch, vbExclamation
Else
End If
FolderPath = strTargetFolder_Batch
'Sets Parameters to Open the file
MyFolder = FolderPath 'location of files
MyExtension = "*.xlsx*"
MyFile = Dir(MyFolder & MyExtension)
Do While MyFile <> "" 'will start LOOP until all files in MyFolder have been looped through
Set oWbk = Workbooks.Open(MyFolder & "\" & MyFile)
*Batch Run is a Boolean function*
'*** 1. Calls Import Data Macro, which Imports the Data ***'
Call Import_new_data(Batch_Run, oWbk)
'*** 2. Calls Data Collector Macro, which Analyses the Data ***'
Call Data_Collector(Batch_Run)
'*** 3. Calls Report Production Macro, which Produces Report ***'
Call Report_Production_Sub(Batch_Run)
ContinueLoop:
MyFile = Dir
'**^^ Here is where the Macro breaks after completing a full first iteration** !
Loop
What essentially the macro does, it picks up data from the opened file, closes the file and then analyses it, before creating a report out of it. It should then move on the second file in the folder and perform the same operation.
While the first file gets opened fine, and analysed as it should, the problem arises moving on to the second file. The variable MyFile in fact picks up a 'Ghost' file named ".." which then throws an error of course as it does not exist. Doing some research I have found out this may relate to the Directory path.
Any help would be super appreciated!
Calling the Dir function with parameter starts a search for matching files. If nothing is specified as second parameter, is will search only regular files (no directories, no hidden files etc).
Any following calls to Dir (without parameter) will continue the last search initiated by a Dir(with parameter).
The .. you get as result of the Dir within your loop is not a file, it's a folder (up directory). You will get this only when you started a Dir with option vbDirectory as second parameter. As this parameter is missing in your code, I would strongly assume that anywhere in your code (that is not displayed) a new Dir-search is started (which destroys the search results of a previous Dir-search).
Update: If you need to check if a folder exists but don't want to destroy your Dir-Loop, you could use the FileSystemObject. The FileSystemObject is usefull for several things concerning files and folders.
if CreateObject("Scripting.FileSystemObject").FolderExists("<enter your path>") then

"Kill" / "FileCopy" leads to permission denied

I'm having a problem with my Access VBA macro which for some reason is breaking on those lines with error "Permission Denied [Run-time error 70]:
sOutputFile = CurrentProject.Path & "\Output Files\Recon\" & sDate & " " & sClient & " Cash Recon.xlsx"
sTemplateFile = CurrentProject.Path & "\Temp Files\Template_Listed.xlsx"
If Dir(sOutputFile) <> "" Then Kill sOutputFile
FileCopy sTemplateFile, sOutputFile
What's getting "pointed out" directly is the "Kill sOutputFile" phrase.
It is worth to mention, that I do not have any of the files open, I have full access to the directories, and not long ago (before declaring sOutputFile and sTemplateFile) they've been both cleared.
Any help is much appreciated and I'm willing to share more of my code if needed.
Edit: Also, from time to time, the macro goes to the next line and breaks at the FileCopy instead.
The logic is not quite right in my opinion, please try the following (FileCopy should be inside an If...End If):
sOutputFile = CurrentProject.Path & "\Output Files\Recon\" & sDate & " " &
sClient & " Cash Recon.xlsx"
sTemplateFile = CurrentProject.Path & "\Temp Files\Template_Listed.xlsx"
If FileExists(sOutputFile) Then
Kill sOutputFile
FileCopy sTemplateFile, sOutputFile
End If
And this is the FileExists function:
Public Function FileExists_1(sFileName As String) As Boolean
Dim obj_fso As Object
Set obj_fso = CreateObject("Scripting.FileSystemObject")
FileExists_1 = obj_fso.fileExists(sFileName)
Set obj_fso = Nothing
End Function
What was the issue in my case, was that I previously used the macro, but the full ran failed. After trying to run it again after few adjustments (not related to the code I posted here), the above issue was happening. All just because I had the file still open somewhere in my excel's memory, hence the file couldn't be deleted.
Thanks for all the contributions guys. You're amazing as always!

Running RScript in VBA

I'm trying to create a VBA script that run RStudio script.
i tried using the Shell() command or the Run oShell at VBA, but the best thing i mange on doing is open the RStudio script, not making it to run automatically.
By the way, the RStudio script create a csv file which i will use.
this is the VBA script i use right now:
Sub RunRStudio()
Dim path As String
path = ThisWorkbook.path & "\Test.R"
Set oShell = CreateObject("WScript.Shell")
oShell.Run "RStudio " & path
shell ("RStudio " & path)
End Sub
How can i run this RStudio script automatically from VBA?
Thanks.
I had the same problem. Thank you, because your code helped me to find the solution.
This code, with a little change, it works to open the window of Rstudio, but it doesn't work to run the script. You need to use "RScript", not "RStudio".
You can try this to run your code:
Sub RunRTest()
Dim path As String
path = """C:\Program Files\R\R-3.5.2\bin\RScript.exe""
""C:\Folder\YourScriptName.R"""
Set oShell = CreateObject("WScript.Shell")
oShell.Run path
End Sub
Or:
path_file = ThisWorkbook.path & "\YourScriptName.R"
path = """C:\Program Files\R\R-3.5.2\bin\RScript.exe"" " & path_file & ""
if you have the path of your file in other var.
I hope to help someone!

How to open a file and make it default in VBA

I am trying to make "python.py" to open in notepad each time...I have got the code that does that but how to make it as default..so next time if the user wants to open the python file in notepad, it should open in notepad all the time using VBA and only after the code is excecuted...please find the code below for opening a python file in notepad..
Shell "notepad C:\Users\stackoverflow\Desktop\python.py", vbNormalFocus
You could try a VBA macro attached to a button that does this. But I am unsure if this is what you are asking for.
Sub LetterChecklist()
Dim strPath As String
Dim strProgram As String
strPath = "\\aw\data\Letters\2099_Correspondence\Incoming Letters\.pdf"
strProgram = "C:\Program Files (x86)\Adobe\Acrobat 11.0\Acrobat\Acrobat.exe"
Call Shell("""" & strProgram & """ """ & strPath & """", vbNormalFocus)
End Sub

Pass parameter\variable from .vbs to .bat

I'm trying to pass a variable from a VBS to BAT but i'm getting "The system cannot find the file specified"
Here is my vbs :
Option Explicit
Dim strFile
strFile = SelectFile( )
If strFile = "" Then
WScript.Echo "No file selected."
Else
WScript.Echo """" & strFile & """"
End If
Function SelectFile( )
Dim objExec, strMSHTA, wshShell
SelectFile = ""
strMSHTA = "mshta.exe ""about:" & "<" & "input type=file id=FILE>" _
& "<" & "script>FILE.click();new ActiveXObject('Scripting.FileSystemObject')" _
& ".GetStandardStream(1).WriteLine(FILE.value);close();resizeTo(0,0);" & "<" & "/script>"""
Set wshShell = CreateObject( "WScript.Shell" )
Set objExec = wshShell.Exec( strMSHTA )
SelectFile = objExec.StdOut.ReadLine( )
Dim wshShelll
Set WshShelll = Wscript.CreateObject("WScript.Shell")
WshShelll.Run "C:\Users\nbendjelida\Desktop\email.bat" & SelectFile
Set objExec = Nothing
Set wshShell = Nothing
Set wshShelll = Nothing
End Function
here is my bat :
"C:\Program Files\Microsoft Office\Office12\Outlook.exe" /eml %1
do you have any idea ?
I repeat the right answer of sachadee with more details to get this question removed from the list of unanswered questions.
Run Method must be called with first parameter being the command to execute with the parameters exactly as when entering the command in the command line window. The examples on the referenced Microsoft help page have also a space character after the command Notepad.
The command line required to call the batch file with a file name as first parameter is:
C:\Users\nbendjelida\Desktop\email.bat name_of_selected_file
But the Windows script host code line
WshShelll.Run "C:\Users\nbendjelida\Desktop\email.bat" & SelectFile
builds the string for the command to run as
C:\Users\nbendjelida\Desktop\email.bat name_of_selected_file
because of the missing space character.
The problem is solved with the correct Windows script host code line
WshShelll.Run "C:\Users\nbendjelida\Desktop\email.bat " & SelectFile
because of the space charater between name of batch file and name of selected file.
If name of selected file contains 1 or more spaces, it is necessary that either variable SelectFile contains already a double quote at beginning and at end, or the necessary double quotes are added on concatenating the command string.
Example with entire batch file name also containing a space character:
Dim FileName
FileName = "%TEMP%\Any File.txt"
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run """%USERPROFILE%\Desktop\My Batch File.bat"" """ & FileName & """"
The batch file My Batch File.bat on desktop of current user containing
#echo %0 %*
#pause
outputs for example on Windows 7
"C:\Users\username\Desktop\My Batch File.bat" "C:\User\username\AppData\Local\Temp\Any File.txt"
or on English Windows XP
"C:\Documents and Settings\user name\Desktop\My Batch File.bat" "C:\Documents and Settings\user name\Local Settings\Temp\Any File.txt"
which are the expected results for the command string.
(Yes, a user name can contain a space character although Microsoft recommends not to use a space character in user name, see Microsoft page Creating User and Group Accounts.)