UDF循环引用

时间:2016-03-07 05:25:55

标签: excel vba circular-reference

我有一个创建几个UDF的任务,主要是将销售数据与基准进行比较,然后根据前一个工作表上返回的相同值返回一个整数。我遇到了臭名昭着的循环错误,这对我来说没有意义,因为虽然我指的是VBA中禁止使用的单元格地址,但它只是在另一张表格的上下文中。

如果我启用迭代计算,它可以工作,但有时它继续迭代,只是将返回值向上输出。这会影响整个工作簿。我觉得我在这里错过了一些简单的东西,但我缺乏明确了解VBA的经验。如果某人有一个我可能会忽略的快速简单修复,我会非常感激。

我关于智慧,并且使用Apache POI使用xlwings或Java在Python中执行此操作。考虑一下这是我放弃VBA的冰雹玛丽传球。有什么想法吗?

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

1 个答案:

答案 0 :(得分:0)

在UDF中引用其他工作表时,您必须小心获得预期的工作表。您的所有引用都应该是合格的,否则它们将默认为您可能不符合预期的内容。

例如:

oldValue = Worksheets(sheet - 1).Range(callCell).Value

与:

相同
oldValue = ActiveWorkbook.Worksheets(sheet - 1).Range(callCell).Value

因此,如果包含您的公式的工作簿不是活动工作簿,那么您的结果可能不是您所期望的。

一些建议编辑:

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