Sub function Excel VBA - excel

Why would this be a syntax error? it is asking for an = sign
cyberlinkcompute("A1","B2")
private sub cyberlinkcompute ( a as string, b as string)
end sub
isnt a sub function something that does not need an =?
thanks in advance

Remove the parentheses or put the word Call in front of the procedure name

Its the function-like parentheses it dislikes so either;
cyberlinkcompute "A1","B2"
or less advisably:
call cyberlinkcompute("A1","B2")

Related

Possible syntax mistake? "Expecting =" In a Sub call from a UserForm

I want to call a Sub I declared at it gives a compilation error saying that it expects a =.
The Sub call is in a UserForm_Initialize event procedure.
The code is as follows.
In a module:
Public Sub FillCb(Ar() As String, Cb As ComboBox)
Cb.Clear
For I = 1 To Application.CountA(Ar)
Cb.AddItem (Ar(I))
Next I
End Sub
In the UserForm code:
Private Sub UserForm_Initialize()
LblDate.Caption = Date
FillCb(LibrosNoPrestados, CbLibro)
End Sub
This code is giving me error.
I analized the code line by line using the debugger and commenting the las line inside the Initialize event, and it works fine up to that point. The error is thrown at compile time in the
FillCb(LibrosNoPrestados, CbLibro)
The rest of the code is not needed here since as I said it works fine, but the syntax in that last line must be wrong and I can't see the mistake.
A VBA "feature". If you are calling a sub routine without the "Call" keyword then don't use parentheses, if you use the "Call" keyword then you need the parentheses.
Eg
Call FillCb(LibrosNoPrestados, CbLibro)
Or
FillCb LibrosNoPrestados, CbLibro
Here's Microsoft's documentation:
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/call-statement

Excel VBA - Use an existing string in called sub

