With VBA, it's easy to show precedents of the cell :
Sub ShowPrecedents() Dim s As String [a1] = "=$b$2*c3+d9^2/12" s = Range("a1").Precedents.Address MsgBox s End Sub
But when we compile this as an UDF,it won't work in worksheet:
Function MyPrecedents(ByRef MyCell As Range) As String MyPrecedents = MyCell.Precedents.Address End Function
If we input a formula "=MyPrecedents(A1)" in [B1],it will show "$A$1" instead of "$B$2,$C$3,$D$9". It returns only the address of MyCell! I t is not passed to the function as an argument ,What's wrong with it?
Furthermore, if we need the expression with orign data, a feasible method is to use "Worksheet_Change" event subroutine instead. (See F36 of http://club.excelhome.net/viewthread.php?tid=663427&pid=4519978&page=4)
Private Sub Worksheet_Change(ByVal Target As Range) Dim r As Range, r2 As Range, s As String, t As String s = Application.ConvertFormula(Target.Formula, xlA1, xlR1C1, xlRelative, [iv65536]) Set r = Target.Precedents If Not r Is Nothing Then For Each r2 In r t = r2.Address(0, 0, xlR1C1, , [iv65536]) s = Replace(s, t, r2.Value) Next Application.StatusBar = Target.Address(0, 0) & s End If End Sub
And after many tests,I found a way to use UDF at last.
Function MyFormula(ByVal Mycell As Range) Dim s$, t$, ms, m s = Application.ConvertFormula(Mycell.Formula, xlA1, xlR1C1, xlRelative, [IV65536]) With CreateObject("VBSCRIPT.REGEXP") .Global = True .Pattern = "R/[*[^/[]*/]C/[*[^/[]*/]" Set ms = .Execute(s) For Each m In ms t = Application.ConvertFormula(m, xlR1C1, xlA1, , [IV65536]) s = Replace(s, m, Range(t).Value) Next End With If s Like "*[a-zA-Z]*" Then MyFormula = "Err" Else MyFormula = s End If End Function