2016-03-07 28 views
0

我有一個任務,創建一對UDF,主要是將銷售數據與基準進行比較,然後返回一個基於上一張表返回的相同值的整數。我遇到了一個臭名昭着的循環錯誤,這對我來說毫無意義,因爲我指的是VBA中的單元格地址,它只在另一個表單的上下文中。UDF通函

如果我啓用迭代計算,它可以正常工作,但有時它會繼續迭代,只是將返回值拉高。這影響了整個工作簿。我覺得我在這裏錯過了一些簡單的東西,但我缺乏VBA的經驗來明確地知道。如果某人有一個快速簡單的解決方法,我可能會忽略我很欣賞它。

我想知道這個問題,並且只會在Python中使用xlwings或使用Apache POI的Java來執行此操作。考慮一下我的雹子瑪麗放棄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 

回答

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 
+0

謝謝你的添,我從來沒有想過這一點。 VBA對我來說似乎有點像伏都教。希望如果他們需要一個更深入的解決方案,我將能夠把它們變成更好的東西。 – grturner