我在vba上尝试自己并没有成功。我想实现一个简单的函数,它将一系列单元格的内容总结为今年年初至今。不幸的是,当我调用该函数时,我得到了一个“循环引用”错误,我只是看不出原因。任何帮助将不胜感激。
Public Function til2day(r As Integer) As Long ''supposed to receive cell("row") as parameter
Dim c As Integer
Dim c1 As Integer
Dim c_here As Integer
Application.Volatile True
c_here = ActiveCell.Column
c = 0
c1 = 34 ''column contains 1/1/2013 date
Range("AH4:OM4").Activate ''contains a timeline
Do While ActiveCell.Offset(0, c).Value <> Date
c = c + 1
Loop
If ActiveCell.Offset(0, c).Value = Date Then
c = ActiveCell.Offset(0, c).Column
End If
til2day = Application.WorksheetFunction.Sum(Range(Cells(r, c1).Address, Cells(r, c).Address))
Range(Cells(r, c_here).Address).Activate
End Function
答案 0 :(得分:1)
在函数中使用“activate”是一个非常糟糕的主意;我无法解释完全为什么会这样,除了你在计算过程中改变单元格的选择。在以下情况中,这将导致问题:
multiple cells are being calculated with this function, and
you use `Application.Volatile`, and
you refer to the active cell inside your function, and
you allow multi-threaded calculation,
事情不会按照您期望的顺序发生,并且在某些时候,活动单元格将与您想象的不同。函数最终会引用它所在的单元格,并且您有一个循环引用。运行调试器时不会发生这种情况,因为它按定义运行为单个线程 - 这就是为什么你找不到问题的原因......
以下是对您的函数的建议重写 - 它不会激活单元格,但会尝试保持相同的功能:
Public Function til2day(r As Integer) As Long ''supposed to receive cell("row") as parameter
Dim c As Integer
Dim c1 As Integer
Dim dateRange as Range
Dime dateCell as Range
Application.Volatile True
c = 0
c1 = 34 ''column contains 1/1/2013 date
set dateRange = Range("AH4:OM4")
For Each dateCell in dateRange
If dateCell.Value = Date Then Exit For
Next dateCell
c = dateCell.Column
til2day = Application.WorksheetFunction.Sum(Range(Cells(r, c1).Address, Cells(r, c).Address))
End Function
注意:我试图重现您的功能的功能 - 但如果没有您正在使用的工作表的良好示例,以及您希望返回的值,则很难进行测试。请尝试在工作表上运行此操作 - 如果事情无法按预期运行,请告诉我。
另请注意,SUMIF
函数可以使用效果很好:
=SUMIF(range, criteria, sum_range)
在您的情况下,请使用
=SUMIF($AH$4:$OM$4, "<=" & NOW(), $AH18:$OM18)
其中“18”是您需要的任何行(当您将公式拖到另一行时,由于$4
绝对引用,它将继续引用日期行,但计算由于$AH18:$OM18
中的相对行引用而对另一行求和。
使用此功能的示例(简化范围......)
正如您所看到的,该函数仅在6月15日这样做之后才对C到F列进行求和。