2009-04-12 19:29 顯示鄰格的計算公式
更新內容:
- 可跨工作表參照。
- 相關話題 [遍歷儲存格的前導參照儲存格]。
請下載更新檔案 -2009.4.12
問題來源:YAHOO奇摩知識+-Excel如何讓A3顯示B3內的計算公式
假設B1內容為(=5+2) 顯示為(7),A1內容則自動顯示出(5+2),B2內容為(=6+8)顯示為(14),A2內容則自動顯示出(6+8)。
這個很簡單,用下列自定義函數就可以了
Function myTran(Rng As Range) As String
myTran = Replace(Rng.Formula, "=", "", 1, 1)
End Function
可是呢!如果接著B3內容為(=B1+B2)顯示為(21),A3內容要自動顯示出(7+14)而不是(B1+B2)呢?
原來也想繼續使用自定義函數來達成,因功力不夠而作罷(後來 [太陽之子] 有做了一個出來,已經收錄在範例檔Module2中,歡迎參考。另 [Dune in mud 小沙魚 in mu] 也發表了一個,也收錄在範例檔Module4中,真是一山比一山高),改以程序配合工作表的CHANGE事件, 來自動顯示計算公式。其中主要是利用 DirectPrecedents 屬性找出公式參照到本工作表的哪些儲存格,然後將這些儲存格的值替換掉公式的位址達成需求。
DirectPrecedents 屬性
傳回 Range 物件,該物件代表由儲存格的所有直接前導參照組成的範圍。如果儲存格有若干前導參照,該範圍就可能是多重選定範圍 (Range 物件的聯合)。唯讀 Range 物件.
expression.DirectPrecedents
expression 必選。此運算式會傳回 [套用至] 清單中其中一個物件。
備註
附註 DirectPrecedents 屬性只能用於使用中的工作表,並且無法追蹤遠端的參照。
附註 DirectPrecedents 屬性只能用於使用中的工作表,並且無法追蹤遠端的參照。
範例
此範例將選取 Sheet1 上儲存格 A1 的直接前導參照儲存格。
Worksheets("Sheet1").Activate
Range("A1").DirectPrecedents.Select
此範例將選取 Sheet1 上儲存格 A1 的直接前導參照儲存格。
Worksheets("Sheet1").Activate
Range("A1").DirectPrecedents.Select
另外考慮到可能有其他的儲存格參照到此公式的儲存格,也要一併更改其顯示的公式,所以也用到DirectDependents 屬性將它找出來,然後遞迴呼叫自己即可以將所有參照到此公式的儲存格的所有儲存格其顯示的公式更新。
DirectDependents 屬性
傳回 Range 物件,該物件代表由儲存格的所有直接從屬儲存格組成的範圍。如果儲存格有若干從屬參照,該範圍就可能是多選定範圍 (Range 物件的聯合)。唯讀 Range 物件。
expression.DirectDependents
expression 必選。此運算式會傳回 [套用至] 清單中其中一個物件。
expression 必選。此運算式會傳回 [套用至] 清單中其中一個物件。
備註
附註 Direct Dependents 屬性只能用於使用中的工作表,並且無法追蹤遠端參照。
附註 Direct Dependents 屬性只能用於使用中的工作表,並且無法追蹤遠端參照。
範例
此範例將選取 Sheet1 上儲存格 A1 的直接從屬儲存格。
Worksheets("Sheet1").Activate
Range("A1").DirectDependents.Select
此範例將選取 Sheet1 上儲存格 A1 的直接從屬儲存格。
Worksheets("Sheet1").Activate
Range("A1").DirectDependents.Select
參考程式碼如下:
- 一般模組 Module1
Option Explicit
'本程式碼假設在B欄輸入公式...數值計算公式
'則在A欄顯示不帶"="開頭的公式字串
'引數 Rng 為輸入公式的儲存格
Sub ShFormula(Rng As Range)
Dim thePrece '前導範圍之位址
Dim Addresses '前導範圍位址之集合
Dim theCell As Range '單一前導儲存格
Dim theFor As String '公式字串
With Rng '對於輸入公式的儲存格
'首先檢查有否發生循環參照, 避免程序陷入無窮堆疊
If Not .Worksheet.CircularReference Is Nothing Then
MsgBox "發生循環參照於" & .Worksheet.CircularReference.Address
Exit Sub
End If
'若不是公式, 將前面A欄清空
If Not .HasFormula Then
.Previous = ""
Exit Sub
End If
'取的公式字串並且刪除前面=號
theFor = Replace(.Formula, "=", "", 1, 1)
theFor = Replace(theFor, "$", "")
'取得當前工作表的前導範圍, 未處理跨工作表或外部參照
On Error Resume Next
Addresses = Split(.DirectPrecedents.Address(0, 0), ",")
'測試是否已經有取得任何前導範圍
If Err.Number = 0 Then
'遍歷各前導範圍
For Each thePrece In Addresses
'遍歷個範圍中之儲存格
For Each theCell In Range(thePrece)
'將公式的位址換成該位址的值
theFor = Replace(theFor, theCell.Address(0, 0), .Worksheet.Range(theCell.Address(0, 0)), 1, 1)
Next
Next
End If
.Previous = theFor '將字串賦予左邊的儲存格
Err.Clear
Addresses = Null '清空變數Addresses, 因為下面還要用
'是否有從屬儲存格
On Error Resume Next
Addresses = Split(.DirectDependents.Address(0, 0), ",")
'若有的話須將從屬儲存格的左邊公式顯示一併處理
If Err.Number = 0 Then
For Each thePrece In Addresses
For Each theCell In Range(thePrece)
'不需再寫程序, 遞迴呼叫即可
ShFormula theCell
Next
Next
End If
End With
End Sub - 工作表模組 Sheet1
Option Explicit
'利用工作表的CHANGE事件, 自動化
Private Sub Worksheet_Change(ByVal Target As Range)
With Target.Cells(1)
If .Column = 2 Then
ShFormula Target.Cells(1)
End If
End With
End Sub



