Functions vs Sub Procedures - function

I am new to vbscript and trying to use the below code with a Function and then a Sub Procedure. I am confused as to why I have to "call" the function as it should itself return the value without calling the function. Please see the below pieces of code - one with Function and the other one with Sub Procedure.
Function -
Systemutil.Run"C:\Program Files\Internet Explorer\iexplore.exe","www.gmail.com"
Function tester()
Set tester=Description.Create
tester=Browser("title:=Gmail").Page("title:=Gmail").WebButton("html id:=next").GetROProperty("Name")
print tester
End Function
Call tester
If I don't call the function, it doesn't return anything.
I have used function name as a variable to output the value.
Sub Procedure-
Systemutil.Run"C:\Program Files\Internet Explorer\iexplore.exe","www.gmail.com"
Sub tester()
Set X=Description.Create
X=Browser("title:=Gmail").Page("title:=Gmail").WebButton("html id:=next").GetROProperty("Name")
print X
End Sub
Call tester
My question is why doesn't the first script work without calling the Function.

The first part of your code only defines your function. It doesn't execute the code in it yet.
Whether it returns a value or not is irrelevant. If you want the code in your function or sub to execute, you must call it.

Related

Access VBA: Passing Form/Subform name to a Function?

I am attempting to pass a form/subform name to a function without success. The function steps thru each .Control on the subform and performs a simple set of look-ups & actions. My code works as expected with the Form/Subform name hard coded; I am looking for a more generic approach.
Getting a type mismatch error on the function call, with and without quotes.
Example:
'Function Call
call AuditChanges("forms![someForm]![someSubForm]")
'Audit Function
Sub AuditChanges(thisForm as form)
Dim ctl As Control
Dim strTest as string
For each ctl in thisForm.controls
strTest = ctl.Value
'do some stuff
Next ctl
end sub
Any suggestions for proper syntax to pass the form/subform info?
Thanks!
Your sub call is all kinds of weird:
The likely cause of your error is the quotes. You're currently passing a string to your function containing "forms![someForm]![someSubForm]"
Furthermore, you shouldn't use parentheses when you're not receiving a return value (so never when calling a sub).
Also, the Call keyword has been deprecated a long time ago.
And you likely want to pass the form object, and not the subform control object
Try calling your sub like this:
AuditChanges forms![someForm]![someSubForm].Form
(Never had this many comments on one line of code before)

Calling sub from another module

