无论如何,我可以为函数中的单元格指定值/名称吗?
谢谢
修改
很抱歉不清楚,这是我的要求。
我有一个用户定义的函数(= MyFunction()),可以从excel表调用。因此,当用户单击按钮时,我还有一个菜单按钮,我需要调用所有函数调用= MyFunction()。
我的计划是在MyFunction()内部,为调用单元格指定名称rerefence并将其存储在vba中。所以我可以有一系列的单元名称。然后,当单击菜单按钮时,我可以调用这些单元格引用。
请帮助我实现这一目标。有没有更好的方法来保持细胞参考?
答案 0 :(得分:1)
编辑:
啊,现在我明白了。 最简单的方法是制作一个虚假的参数:MyFunction(ByVal r As Variant)
,并且,无论何时在工作表上使用此函数,都要提供与参数完全相同的单元格:=MyFunction(A1)
。单击菜单项时,将A1中的值更改为任何值,并且所有MyFunction都将重新计算。
或者,您可以在函数体中使用Application.Volatile
。这样,每次更改任何打开的工作簿中的任何单元格时,它都会重新计算。
你也也可以使用模块级集合来存储引用,但Excel有时会重置项目,从而丢失模块级变量。如果你有足够的勇气尝试:
Option Explicit
Private RefsToCalculate As New Collection
Public Function MyFunction() As Long
Static i As Long
i = i + 1
MyFunction = i
If TypeOf Application.Caller Is Excel.Range Then
On Error Resume Next
RefsToCalculate.Add Application.Caller, Application.Caller.Address
On Error GoTo 0
End If
End Function
Public Sub MenuButtonClicked()
Dim i As Long
For i = 1 To RefsToCalculate.Count
RefsToCalculate(i).Dirty
Next
End Sub
答案 1 :(得分:0)
“我有一个用户定义的函数(= MyFunction()),可以从excel表调用。因此,我还有一个菜单按钮,我需要调用所有函数调用= MyFunction() ,当用户点击按钮时。“
这可以轻松完成,无需创建缓存来存储一系列单元格。但是,您需要小心计算方法。我相信下面的代码确保您的范围将始终计算,但是:(1)如果calc方法不是手动的,那么Excel最终控制计算的内容,时间和原因,因此它也可能重新计算其他单元格。 (2)同样,我相信无论使用何种计算方法,我都相信它可以保证使用您的函数重新计算所有单元格,但我没有测试下面的表格和半自动计算方法。
以下代码提供了两种方法:
(1) - 重新计算包含公式的所有单元格:优点是您跳过循环及其中的代码,缺点是您可能会强制重新计算比您真正需要的更多单元格。
(2) - 构建一系列兴趣和重新计算范围:缺点是构建该范围可能需要一些严肃的计算工作。优点是,如果calc方法设置为手动,那么我相信Excel只会重新计算该范围内的单元格。
我猜选择取决于您需要解决的问题的具体细节。
“我的计划是在MyFunction()内部,为调用单元格指定一个名称rerefence并将其存储在vba中。所以我可以有一个单元格名称数组。然后我可以在菜单按钮时调用这些单元格引用点击“。
如果你真的想要遵循这种方法,或者你肯定需要为你描述的目的创建一个单元格的缓存,那么这可以做到,尽管是初步的,它甚至可以以这样的方式构建在Excel会话之间保留。然而,这需要更多的工作,更先进的方法,它仍然是非常基本的。国际海事组织,这个问题明显有些过分。更糟糕的是,每次更新单元时都必须调用代码,以确保缓存保持最新,这可能会对性能产生很大的影响。至于GSerg的建议:这种方法 - 正如他自己提到的 - 并没有给你任何真正的控制缓存本身的生命。这是,每次到达缓存时,您都必须检查Excel是否已将其擦除,如果是这种情况,则重建它。
结论:我建议您不要缓存细胞。相反,我建议您尝试按需查找需要重新计算的单元格,并以最佳方式强制重新计算这些单元格。还是不相信?在这种情况下,使用Application.Caller.Address
(参见下面的代码)来检索调用函数的单元格的地址。
备注:在Excel 2003中实施和测试。包含C#样式的注释符号用于格式化。
Option Explicit
Public Sub ReEvaluateMyFunction()
On Error GoTo Handle_Exception
Dim targetCells As Range
Dim targetCell As Range
Dim rangeToRecalc As Range
/*'Workbook and worksheet names
'hard-coded for the example*/
Set targetCells = Application _
.Workbooks("Book1") _
.Worksheets("Sheet1").UsedRange _
.SpecialCells(xlCellTypeFormulas)
If targetCells Is Nothing Then Exit Sub
/*'You can narrow down the range if you know
'more about the function's return type, e.g.:
'.SpecialCells(xlCellTypeFormulas, xlNumbers)
'.SpecialCells(xlCellTypeFormulas, xlTextValues)
'OPTION 1: re-calculate all cells in the range
'Remark: unless calc method is set to "Manual", which
'should give you full control, I think there's no
'guarantee that other cells will not be recalculated*/
If Application.Calculation = xlCalculationManual Then
//'Use to force recalculation if calc mode is manual
targetCells.Calculate
Else
//'Use this to force recalculation in other cases
targetCells.Dirty
End If
Set targetCells = Nothing
Exit Sub
/*'OPTION 2: create a range specific to your
'function and recalculate that range*/
For Each targetCell In targetCells
If targetCell.Formula = "=MyFunction()" Then
If rangeToRecalc Is Nothing Then
Set rangeToRecalc = targetCell
Else
Set rangeToRecalc = Union(rangeToRecalc, targetCell)
End If
End If
Next targetCell
//'Same comments as before
If Application.Calculation = xlCalculationManual Then
rangeToRecalc.Calculate
Else
rangeToRecalc.Dirty
End If
Set rangeToRecalc = Nothing
Set targetCell = Nothing
Set targetCells = Nothing
Exit Sub
Handle_Exception:
Set rangeToRecalc = Nothing
Set targetCell = Nothing
Set targetCells = Nothing
MsgBox "An error has been found: " + Err.Description, vbCritical
End Sub
Public Function MyFunction() As String
MyFunction = Application.Caller.Address
End Function