「我有一個用戶自定義函數(= MyFunction的()),它可以從一個Excel工作表被稱爲因此,我也有一個菜單按鈕在哪裏。當用戶單擊按鈕時,需要調用所有調用= MyFunction()的函數。「
這可以輕鬆完成,無需創建緩存來存儲一系列單元格。但是,您需要注意計算方法。我相信下面的代碼可以確保你的範圍總是被計算出來,但是:(1)如果calc方法不是手動的,那麼Excel最終控制什麼是計算的,什麼時候和爲什麼,因此它可能重新計算其他單元格。 (2)同樣,我相信它保證用你的函數重新計算所有的單元格而不管計算方法如何,但是我沒有測試下面的表格和半自動計算方法的代碼。
下面的代碼提供兩種方法:
(1) - 重新計算包含公式的所有單元:的優點是,跳過一個循環,並在其中的代碼,缺點是,你可能迫使許多的重新計算比你真正需要更多的細胞。 (2) - 建立一個範圍的興趣和重新計算範圍:缺點是建立該範圍可能需要一些嚴重的計算工作。優點是,如果calc方法設置爲manual,那麼我相信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
這與http://stackoverflow.com/questions/2259035/how-to-get-address-of-cell-which-calls-a-vba-functions-in-a-excel-愚弄的人表 – 2010-02-21 03:42:23
不,我需要知道如何爲函數的調用單元賦一個名稱,而不是如何從調用單元對象中檢索值 – nimo 2010-02-21 03:53:21
啊,現在它更清晰了。看到答案。 – GSerg 2010-02-21 11:46:17