Using VBA with Access 2010, I have a sub:
Public Sub setInterest(account As String, dmonth As Integer)
...somecode...
End Sub
And I am calling it with
setInterest("myAccount",3)
And I get syntax errors.
Modifying the sub to only take one argument and leaving out the 3 gives no errors, the problem is only when I have 2 arguments.
When using multiple arguments, you can either write:
setInterest "myAccount", 3
Or
Call setInterest("myAccount", 3)
In both examples you can name the arguments:
setInterest account:="myAccount", dmonth:= 3
I add this answer, for Why your syntax works with one argument ?
Public Sub setInterest(account As String)
'...somecode...
End Sub
setInterest ("myAccount")
Note :
When there is not any , between ( and ), VBA thinks it's a formula and exactly one argument.
When formula calculate the result will be like this:
Dim str As String
str = ("TEST")
Debug.Print str
[Output:]
TEST
Related
I am familiar with this post: How to Return a result from a VBA Function but changing my code does not seem to help.
I want to write a simple function in VBA that allows to lowercase an input sentence. I wrote this:
Private Function Converter(inputText As String) As String
Converter = LCase(inputText)
End Function
Sub test()
Dim new_output As String
new_output = Converter("Henk")
MsgBox (new_output)
End Sub
I tried following the advice I found at another stackoverflow post. I made me change this:
Private Function Converter(inputText As String)
Set outputText = LCase(inputText)
End Function
Sub test()
Dim new_output As String
Set new_output = Converter("Henk")
MsgBox (new_output)
End Sub
However, now I get an error that an object is required. Why does it require an object now? I dont get it...
Set outputText = LCase(inputText)
The Set keyword is reserved for Object data types. Unlike VB.NET, String in VBA is a basic data types.
So you dont Set a variable to a string. Drop the second version of your code altogether. It doesn't make sense. That "advice" was probably in another context.
To fix your first version
1- Assign the returned result to the name of the function Converter
2- It would be beneficial to specify explicitly the return type, as String. Currently it is a Variant that always embeds a String, so better make it explicit:
' vvvvvvvvv
Private Function Converter(inputText As String) As String
Converter = LCase(inputText) ' <------------ assign return to name of function
End Function
I just figured out that setting optional parameters requires "Call" infront of the method.
Public Sub Test()
Call abc("aaa")
Call abc("aaa", 2)
abc("aaa") ' is fine
abc("aaa", 2) ' is a syntax error
End Sub
Function abc(a As String, Optional iCol As Long = 3)
MsgBox (iCol)
End Function
Can you add a "why does this make sense?" to my new information?
Greetings,
Peter
Edit: PS the function abc for no other use than to simplify the question.
Documentation
Call is an optional keyword, but the one caveat is that if you use it you must include the parentheses around the arguments, but if you omit it you must not include the parentheses.
Quote from MSDN:
You are not required to use the Call keyword when calling a procedure.
However, if you use the Call keyword to call a procedure that requires arguments, argumentlist must be enclosed in parentheses. If you omit the Call keyword, you also must omit the parentheses around argumentlist. If you use either Call syntax to call any intrinsic or user-defined function, the function's return value is discarded.
To pass a whole array to a procedure, use the array name followed by empty parentheses.
Link: https://msdn.microsoft.com/en-us/library/office/gg251710.aspx
In Practice
This means that the following syntaxes are allowed:
Call abc("aaa")
Call abc("aaa", 2)
abc "aaa", 2
abc("aaa") ' <- Parantheses here do not create an argument list
abc(((("aaa")))) ' <- Parantheses here do not create an argument list
The following syntaxes are not allowed:
Call abc "aaa", 2
abc("aaa", 2) ' <- Parantheses here create an argument list
Function Return Values
This doesn't take effect when using a function to get a return value, for example if you were to do the following you need parentheses:
Function abc(a As String, Optional iCol As Long = 3)
abc = iCol
End Function
'## IMMEDIATE WINDOW ##
?abc("aaa", 2) 'this works
?abc "aaa, 2 'this will not work
?Call abc "aaa", 2 'this will not work
?Call abc("aaa", 2) 'this will not work
If you are using Call on a Function then consider changing it to a Sub instead, functions are meant to return a value as in the cases above.
Something like this would work:
Option Explicit
Public Sub Test()
Dim strText As String
strText = "E"
Call Abc(strText, 3)
Call Abc(strText, 2)
Abc (strText)
' Abc (strtext,5)
Abc strText, 2
Abc strText
End Sub
Public Sub Abc(strText As String, Optional iCol As Long = 5)
Debug.Print iCol
End Sub
Absolutely no idea why the commented code does not work...
Call is an optional keyword, as already described in detailed in the answer above.
for your second option
abc("aaa", 2) ' is a syntax error
Just use:
abc "aaa", 2
Note: there is little use to have a Function if you don't return anything, you could have a regular Sub instead.
to have a Function that return a String for instance (just something made-up quick):
Function abc(a As String, Optional iCol As Long = 3) As String
abc = a & CStr(iCol)
End Function
and then call it:
Public Sub Test()
d = abc("aaa", 2)
MsgBox d
End Sub
I want a list of possible values to show up when I call a function func1. I found a way to achieve this in VBA via ENUM, but that doesn't work in a worksheet. So I've created a function e that will convert certain strings into the right enum value. Unfortunately, I can't find a way to call this function func1 with either a string or the enum value without getting an error or losing functionality. Here's what I've got so far:
Enum eLanguages
evEnglish = 2
evItalian = 3
'and so on
End Enum
Function e(vString)
Select Case vString
Case "english", "eng", "en", "e"
e = evEnglish
Case "italian", "italien", "it", "i"
e = evItalian
Case Else
e = vString '(= will keep the value if it's already a number)
End Select
End Function
Option 1: Shows the list of possible values when typing in VBA, but won't work for string inputs
Function func1(var As eLanguages)
func1 = e(var)
End Function
Sub test1()
MsgBox func1(evEnglish) 'Will result in 2 (through the enum and the e function)
MsgBox func1("e") 'Type 13 error
End Sub
Option 2: Gives the right result but I don't get the list of possible values within VBA
Function func2(var)
func2 = e(var)
End Function
Sub test2()
MsgBox func2(evEnglish) 'Will result in 2 (through the enum and the e function)
MsgBox func2("e") 'Will result in 2 (through the e function)
End Sub
Note: Calling either of the two functions like this will give the right result, but obviously I'm not keen on having to write e() everytime I call the function:
MsgBox func1(e("e"))
So do you have any suggestions on how to ignore the Type 13 error or how to include an "any string allowed" option in the ENUM declaration?
Thanks in advance.
#CinyMeister 's idea is interesting. A slight variation -- make both arguments optional and use if - then - else, together with the IsMissing function to merge the two arguments back into one: Function func3(Optional x As eLanguages, Optional y As String)
Dim var As Variant
If IsMissing(x) Then
var = y
Else
var = x
End If
func3 = e(var)
End Function
Sub test()
MsgBox func3(evEnglish)
MsgBox func3(, "it")
End Sub
Even with a large number of parameters, this sort of thing will work -- when you invoke the function in the VBA editor you can tab through the options by repeatedly pressing the comma key. Parameters that are given by enumerations will evoke intellisense drop-downs. Other parameters will hopefully have descriptive names.
I just had another idea, but I don't think it would work as a superelegant solution either.
I could have 2 functions, one for Excel, one for VBA. Like that:
Function funcV(var As eLanguages)
funcV = SOMETHING
End Function
Function funcE(var)
funcE= funcV(e(var)) '(which is "SOMETHING")
End Function
The question is whether I would remember which of my many functions have a sister function. There's no way to capture the Type 13 error as an "on error" event and redirect automatically, is there?
VBA Beginner here.
I am trying to pass an array of strings from a subroutine to a function which will then modify each string in the array. However I get the "Type:array or user-defined type expected" error message.
I have tried redefining different data types for the array so it is aligned with the data type entered in the function but to no avail.
Hope you can help! THank you so much!
Below is the dummy code:
Sub text()
Dim haha() As Variant
haha = Array("Tom", "Mary", "Adam")
testing (haha())
MsgBox Join(haha, " ")
End Sub
Function testing(ByRef check() As String) As String()
Dim track As Long
For track = LBound(check) To UBound(check)
check(track) = check(track) & " OMG"
Next
End Function
In orignial code, a string is not the same variant (I believe they both would need to be variant? someone can verify), you dont need the brackets after testing, only need brackets if you are setting to another value e.g.
haha2 = testing(haha())
Below code should be ok
Sub text()
Dim haha()
haha = Array("Tom", "Mary", "Adam")
testing haha()
MsgBox Join(haha, " ")
End Sub
Function testing(ByRef check()) As String
Dim track As Long
For track = LBound(check) To UBound(check)
check(track) = check(track) & " OMG"
Next
End Function
You have a few errors in your code:
There are two ways of invoking methods:
1) with Call keyword - in this case you must give all the parameters in brackets:
Call testing(haha)
2) without Call keyword - in this case you just give your parameters after the name of function:
testing haha
In your code you combined both of them and this is syntax error.
If you pass an array as a parameter to function you don't need to put brackets like that: testing (haha()).
The proper syntax is:
testing(haha)
Function testing requires as a parameter an array of String type, you cannot pass object of other type instead since it causes compile error Type mismatch. Currently you are trying to pass variable haha which is of Variant type.
You can change the type of haha variable to array of strings (to avoid the error described above):
Dim haha() As String
However, in this case you cannot assign the value of function Array to it, since the result of this function is of Variant type.
You would have to replace this code:
haha = Array("Tom", "Mary", "Adam")
with this:
ReDim haha(1 To 3)
haha(1) = "Tom"
haha(2) = "Mary"
haha(3) = "Adam"
A couple of suggestions to improve your code:
Dim haha() As String
You define the type of the entry in the array, not the array itself. Use the way mentioned by mielk to fill the array.
Function Testing(byref check as variant) As String
This will avoid problems with undefined variables. Not clear why you feel that the function should return a string though. Maybe even convert to a Sub instead.
I would like to be able to only pass q as argument to a function, so that the user does not have to enter a string "q".
I have a function defined in a module
Function doThis(val As Variant)
MsgBox CStr(val)
' Here is a comparison of val with other strings and additional code
End
I call it from my worksheet:
=doThis(q)
And the messagebox returns
Error 2029
I have tried with String and Boolean as value type as well, but only variant fires the function.
Is it possible to receive a q as argument?
Quite simple. First create a Defined Name for q
Secondly in a standard module:
Function doThis(val As Variant)
MsgBox CStr(val)
doThis = ""
End Function
Finally in the worksheet: