I'm trying to send a string variable to command prompt using vba excel.
I'm using following code:-
code_name = "xyz.c"
version = "def"
label = "1XDFO"
'open command prompt
Dim oWsc As Object
Set oWsc = CreateObject("WScript.Shell")
Dim oExec As Object
'save config spec in a text file
Set oExec = oWsc.Exec("perl F:\My_work\hello_world.pl code_name version label")
While oExec.Status <> 1 ' Wait for process
Sleep 1000
Wend
While calling perl script at line
"oWsc.Exec("perl F:\My_work\hello_world.pl code_name version label")"
i want to send original contents of string variable code_name,version,label; but its sending the variable names as it is and not the content; Can anyone help me with this?
Thanks in advance.
How can an external script (Perl or any other one) understand that what you are sending are variables and read their content? You have to send just the content:
Set oExec = oWsc.Exec("perl F:\My_work\hello_world.pl " & code_name & " " & version & " " & label)
Clarification 1: VBA or .NET or any other Microsoft language, do not "read variables inside strings", like other languages do, PHP for example.
Clarification 2: even a language capable of reading variables inside strings cannot manage what is being done "outside its framework". If you call a PHP script from an external program, you cannot call it as you are doing now because PHP does not have any control on what the external program does and thus on its variables.
Related
how do I add a path to a code where "HERE_HAS_TO_BE_A_PATH" is. When I do, Im getting an error message. The goal is to be able to specific the path where is the final text file saved.
Thanks!
Here is a code:
Dim newFile As IO.StreamWriter = IO.File.CreateText("HERE_HAS_TO_BE_A_PATH")
Dim fix As String
fix = My.Computer.FileSystem.ReadAllText("C:\test.txt")
fix = Replace(fix, ",", ".")
My.Computer.FileSystem.WriteAllText("C:\test.txt", fix, False)
Dim query = From data In IO.File.ReadAllLines("C:\test.txt")
Let name As String = data.Split(" ")(0)
Let x As Decimal = data.Split(" ")(1)
Let y As Decimal = data.Split(" ")(2)
Let z As Decimal = data.Split(" ")(3)
Select name & " " & x & "," & y & "," & z
For i As Integer = 0 To query.Count - 1
newFile.WriteLine(query(i))
Next
newFile.Close()
1) Use a literal string:
The easiest way is replacing "HERE_HAS_TO_BE_A_PATH" with the literal path to desired output target, so overwriting it with "C:\output.txt":
Dim newFile As IO.StreamWriter = IO.File.CreateText("C:\output.txt")
2) Check permissions and read/write file references are correct:
There's a few reasons why you might be having difficulties, if you're trying to read and write into the root C:\ directory you might be having permissions issues.
Also, go line by line to make sure that the input and output files are correct every time you are using one or the other.
3) Make sure the implicit path is correct for non-fully qualified paths:
Next, when you test run the program, it's not actually in the same folder as the project folder, in case you're using a relative path, it's in a subfolder "\bin\debug", so for a project named [ProjectName], it compiles into this folder by default:
C:\path\to\[ProjectName]\bin\Debug\Program.exe
In other words, if you are trying to type in a path name as a string to save the file to and you don't specify the full path name starting from the C:\ drive, like "output.txt" instead of "C:\output.txt", it's saving it here:
C:\path\to\[ProjectName]\bin\Debug\output.txt
To find out exactly what paths it's defaulting to, in .Net Framework you can check against these:
Application.ExecutablePath
Application.StartupPath
4) Get user input via SaveFileDialogue
In addition to a literal string ("C:\output.txt") if you want the user to provide input, since it looks like you're using .Net Framework (as opposed to .Net Core, etc.), the easiest way to set a file name to use in your program is using the built-in SaveFileDialogue object in System.Windows.Forms (like you see whenever you try to save a file with most programs), you can do so really quickly like so:
Dim SFD As New SaveFileDialog
SFD.Filter = "Text Files|*.txt"
SFD.ShowDialog()
' For reuse, storing file path to string
Dim myFilePath As String = SFD.FileName
Dim newFile As IO.StreamWriter = IO.File.CreateText(myFilePath) ' path var
' Do the rest of your code here
newFile.Close()
5) Get user input via console
In case you ever want to get a path in .Net Core, i.e. with a console, the Main process by default accepts a String array called args(), here's a different version that lets the user add a path as the first parameter when running the program, or if one is not provided it asks the user for input:
Console.WriteLine("Hello World!")
Dim myFilePath = ""
If args.Length > 0 Then
myFilePath = args(0)
End If
If myFilePath = "" Then
Console.WriteLine("No file name provided, please input file name:")
While (myFilePath = "")
Console.Write("File and Path: ")
myFilePath = Console.ReadLine()
End While
End If
Dim newFile As IO.StreamWriter = IO.File.CreateText(myFilePath) ' path var
' Do the rest of your code here
newFile.Close()
6) Best practices: Close & Dispose vs. Using Blocks
In order to keep the code as similar to yours as possible, I tried to change only the pieces that needed changing. Vikyath Rao and Mary respectively pointed out a simplified way to declare it as well as a common best practice.
For more information, check out these helpful explanations:
Can any one explain why StreamWriter is an Unmanaged Resource. and
Should I call Close() or Dispose() for stream objects?
In summary, although streams are managed and should garbage collect automatically, due to working with the file system unmanaged resources get involved, which is the primary reason why it's a good idea to manually dispose of the object. Your ".close()" does this. Overrides for both the StreamReader and StreamWriter classes call the ".dispose()" method, however it is still common practice to use a Using .. End Using block to avoid "running with scissors" as Enigmativity puts it in his post, in other words it makes sure that you don't go off somewhere else in the program and forget to dispose of the open filestream.
Within your program, you could simply replace the "Dim newFile As IO.StreamWriter = IO.File.CreateText("C:\output.txt")" and "newFile.close()" lines with the opening and closing statements for the Using block while using the simplified syntax, like so:
'Dim newFile As IO.StreamWriter = IO.File.CreateText(myFilePath) ' old
Using newFile As New IO.StreamWriter(myFilePath) ' new
Dim fix As String = "Text from somewhere!"
newFile.WriteLine(fix)
' other similar operations here
End Using ' new -- ensures disposal
'newFile.Close() ' old
You can write that in this way. The stream writer automatically creates the file.
Dim newFile As New StreamWriter(HERE_HAS_TO_BE_A_PATH)
PS: I cannot mention all these in the comment section as I have reputations less than 50, so I wrote my answer. Please feel free to tell me if its wrong
regards,
vikyath
I'm developing a MS Word macro which needs to open a file on a network drive and pass it the calling file's path as a parameter (i can then retrieve the parameters in the opened file using this method http://www.vbaexpress.com/forum/archive/index.php/t-21174.html).
What i am trying to achieve is the following:
1. Document X (any MS word document) calls document Y (macro document)
2. Document Y processes document X (using the Document object)
3. Document Y closes
The reason i am doing step 1 above is do that users don't have to deploy complex vba code (i am dealing with non IT literate users) and the ease of making updates and enhancements to the code if required.
The following code snippet opens the file with parameters:
Dim currentFilePath As String
currentFilePath = ThisDocument.Path & ThisDocument.Name
Dim MacroFilePath As String
MacroFilePath = ThisDocument.Path & "\Test.docm"
MacroFilePath = """" & MacroFilePath & """" & currentFilePath
Documents.Open (MacroFilePath)
The value of 'MacroFilePath' is gets setup like this (263 chars):
“\\XXXXXXXXXXXX\XX_XX\XXX_XXX XXXX procedural documentation\XX Design Support\Macros - DO NOT MOVE\Work in progress\Calling Document.docm” \\XXXXXXXXXXXX\XX_XX\XXX_XXX XXXX procedural documentation\XX Design Support\Macros - DO NOT MOVE\Work in progress\Test.docm
When I run the above code the error Run-Time '9105': String is longer than 255 characters occurs. I have tested the code where i moved the files to a shorter directory and it works. Is there a way to get around this or another way of achieving what i am trying to do?
Shorting the file paths by saving the documents elsewhere, changing the language i am programming in, or creating any kind of executable is not an option as i am in an enterprise environment.
X can open Y, then call a procedure in Y and pass in it's own path as a parameter.
You can use Application.Run to do this.
See:
https://msdn.microsoft.com/en-us/library/office/ff838935.aspx
Here's the example from that link:
Dim strTemplate As String
Dim strModule As String
Dim strMacro As String
Dim strParameter As String
strTemplate = InputBox("Enter the template name")
strModule = InputBox("Enter the module name")
strMacro = InputBox("Enter the macro name")
strParameter = InputBox("Enter a parameter value")
Application.Run MacroName:=strTemplate & "." _
& strModule & "." & strMacro, _
varg1:=strParameter
I have a code, in which I want to loop through files in a folder, check their built-in or custom document properties (without opening them), and later open those, which are meant to be open.
To do this, I'm using Shell and to set the folder I'm using Shell.Namespace.
The problem is with the Namespace, I guess. When I use a variable strSuborCesta for the path it doesn't work. When I print the variable strSuborCesta into immediate window and use the printed string inside the Shell.Namespace("....") it does work.
By it doesn't work I mean I get:
run-time error : 91 Object variable or With block not set
when I try to loop through the files in folder (which is not set in that case, so I understand why the error occurred, but don't understand why it's not accepting a string variable)
The path is correct in both ways. But I need it to be a variable, not a hardcoded string.
Where do I error?
Is there any better way, to check document properties (like comments, title, author, etc.) without opening the Excel files?
Below is the section (currently just in testing phase) that is giving me a hard time.
str[name of variable] variables are string data types. sFile, oShell, oDir are as Variants
'--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'get a root path
strPriecinokCesta = ThisWorkbook.Path 'path to this file
strPriecinokCesta = Left(strPriecinokCesta, Len(strPriecinokCesta) - (Len(strPriecinokCesta) - InStrRev(strPriecinokCesta, "\"))) 'root path is one level above this file
'--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'input files are in a subfolder
strSuborCesta = strPriecinokCesta & "Zdroje\"
strSuborPripona = "Formular_BD_kotolna*.xls" 'name of a file with extension
strSuborNazov = Dir(strSuborCesta & strSuborPripona) 'actual file name
'--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
'get access to the file system
Set oShell = CreateObject("Shell.Application")
Set oDir = oShell.Namespace(strSuborCesta) '<----this will produce an error. In contrast to using a hard coded string. Why?
For Each sFile In oDir.Items '<---- run time error 91 occurs on this line
Debug.Print test & " : " & oDir.GetDetailsOf(sFile, 24) 'comments
Next
Variable strSuborNazov should be a variant
Dim strSuborNazov as variant
oShell.Namespace(strSuborNazov)
https://msdn.microsoft.com/en-us/library/windows/desktop/bb774085(v=vs.85).aspx
I have an app which monitors a network location for new documents.
They can be word documents, PDF files, spreadsheets etc.
When a document is detected, it is copied to a local folder within c:\Temp.
What I need is for the document, once copied, to be sent to a specified (not default) printer.
Has anyone got any ideas on how I can achieve this?
Thanks!!
You may need to create a variety of functions to print your document. Like using LPR to print PDF or PostScript, Microsoft.Office.Interop for Word and Excel documents, and so on...
If it were me, I would use System.IO.Path.GetExtension(filename) to determine the file type and then call whichever function was most appropriate...or log that the file was not printable if the format was not handled.
Microsoft.Office.Interop
Using Microsoft.Office.Interop.Excel, you can call the PrintOutEx method on a Workbook or Worksheet and specify which printer to use.
See:
https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.worksheets.printoutex.aspx
and
https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._workbook.printoutex.aspx
With Microsoft.Office.Interop.Word you can set the ActivePrinter property of the Application and then use the PrintOut method on the Document.
See:
https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word._application.activeprinter.aspx
and https://msdn.microsoft.com/en-us/library/microsoft.office.interop.word._document.printout.aspx
LPR
I wrote a tool once that prints PDF and PostScript files. The code was something like:
'Set the IP address of the printer to use.
If printer1 Then
printserver = printer1Address
ElseIf printer2 Then
printserver = printer2Address
ElseIf printer3 Then
printserver = printer3Address
End If
'Use LPR to print the file.
Dim lprProcess As New Process()
With lprProcess.StartInfo
.UseShellExecute = False
.FileName = "CMD"
.Arguments = "/c LPR -s " & printserver & " -P P3 " & myNewFileName
End With
lprProcess.Start()
LPR is not a included by default in Windows 7 and above, but it is a cake-walk to turn on. See steps 1-3 on http://campus.mst.edu/cis/desktop/documentation/pc/win7_x64/lpr_printer/install.htm
I need to run a small piece of Java code (Java is the only option in this case)
I have the jar file in the VB.net resources as JSSMCL(the extension is not required to run it, of this I am sure :P) I know I use Path.GetFullPath(My.Resources.ResourceManager.BaseName)
but no mater how I do it it fails, I have tried so many ways i have lost count!
this is the command that I need to run:
java -cp "JSSMCL.jar" net.minecraft.MinecraftLauncher username false
You can use System.Diagnostics.Process class and its method to start/run the external process.
Refer to the following code part to run the Command using Process
Sub Main()
' One file parameter to the executable
Dim sourceName As String = "ExampleText.txt"
' The second file parameter to the executable
Dim targetName As String = "Example.gz"
' New ProcessStartInfo created
Dim p As New ProcessStartInfo
' Specify the location of the binary
p.FileName = "C:\7za.exe"
' Use these arguments for the process
p.Arguments = "a -tgzip """ & targetName & """ """ & sourceName & """ -mx=9"
' Use a hidden window
p.WindowStyle = ProcessWindowStyle.Hidden
' Start the process
Process.Start(p)
End Sub
EDIT:
Use the Coding part like below, may be it works
-jar "compiler.jar" --js_output_file="myOutput.min.js" --js="input1.js" --js="input2.js"
Have a look at this link for your problem