I'm pretty new to this so apologies in advance
I'm half way through a userform in Excel and I'm trying to cut some fat off my code by using Call - I have 12 buttons that all do the same thing, the only difference is that each buttons sub is dependant on the buttons caption. My problem is that I can't figure out a way to use a String I've already declared in the Buttons Sub, then use it in the called Sub. I know you can do it, but my googling skills have failed me :(
Please could someone show me how to do this? Hope that all makes sense...
Here is a very small snippet of my code, but you get the jist:
Public Sub CommandButton4_Click()
Dim Name As String
Name = CommandButton4.Caption
Call Sort1
End Sub`
And the other one (Also tried this as function for the sake of trial and error)
Public Sub Sort1(Name As String)
Label11.Caption = Name
Sheets(Name).Select
End Sub
What you're referring to is passing an argument to another subroutine or function. Let's say you want to use a function a lot of times to get the first letter of a string. A sample of this is:
Function LeftOne(StrSample As String) As String
LeftOne = Left(StrSample, 1)
End Function
The above function can be used inside another function or subroutine provided you meet its requirement: StrSample. By declaring StrSample As String in the arguments field of the function, you are basically requiring that any calls to this should require a string to be passed to it. Anything else would throw an error.
The full line LeftOne(StrSample As String) As String can be read as: "I am function LeftOne. Pass me a string and I'll return to you a string after doing something with it." Note that the name StrSample is an arbitrary name.
Anyway, calling the above is as simple as:
Sub MsgInABox()
Dim StrToFeed As String
StrToFeed = "BK201"
MsgBox LeftOne(StrToFeed) 'Returns B.
End Sub
In your example, if you want to pass Name to Sort1, your attempt is absolutely correct.
Let us know if this helps.
You hat to give your sort1 procedure the parameter name.
call sort1(name)
or
call sort1(CommandButton4.Caption)

Is there a shorter way of appending information to an existing string?

Is there a shorter way of appending information to an existing string in vba than:
strExample = strExample & "Lorem Ipsum"
I've got a lot of these when compiling dynamic strings, and it'd save time and look neater in my code if there was a shorter way of typing this.
Thanks
No sorry that is not possible.
With vb.net you can use the operator &=.
But it is not available for vbscript.
You could set up a global string var and create a function to add on to just that string. It wouldn't save that much time coding, but it may be something that helps
Public strExample as String
Sub Main()
{do something}
AddTo("One")
{do something else}
AddTo("Two")
End Sub
Sub AddTo(str as String)
strExample = strExample & str
End Sub

Why is this VBA code wrong and how can I fix / avoid?

I currently have this code
Private Sub Worksheet_Change(ByVal Target As Range)
WorksheetChanged(Target, Range("AB3").CurrentRegion, Range("B18:B19"))
WorksheetChanged(Target, Range("AE3").CurrentRegion, Range("B20:B21"))
End Sub
But it throws me a "Compile Error: Expected =", I have no idea why and I don't know where an = would go, any help? Thank you in advance.
If you want to use brackets, you need to assign to a variable or in some cases, use Call, if you do not need to assign, skip the brackets:
WorksheetChanged Target, Range("AB3").CurrentRegion, Range("B18:B19")

Stop VBA Evaluate from calling target function twice

I am having trouble getting VBA's Evaluate() function to only execute once; it seems to always run twice. For instance, consider the trivial example below. If we run the RunEval() subroutine, it will call the EvalTest() function twice. This can be seen by the two different random numbers that get printed in the immediate window. The behavior would be the same if we were calling another subroutine with Evaluate instead of a function. Can someone explain how I can get Evaluate to execute the target function once instead of twice? Thank you.
Sub RunEval()
Evaluate "EvalTest()"
End Sub
Public Function EvalTest()
Debug.Print Rnd()
End Function
This bug only seems to happen with UDFs, not with built-in functions.
You can bypass it by adding an expression:
Sub RunEval()
ActiveSheet.Evaluate "0+EvalTest()"
End Sub
But there are also a number of other limitations with Evaluate, documented here
http://www.decisionmodels.com/calcsecretsh.htm
I don't know of a way to stop it, but you can at least recognize when it is happening most of the time. That could be useful if your computation is time consuming or has side effects that you don't want to have happen twice and you want to short circuit it.
(EDIT: Charles Williams actually has an answer to your specific quesion. My answer could still be useful when you don't know what data type you might be getting back, or when you expect to get something like an array or a range.)
If you use the Application.Caller property within a routine called as a result of a call to Application.Evaluate, you'll see that one of the calls appears to come from the upper left cell of of the actual range the Evaluate call is made from, and one from cell $A$1 of the sheet that range is on. If you call Application.Evaluate from the immediate window, like you would call your example Sub, one call appears to come from the upper left cell of the currently selected range and one from cell $A$1 of the current worksheet. I'm pretty sure it's the first call that's the $A$1 in both cases. (I'd test that if it matters.)
However, only one value will ever be returned from Application.Evaluate. I'm pretty sure it's the one from the second eval. (I'd test that too.)
Obviously, this won't work with calls made from the actual cell $A$1.
(As for me, I would love to know why the double evaluation happens. I would also love to know why the evaluator is exposed at all. Anyone?)
EDIT: I asked on StackOverflow here: Why is Excel's 'Evaluate' method a general expression evaluator?
I hope this helps, although it doesn't directly answer your question.
I did a quick search and found that others have reported similar behavior and other odd bugs with Application.Evaluate (see KB823604 and this). This is probably not high on Microsoft's list to fix since it has been seen at least since Excel 2002. That knowledge base article gives a workaround that may work in your case too - put the expression to evaluate in a worksheet and then get the value from that, like this:
Sub RunEval()
Dim d As Double
Range("A1").Formula = "=EvalTest()"
d = Range("A1").Value
Range("A1").Clear
Debug.Print d
End Sub
Public Function EvalTest() As Double
Dim d As Double
d = Rnd()
Debug.Print d
EvalTest = d + 1
End Function
I modified your example to also return the random value from the function. This prints the value a second time but with the one added so the second print comes from the first subroutine. You could write a support routine to do this for any expression.
I face the same problem, after investigation i found the function called twice because i have drop down list and the value used in a user defined function.
working around by the code bellow, put the code in ThisWorkbook
Private Sub Workbook_Open()
'set the calculation to manual to stop calculation when dropdownlist updeated and again calculate for the UDF
Application.Calculation = xlCalculationManual
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, _
ByVal Source As Range)
'calculte only when the sheet changed
Calculate
End Sub
It looks like Application.Evaluate evaluates always twice, while ActiveSheet.Evaluate evaluates once if it is an expression.
When the object is not specified Evaluate is equivalent to Application.Evaluate.
Typing [expression] is equivalent to Application.Evaluate("expression").
So the solution is to add ActiveSheet and to make that an expression by adding zero:
ActiveSheet.Evaluate("EvalTest+0")
After seeing there is no proper way to work around this problem, I solved it by the following:
Dim RunEval as boolean
Sub RunEval()
RunEval = True
Evaluate "EvalTest()"
End Sub
Public Function EvalTest()
if RunEval = true then
Debug.Print Rnd()
RunEval = False
end if
End Function
problem solved everyone.

Resources