I have a simple Function Test() in Module1 and a Sub SubName() in Module2. I'm trying to call SubName() from Function Test(). When I type:
Call Module2.SubName
and exit the raw, I'm getting an error:
Compile Error: Expected: identifier
When I just type Module2 and put Stop, it offers me the name of the SubName in Module2. So it sees it, but looks like is missing something in syntax. I can't figure out what.
Some related links :
MSDN-Calling Sub and Function Procedures
SO-Calling a Sub in VBA
SO-What does the Call keyword do in VB6?
Solution to your question :
Either use Call SubName or just SubName.
Testing:
After some testing, I've been able to break the code. The error is NOT the same you get, but maybe this will bring us closer to solution.
Picture from VBA:
The solution is simple: just use the statement
SubName
and it'll be called.
Few clarifying remarks:
No need to use the Call statement. If you do however, you need to use Call SubName()
If you call any sub with parameters, use SubName Param1 - or call Call SubName(Param1). Don't use Subname(Param1)- if param1 is an object, this will pass it's default property to the sub, not the object (e.g. Subname (Range("A1")) will pass the value of the cell to the sub - but not the Range object - Subname Range("A1") will pass the Range object.
You can also use Module2.SubName - however this is only required, if you have multiple SubName sub in different modules

VBA close access after all functions finished

I have got vba which I am running from a batch that starts a macro to execute them, I am trying to close down access once all the functions have finished however making a new function and placing "Application.Quit" is closing the application before the functions have finished.
Anyone have any ideas?
Thanks,
Simon
Edit:
Public Function finish()
Application.Quit
End Function
Put a timer loop in your code to put the DB to sleep and give it time for the functions to run.
First, put this just under the Option Compare or Option Explicit line in any MODULE (NOTE: it must be in a proper module, and not a form's module):
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Then your function should look like this:
Public Function finish()
Dim X as Integer
For X = 1 To 10
Sleep 1000
DoEvents
Next X
Application.Quit
End Function
Honestly, I don't understand what exactly you are doing so that your application closes before all your functions have finished.
If you want to execute some functions and then close the app, there are two ways how you can do it:
Put several RunCode actions in the macro, each one executing one of your functions and the last one executing Application.Quit.
Write a "runner" function that executes all the others and then quits:
Public Function F1()
'do stuff
End Function
Public Function F2()
'do stuff
End Function
Public Function Finish()
Application.Quit
End Function
'execute this function from the macro:
Public Function Runner()
F1
F2
Finish 'or directly call "Application.Quit" here instead
End Function
No matter which of these ways you choose, Access executes the functions in the specified order, one after the other...and it shouldn't close before everything is finished!
If it does, I suppose you're doing something different.
As already suggested by shahkalpesh in his comment - show us more code, then.

Calling a Function from Macro Design In Access

I have written some sql queries, some sub procedures and have some saved imports.
Now I am trying to use the Macro Design in Access to provide a run button which will run these objects sequentially.
However I dont see any command for running a sun procedure, I can see OpenVisualBasicModule and Runcode.
OpenVisualBaicModule is only opening my sub procedures and Run Code is asking for a function only.
I created a function with all the sub procedure call inside. But thats not working while individually all of them work.
Any suggestion what to do.
Make sure your VBA code is placed inside a Function (not a SUB, that won't work).
Create your function like:
Function DoSomething()
'Do your stuff
End Function
Or if you want to execute a Sub, just create a Function that calls your sub, like:
Function DoSomething()
Call YourSub()
End Function
Inside the Macro Design, add the 'RunCode' action (Macro Commands > RunCode) and call your function:
DoSomething()
And voila, you're done.
As you are already using code, the Macro seems unnecessary. In the Property Sheet for the Button, find the OnClick row and type in there:
=YourFunctionName()
(this also has to be a Function, not a Sub-procedure; this is a peculiarity of Access)
In your function you can use DoCmd to call any Macro Actions that you are using in your current Macro. Throw a MsgBox as the first line of your function to check that it is running.
You may be less familiar with the code, than a macro, but you will be able to add good comments to it, step-through and debug the code, use sensible error-handling - far easier than you can with a Macro.

Using variables as function names and parameters in VBA

I have the following variables in my VBA logic sFunctionName, sParam1, sParam2, sParam3 all string variables populated from a table. I would like to use those variables to call a function. I have tried using Application.Run(sFunctionName, sParam1) and the statement fails, However when i use Application.Run(sFunctionName) it works just fine. I have also tried Eval on someones suggestion with no luck. Can someone let me know what I am missing, or if i can even do what I am attempting to do? I appreciate any and all help.
Thanks,
J
#1. Regarding Eval(): Per Access's help files,
You can use the Eval function to
evaluate an expression that results in
a text string or a numeric value.
So, if your function resolves to text or numeric, then you're good to go.
i.e. Debug.Print Eval("Date()")
#2. I don't think your problem with Run() is with the actual function itself, but rather how you are applying it. I threw together some quick code. Does this help?
Function AddOne(What As Integer) As Integer
AddOne = What + 1
End Function
Function x()
Dim WhichFunc As String
WhichFunc = "AddOne"
Dim What As Integer
What = 1
x = Run(WhichFunc, What)
End Function
(Calling this with debug.print x in the Immediate Window will give you a 2)
Try running a method without braces, like:
Application.Run sFunctionName, sParam1