Why doesn't this VBScript automation work? [duplicate] - vbscript

I am getting the 800A0414 error in lines 7 and 12 of this script:
Module Module1
Dim p
Sub Main()
CreateObject("Wscript.Shell").Run("program.bat", 0, True)
p = Process.GetProcessesByName("program")
If p.Count > 0 Then
WScript.Sleep(300000)
Else
CreateObject("Wscript.Shell").Run("program clean up.bat", 0, True)
End If
End Sub
Private Function WScript() As Object
Throw New NotImplementedException
End Function
End Module
I am trying to run a batch script, that starts a process, then wait until the process terminates, then run another batch script. I also do not want any command boxes being shown. If their is a easier way please let me know.
Thanks for your help

When you enclose a procedure's argument list in parentheses, you must use the Call keyword:
Call CreateObject("WScript.Shell").Run("program.bat", 0, True)
If you omit the Call keyword, you must also drop parentheses:
CreateObject("WScript.Shell").Run "program.bat", 0, True

To complete what's been said before:
When Call keyword is used to call a procedure (i.e. sub or function) the arguments must be enclosed in parentheses, except when the procedure has no arguments in which case the parentheses are optional. For example all the statements:
Call test()
Call test
Call test(1,2)
are valid, but not this one:
Call test 1
When calling a procedure without using the Call keyword, the parentheses can only be used when either the procedure has zero or one argument or the procedure has a return value (i.e. is a function) and its value is used in the same statement. For example all the statements:
test()
test(1)
test(1,2)
a = test
a = test(1,2)
a = test(test(1,2),2)
are valid, except the third one which has more than one argument. In case it's not clear, the inner call of "test" in the last statement is valid because its return value is used as an argument to another call.
Note that whenever parentheses is used in this text, it is meant to imply the possible comma-separated values as well.

Seems to me this is a VB.NET, not VBScript code.
You have Shell function in VB.NET (and other methods).
Anyway, Run returns any error code returned by the program, and if you
store that result in a variable, you can use parentheses in this case.
Dim lResult As Long
lResult = CreateObject("Wscript.Shell").Run("program.bat", 0, True)
The rest was answered by #Helen.

Related

