I have a task with creating a couple UDF's mainly to compare sales figures against a benchmark and then return an integer based on the same value which was returned on a previous sheet. I've run into a the infamous circular error which makes no sense to me because while I am referring to the address of the cell which is a no-no in VBA, it's only in the context of another sheet.
If I enable iterative calculations, it works but then on occasion the it continues to iterate and just jacks the return value up. Which affects the entire workbook. I feel like I'm missing something simple here but I lack the experience with VBA to know explicitly. If someone has a quick easy fix that I might be overlooking I'd much appreciate it.
I'm about at wits and and going to just do this in Python using xlwings or Java using Apache POI. Consider this my hail mary pass at giving up on VBA. Any ideas?
Function tier1(Sales As Double) As Integer
'Constant Declaration
'Change these to alter benchmark values
Const BENCH As Double = 133000#
Const VARIANCE As Double = 0.9
'Variable Declaration
Dim callCell As String
Dim sheet As Integer
Dim oldValue As Integer
Dim returnValue As Integer
'Assigns Values to callCell & sheet
sheet = ActiveSheet.Index
callCell = Application.Caller.Address
If sheet > 1 Then
oldValue = Worksheets(sheet - 1).Range(callCell).Value
Else
oldValue = 0
End If
Select Case Sales
Case Is >= BENCH
Select Case oldValue
Case Is > 0
returnValue = oldValue - 1
Case Is > 2
returnValue = 2
Case Else
returnValue = 0
End Select
Case Is < BENCH
returnValue = oldValue + 1
If Sales > (BENCH * VARIANCE) And returnValue > 2 Then
returnValue = 2
End If
End Select
tier1 = returnValue
End Function
Have to be careful when referring to other sheets within a UDF that you get the sheet you expect. All your references should be qualified, otherwise they will default to something which might not be what you expect.
For example:
oldValue = Worksheets(sheet - 1).Range(callCell).Value
is the same as:
oldValue = ActiveWorkbook.Worksheets(sheet - 1).Range(callCell).Value
so if the workbook containing your formula isn't the active workbook, your results are likely to not be what you expect.
A few suggested edits:
Function tier1(Sales As Double) As Integer
'Constant Declaration
'Change these to alter benchmark values
Const BENCH As Double = 133000#
Const VARIANCE As Double = 0.9
'Variable Declaration
Dim callCell As Range
Dim sheet As Integer
Dim wb As Workbook
Dim oldValue As Integer
Dim returnValue As Integer
Set callCell = Application.Caller
Set wb = callCell.Worksheet.Parent
sheet = callCell.Worksheet.Index
If sheet > 1 Then
oldValue = wb.Worksheets(sheet - 1).Range(callCell.Address).Value
Else
oldValue = 0
End If
Select Case Sales
Case Is >= BENCH
Select Case oldValue
Case Is > 0
returnValue = oldValue - 1
Case Is > 2
returnValue = 2
Case Else
returnValue = 0
End Select
Case Is < BENCH
returnValue = oldValue + 1
If Sales > (BENCH * VARIANCE) And returnValue > 2 Then
returnValue = 2
End If
End Select
tier1 = returnValue
End Function
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.