#value error returns with excel user defined function - excel

i have created user defined function to calculate football match results.
My Root Function looks that:
Function calculatePoints(personTypes As Range, matchesResults As Range) As Integer
calculatePoints = getAllPersonPoints(personTypes, matchesResults)
End Function
getAllPersonPoints function:
Private Function getAllPersonPoints(personTypes As Range, matchesResults
AsRange) As Integer
Dim x As Long
Dim y As Long
Dim isTheSurest As Boolean
getAllPersonPoints = 0
For x = 1 To personTypes.Rows.Count
For y = 1 To personTypes.Columns.Count
isTheSurest = isTheSurestResult(personTypes.Cells(x,
y).DisplayFormat.Interior.PatternColorIndex)
getAllPersonPoints = getAllPersonPoints +
getPoints(matchesResults.Cells(x, y).Value, personTypes.Cells(x, y).Value,
isTheSurest)
Next y
Next x
End Function
When i am trying to call this function by setting manually parameters: personTypes range and matchesResults ragne - everythink works fine.
But when i am trying to call it from sheet i got #VALUE error in selected cell.
But at function form there is correct result:
A have been trying to debug return value and always i got correct value. I have problem only with error in return cell.
Any ideas ?

The issue is that DisplayFormat object does not work with UDF's
See MSDN article
The usual solution to this is to evaluate the Conditional Format conditions to determine which one is active. For example, see cpearson.com

I resolved problem by code:
personTypes.Cells(x, y).Interior.ColorIndex
instead of:
personTypes.Cells(x,y).DisplayFormat.Interior.PatternColorIndex
This solution works.

Related

Range.Find-Function - different results for similar values

I have written a Function to return the Long name of a 3 character string, so in Worksheet "List" there's 2 columns:
Column 1: List Short
Column 2: List Long
Similar to a VLOOKUP, my function shall find the Short and return the Long name.
However, there's something really strange happening:
Line 683 has Short = "Hlm" - and the function returns the correct Long from Lists Column B
Line 684 has Short = "Hlm" - but the function returns a runtime error 91.
Function GetList(ByRef ListShort, DataSource As Workbook)
Dim Lists As Worksheet, ListShort As String
Set Lists = DataSource.Worksheets("Lists")
GetList = Lists.Cells.Find(ListShort, After:=Lists.Cells(1, 1), LookIn:=xlValues, SearchOrder:=xlByColumns).Offset(0, 1)
End Function
The error occurs in Line 4 of my code, runtime error 91 means that GetFile could not be declared.
Someone an idea what's the cause of this?
TIA! Marvin
Checked official documentation, revewed code w debugger, tried If commands to work around "Hml" value...

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

VBA #VALUE!" error while using a Function

Still one hair remaining... not for long
This :
Function Around(Compare As String)
Around = (Range(Compare).Value = Range(Compare).Offset(-1, 0).Value) Or (Range(Compare).Value = Range(Compare).Offset(1, 0).Value)
End Function
generates a #VALUE! in the cell that calls it
I cannot figure out why
Any clues ?
I think #Value error while accessing user defined function in VBA does not apply here.
I'm guessing you're typing the formula in like =Around(E8), when you need to type it in as =Around("E8") since Compare is a String:
If you want to type it without quotation marks, then you need to declare Compare as a Range and change some syntax:
Function Around(Compare As Range)
Around = (Compare.Value = Compare.Offset(-1, 0).Value) Or (Compare.Value = Compare.Offset(1, 0).Value)
End Function

(Excel) Pick formula criteria/logical etc from another cell(reference)

Im writing an If+Or function and would like to use several cell references for the different Logicals in the function, instead of writing each logical statements in the original if+or function. Any ideas of how to solve this? Hope im not too unclear here..
As example: instead of writing =If(or(A1=A2,A3=A4),A1,0) I would like to write out all different logical values in a list of cells, and the just write the original if+or formula like this: =IF(OR(B1),A1,0) where B1 contains the text "A1=A2,A3=A4"
Thanks for any help on this!
You can use the INDIRECT function.
For example, if the value in cell A6 is 10, INDIRECT("A6") = 10.
So basically you can write INDIRECT("A6")=INDIRECT("A7") instead of the A1=A2 condition in your IF formula.
If you want to have "A1=A2" in one cell, you can use LEFT and RIGHT.
Here is an example: https://docs.google.com/spreadsheets/d/157tRicA55TFKKOi86yYBQScnjaQE6fYxaCHFdZx4uUM/edit?usp=sharing
PS: this solution is for Google Sheets so the solution might differ a little if you're using Excel but that should work for Excel too.
You CANNOT Have It All
Instead of using =IF(OR(B1),A1,0) you have to use
e.g. =IFOR(B1,A1) (I prefer "" instead of 0, sorry)
or =IFOR(B1,A1,0) if you (prefer 0 instead of ""),
or change the ElseValue in the declaration to 0,
then you can use =IFOR(B1,A1) to get 0.
Function IFOR(IfOrCell As Range, ThenCell As Range, _
Optional ElseValue As Variant = "", _
Optional SplitDelimiter As String = ",") As Variant
'Description:
'Pending...
'Recalculation
Application.Volatile
'Variables
Dim arrIfOr As Variant
Dim iIfOr As Integer
Dim blnIfOr As Boolean
'The Array: The Split
If InStr(IfOrCell.Value2, SplitDelimiter) = 0 Then Exit Function
arrIfOr = Split(IfOrCell.Value2, SplitDelimiter)
'An Additional Split Introducing the Boolean
For iIfOr = LBound(arrIfOr) To UBound(arrIfOr)
If InStr(arrIfOr(iIfOr), "=") <> 0 Then
If Range(Split(arrIfOr(iIfOr), "=")(0)).Value2 _
= Range(Split(arrIfOr(iIfOr), "=")(1)).Value2 Then
blnIfOr = True
Exit For
End If
End If
Next
'Output
If blnIfOr = True Then
IFOR = ThenCell.Value2
Else
IFOR = ElseValue
End If
End Function

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