Is there a reason a call to Split() should work in one instance and not another? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 days ago.
This post was edited and submitted for review 3 days ago.
Improve this question
I'm writing a script (vbscript) to generate Components that represent code modules (or whatever you'd call the abstraction of a C++ Class for C) in C. Each Component will have Elements for all the structs and enumerations in each module, as well as an interface for the defined functions in the module.
A separate Python script is extracting all of the pertinent information from the source and header files and storing them in a separate file, in a format that is easy for vbscript to deal with (a previous version was directly parsing the code in EA via vbscript, one file at a time, but the limitations of InStr were too great and the pull of Python's regular expressions package were also too great.
My script is working fine for enumerations and structs, and is working fine for functions in the interface--until I start adding Parameters to the Method elements.
One particular call to Split() is silently crashing the script. The call is verbatim to several other calls that are working perfectly fine, and the error box that I get when I execute that line in Debug mode is wordless, with only an OK button and a blue 'i' icon.
Here's a function that contains a call to Split() where the call is working correctly:
Function CreateStructs()
dim structsEnd
structsEnd = false
do while not structsEnd
line = file.ReadLine()
splitLine = Split(line, "#")
Select Case splitLine(0)
Case "STRUCT BEGIN"
CreateStruct splitLine(1)
Case "STRUCTURES END"
structsEnd = true
End Select
loop
End Function
And here's where it's not working:
Function CreateFunct(functionName, ByRef functionList, ByRef functPosition)
dim newFunction as EA.Method
dim newParams as EA.Collection
dim newParam as EA.Parameter
dim position, functEnd, access, returnType
dim newFunctionStereotype, newFunctionReturnType
functEnd = false
line = file.ReadLine()
newFunctionStereotype = Split(line, "#")(1)
line = file.ReadLine()
newFunctionReturnType = Split(line, "#")(1)
set newFunction = functionList.AddNew(functionName, newFunctionReturnType)
newFunction.Stereotype = newFunctionStereotype
newFunction.Pos = functPosition
do while not functEnd
line = file.ReadLine()
splitLine = Split(line, "#")
Select Case splitLine(0)
Case "ARGUMENTS BEGIN"
'CreateArguments newFunction
Case "FUNCT END"
functEnd = true
End Select
loop
newFunction.Update()
End Function
Both calls are within the do while blocks. The variables line and splitLine are "globally" defined in a separate script file that has been !INC'd
I'm at a loss for what to do and any help is greatly appreciated.
Edit: The variable being split is not empty when the silent crash happens, and the file being read from is not at EOF.

vbscript Type mismatch error when calling function

I am running into the Type Mismatch error when I attempt to call a function I created.
Example:
Function DoThis(paramA, paramB, paramC)
If paramA = "Something" Then
DoThis = DoSomething
ElseIf paramA = "This" Then
DoThis = DoSomethingDifferent
Else
DoThis = DoThisOtherThing
End If
End Function
Dim result: result = DoThis(valueA, ValueB, ValueC)
Can anyone see what my mistake could be? Other functions are working correctly. I have double checked the spelling by actually copying and pasting the function name where I call it. I have verified that the function name is not used anywhere else, i.e., as a constant or something else.
Note that when debugging this the ValType for all arguments is vbString. Also I am never able to enter the function, so it is not like I am debugging the function, enter it and then get the type mismatch.
ty.
VBScript has only one data type called a Variant. A Variant is a special kind of data type that can contain different kinds of information, depending on how it is used. Because Variant is the only data type in VBScript, it is also the data type returned by all functions in VBScript.
There are some subtypes of data that a Variant can contain (e.g. Empty, Null, string, integer, object, array etc.) You can use some conversion functions to convert data from one subtype to another, if that conversion is not implicit in VBScript. Now, pay your attention to real, factual data subtype of True and vbTrue.
The True keyword (boolean literal) has a value (inner representation) equal to -1.
On the other hand, vbTrue is one of few built-in constants and, in despite of it's name, has a subtype of Integer! It's one of so-called Tristate Constants:
Constant Value Description
vbUseDefault -2 Use default from computer's regional settings.
vbTrue -1 True
vbFalse 0 False
I hope next code could make clear all above statements:
Wscript.Echo _
vbTrue, CStr( vbTrue), VarType( vbTrue), TypeName( vbTrue) , _
vbNewLine, True, CStr( True), VarType( True), TypeName( True)
However, used with If _condition_ Then ..., there are some particularities; in brief:
The Then part of the If ... statement conditionally executes groups of statements only when a single test If condition is not False, i.e. any non-zero number esteems to be true, not only -1. Therefore you are able to use whatever variable or expression (numeric or string) you choose as long as the result is numeric...
Summarizing: If _expr_ Then ... is the same as
If CBool(_expr_) Then ...
The reason why retval is retuning mismatch error because it has a numeric value and an alpha value and wsh does not like that.
A sure way to get a type mismatch error for the published code is to define DoSomething etc. as Subs (which seems probable, given the names).
I cannot explain why this was a problem, but today I reduced the function down to a simple boolean return value and I still got the type mismatch error.
So I then created a new function with the same parameters and such. When I changed the call to the new function the error goes away.
My original function with the simple boolean return:(MISMATCH ERROR)
Function IsInstalledCheck(valueToCheck, expectedValue, checkType)
IsInstalledCheck = vbFalse
End Function
My new function with the a simple return:(Works)
Function IsItemInstalled(valueToCheck, expectedValue, checkType)
IsItemInstalled = vbFalse
End Function
EDIT
Note that I had tried this with the standard True / False values as well. The solution was to simply recreated the same function with a new name and for whatever magical reason that worked. The function signature was the same, the order of variables, variable names, the test conditions, everything in the body of the new function is the same.

Cannot use parentheses when calling a Sub Error 800A0414 VBS

I am getting the 800A0414 error in lines 7 and 12 of this script:
Module Module1
Dim p
Sub Main()
CreateObject("Wscript.Shell").Run("program.bat", 0, True)
p = Process.GetProcessesByName("program")
If p.Count > 0 Then
WScript.Sleep(300000)
Else
CreateObject("Wscript.Shell").Run("program clean up.bat", 0, True)
End If
End Sub
Private Function WScript() As Object
Throw New NotImplementedException
End Function
End Module
I am trying to run a batch script, that starts a process, then wait until the process terminates, then run another batch script. I also do not want any command boxes being shown. If their is a easier way please let me know.
Thanks for your help
When you enclose a procedure's argument list in parentheses, you must use the Call keyword:
Call CreateObject("WScript.Shell").Run("program.bat", 0, True)
If you omit the Call keyword, you must also drop parentheses:
CreateObject("WScript.Shell").Run "program.bat", 0, True
To complete what's been said before:
When Call keyword is used to call a procedure (i.e. sub or function) the arguments must be enclosed in parentheses, except when the procedure has no arguments in which case the parentheses are optional. For example all the statements:
Call test()
Call test
Call test(1,2)
are valid, but not this one:
Call test 1
When calling a procedure without using the Call keyword, the parentheses can only be used when either the procedure has zero or one argument or the procedure has a return value (i.e. is a function) and its value is used in the same statement. For example all the statements:
test()
test(1)
test(1,2)
a = test
a = test(1,2)
a = test(test(1,2),2)
are valid, except the third one which has more than one argument. In case it's not clear, the inner call of "test" in the last statement is valid because its return value is used as an argument to another call.
Note that whenever parentheses is used in this text, it is meant to imply the possible comma-separated values as well.
Seems to me this is a VB.NET, not VBScript code.
You have Shell function in VB.NET (and other methods).
Anyway, Run returns any error code returned by the program, and if you
store that result in a variable, you can use parentheses in this case.
Dim lResult As Long
lResult = CreateObject("Wscript.Shell").Run("program.bat", 0, True)
The rest was answered by #Helen.

How to determine if code is executing as a script or function?

Can you determine at runtime if the executed code is running as a function or a script? If yes, what is the recommended method?
There is another way. nargin(...) gives an error if it is called on a script. The following short function should therefore do what you are asking for:
function result = isFunction(functionHandle)
%
% functionHandle: Can be a handle or string.
% result: Returns true or false.
% Try nargin() to determine if handle is a script:
try
nargin(functionHandle);
result = true;
catch exception
% If exception is as below, it is a script.
if (strcmp(exception.identifier, 'MATLAB:nargin:isScript'))
result = false;
else
% Else re-throw error:
throw(exception);
end
end
It might not be the most pretty way, but it works.
Regards
+1 for a very interesting question.
I can think of a way of determining that. Parse the executed m-file itself and check the first word in the first non-trivial non-comment line. If it's the function keyword, it's a function file. If it's not, it's a script.
Here's a neat one-liner:
strcmp(textread([mfilename '.m'], '%s', 1, 'commentstyle', 'matlab'), 'function')
The resulting value should be 1 if it's a function file, and 0 if it's a script.
Keep in mind that this code needs to be run from the m-file in question, and not from a separate function file, of course. If you want to make a generic function out of that (i.e one that tests any m-file), just pass the desired file name string to textread, like so:
function y = isfunction(x)
y = strcmp(textread([x '.m'], '%s', 1, 'commentstyle', 'matlab'), 'function')
To make this function more robust, you can also add error-handling code that verifies that the m-file actually exists before attempting to textread it.

Does a function in VBscript take variable number of arguments?

For example, if I have a function in VBscript:
Function sum(a, b, c)
sum = a + b + c
End function
Now, in the main, I make two variables and pass them into the function sum as the following:
Dim a : a = 1
Dim b : b = 2
Call sum(a, b)
Will this work or not, and why? Thanks.
It will not work, VBScript doesn't support optional arguments.
I'd use a function that takes an array of numbers instead vary number of arguments to getting sum.
Function sum(nums)
Dim i, out
For i = 0 To UBound(nums)
out = out + nums(i)
Next
sum = out
End function
Call sum(Array(1, 2, 3, 4))
According to this, VBscript does not support optional arguments. You can do what they suggest and pass null values to your function.
I hope this might help.
I use dictionary object to pass variables to function so I can add new arguments without the need for refactoring existing code.
dim params
set params = CreateObject("Scripting.Dictionary")
'...when I want to call a function
params.add "variable_name", value: params.add "variable_name_2", value ': ...
call fn_function_name(params)
'...declaring a function
function fn_function_name(byRef params_in)
'here I usually make sure that variable is of correct type, or that is set
params_in("variable_name") = fn_check(params_in("variable_name"), "number") ' fn_check is a separate function
' ... function code goes here ...
' in order to user external dictionary "params" multiple times, I empty dictionary before exiting the function. This is possible because I set it as a reference (byRef) instead of value
params_in.removeAll()
end function
VBScript doesn't support optional arguments or method overloading. You can pass in null values to your function call, however.

Resources