how to use `if` worksheet function in vba? - excel

My code is as follows:
Function my_if() As Boolean
my_if = Application.WorksheetFunction.If(True, True, False)
End Function
But I am getting #VALUE as a result. Why is that?

If isn't one of the functions in the WorksheetFunction object. Rather than writing your own my_if function, just use the built-in VBA function IIF instead. Or, you could do:
Function my_if() As Boolean
my_if = IIf(True, True, False)
End Function

Related

how to use missing and boolean values in the same case statement in excel vba

In VBA (MS Excel 2016): How to combine missing and boolean values in a select case statement? The argument val could be passed as a boolean or not passed at all, or passed as something else unexpected.
public sub test(optional val as variant)
select case val
case true, isMissing(val): msgbox("foo")
case else: msgBox("bar")
end select
end sub
Above results in run-time error '13': Type mismatch on the "case true, isMissing(val):" line.
The preference is to use the same case statement allowing for multiple values to result in showing msgbox("foo"). Also would prefer not to set a default value for the optional argument on the function definition.
Each of these calls should work:
call test // expect msgBox("foo")
call test("abc") // expect msgBox("bar")
call test(true) // expect msgBox("foo")
While not very elegant, another option might be:
Public Sub test(Optional val As Variant)
Select Case IIf(IsMissing(val), True, val)
Case True: MsgBox ("foo")
Case Else: MsgBox ("bar")
End Select
End Sub
Found a work around. VBA allows for setting a default value when an optional argument is missing. So this worked:
public sub test(optional val as variant = true)
select case val
case true: msgbox("foo")
case else: msgBox("bar")
end select
end sub
Results as expected:
call test // "foo"
call test("abc") // "bar"
call test(true) // "foo"
Still would like to know if there is a way to do this on the case statement. Maybe there isn't and this is the correct approach.

Using Application.Run to evaluate Worksheet function passed as string

I have essentially a simple syntax question concering Application.Run. I want to write a bit of code where I pass a UDF a string coantaining the name of a worksheet function, e.g. 'iserror' or some other UDF returning boolean. The function will then be exectued for each cell within the passed range and do something depending on result.
However, I have not been able to work out the proper Syntax. Error Messages Change along with my Trials, but non are particularly helpfull. e.g.:
?hrCull(Range("Data!A1:B10"),"Worksheetfunction.iserror", False)
(Error message in German, I'll try my best to translate, but it probably won't 100% match the English Version):
Runtime error 1004:
The macro 'Worksheetfunction.iserror' can not be exectued. The macro may not be available in this worksheet or macros have been deactivated.
Of course, macros have not been deactivated, but it isn't really a macro anyway. Also tried without the leading 'Worksheetfunction', same error message.
In my code the call Looks like this:
Public Function hrCull(r As Range, func As String, Optional invert As Boolean = False) As Range
Dim c As Range
Dim selector As Boolean
...
selector = Application.Run(func, c)
...
end function
I omitted code not relevant.
So what is the proper Syntax?
Misc:
- I'm Aware that I can not assert that the passed function returns a boolean.
- Excel 2016 on Windows 7
A solution using CallByName:
selector = CallByName(Application.WorksheetFunction, "IsError", VbMethod, c)
Lose the WorksheetFunction. prefix, Evaluate doesn't like it as Evaluate is for worksheet functions.
In your function, use:
selector = Application.Evaluate(func & "(" & c.Address & ")")
To test, use:
Debug.Print hrCull(Range("A1"), "ISERROR")
I think you'd be better off declaring your own Enum and adding the functions that you want into this. Then execute them using built in syntax instead of trying to evaluate a string
Public Enum xlSheetFunction
xlIsError
End Enum
Public Function hrCull(r As Range, func As xlSheetFunction, Optional Invert As Boolean = False) As Range
Dim selector As Boolean
Select Case func
Case xlIsError
selector = WorksheetFunction.IsError(r)
End Select
Debug.Print selector
Set hrCull = r
End Function
Public Sub test()
Debug.Print hrCull(Range("A1"), xlIsError)
End Sub

How to call a bloomberg function inside a UDF

I want to call a bloomberg function inside a UDF, hence, I can't use
Cells(x,y).Formula = bdp(equity, field)
Which is what I normally see. I've tried Aplication.Run and WorkSheetFunction without success, are there other ways so that I can call this function?
A UDF isn't setting formulas, nor is it even setting a value - it is returning a value - so just return the value of the Bloomberg function as the result of your UDF.
For example:
Public Function MyUDF(....) As Variant
'...
'whatever calcs you are doing to determine "equity" and "field"
'(or maybe they are parameters)
'...
MyUDF = bdp(equity, field)
End Function

Excel VBA - GoalSeek cannot be called from User Defined Function

Here is the User Defined Function where I'm calling GoalSeek.
I put this into module, however it does not solve for the given context.
Function FindYield() As Double
Worksheets("Sheet1").Range("N8").GoalSeek _
Goal:=0, _
ChangingCell:=Worksheets("Sheet1").Range("N9")
End Function
The same setup works as a Sub.
You need to use a Sub rather than a Function. Functions can only return a value to the cell in which they reside.

Pushing 2-d Variant data into FormulaArray

I originally had a VBA function that returned a two dimensional variant array:
Public Function SplitIntoCells(some_data As String) As Variant()
End Function
I used the Formula array syntax to call it from another vba function:
Public Function MyWrapper() as Variant
MyWrapper = SplitIntoCells("somestring")
End Function
From Excel, if I select a big enough range and then do:
=MyWrapper()
followed by CTRL+SHIFT+ENTER, the data is nicely split into every individual cell in that range.
However in order to automate that, if I change MyWrapper to:
Public Function MyWrapper()
ActiveSheet.Range("A1:E20").Select
Selection.FormulaArray = SplitIntoCells("somestring")
End Function
The above doesn't work. I see nothing being displayed in Excel.
What am I doing wrong?
Update:
Just for testing, if I slightly modify MyWrapper() to:
Public Function MyWrapper()
Dim variant_temp() as Variant
variant_temp = SplitIntoCells("somestring")
ActiveSheet.Range("A1:E20").Select
Selection.FormulaArray = variant_temp
End Function
variant_temp predictably has the 2-d array after returning from SplitIntoCells but the subsequent Selection.FormulaArray still has nothing in it even after the assignment. I am sure I am missing something blindingly obvious.
A VBA user-defined function cannot modify the cell or range it's being called from: it can only return a value.

Resources