merlionXX さん、少し、がんばってみました。
まず、関数名が長たらしいので、省略してみました。
丁寧に作り上げたつもりではいるのですが、まだ、ヘンなところが残っているかもしれません。一通り、いろんな複雑な式を含めて代入してみました。R1C1方式でも、A1方式でも使用可能です。R1C1方式の場合は、絶対参照で、A1方式では、相対参照で出力します。同じブック内なら、ブック名は出ませんが、違うブック名では、ブック名が表示されます。
>Functionというのを使うやり方にも興味がありますので
本来は、C言語で作ったほうが良いらしいのですが、私は良く知りません。VB でも作れるのですが、こちらは、あまり勝手が良くありません。Function は、良く出来たものなら、アドイン化してもよいのですが、臨時的なものは、標準モジュールです。なお、「値渡し」にする必要は、ワークシート用の場合は、ないと思います。
'-------------------------------------------------------------
Function BPRC(rng As Range) As String
'参照先のセルのアドレスを出すユーザー定義関数
Dim objRe As Object
Dim buf As String, buf1 As String, buf2 As String, buf3 As String
Dim buf4 As String, bufnm As String, bufsh As String, bufwb As String
Dim bufar As Variant
Dim wb As Workbook, sh As Worksheet
Dim nm As Variant
Dim ar() As String
Dim n As Integer, m As Integer
Dim Matches As Object, Match As Object
'正規表現オブジェクト
Set objRe = CreateObject("VBScript.RegExp")
With rng
If .HasFormula = False Then Exit Function
If Application.ReferenceStyle = xlR1C1 Then
buf1 = Application.ConvertFormula(.FormulaR1C1, xlR1C1, xlA1, xlRelative, .Cells)
Else
buf1 = Application.ConvertFormula(.FormulaLocal, xlA1, xlA1, xlRelative, .Cells)
End If
End With
For Each nm In Application.Names
If InStr(buf1, nm.Name) > 0 Then
bufnm = nm.Name
buf = nm.RefersTo
buf = Mid$(buf, 2)
ReDim Preserve ar(n)
ar(n) = bufnm & "=" & buf
n = n + 1
buf1 = Replace$(buf1, bufnm, "")
End If
Next nm
objRe.Global = True
objRe.Pattern = "!([^\!\*\+\-\/\=):,]+)"
For Each wb In Workbooks
If InStr(buf1, "[" & wb.Name & "]") > 0 Then
bufwb = "[" & wb.Name & "]"
buf2 = Replace(buf1, bufwb, "", , 1)
If Application.ReferenceStyle = xlR1C1 Then
buf2 = Replace$(buf2, "'", "")
End If
Do
For Each sh In wb.Sheets
If InStr(buf2, sh.Name) > 0 Then
buf3 = Replace(buf2, sh.Name, "", , 1)
bufsh = sh.Name
Set Matches = objRe.Execute(buf3)
buf4 = objRe.Replace(Matches(0).Value, "$1")
ReDim Preserve ar(n)
If bufwb Like "*" & ThisWorkbook.Name & "*" Then
ar(n) = sh.Name & "!" & Range(buf4).Address(0, 0)
buf2 = Replace$(buf2, ar(n - 1), "")
Else
ar(n) = bufwb & sh.Name & "!" & Range(buf4).Address(0, 0)
buf2 = Replace$(buf2, sh.Name & "!" & Range(buf4).Address(0, 0), "")
End If
n = n + 1
If objRe.test(buf2) = False Then Exit Do
End If
Next sh
Loop While objRe.test(buf2)
End If
Next wb
If buf2 = "" Then buf2 = buf1
If Application.ReferenceStyle = xlR1C1 Then
buf2 = Replace$(buf2, "'", "")
End If
For m = 1 To 2
If m = 1 Then
objRe.Pattern = "[\*\+\-\/\=\(,:]([A-Z]{1,2}\d+)"
objRe.Global = True
Else
objRe.Pattern = "([A-D0-9]{1,3}:[A-D0-9]{1,3})"
objRe.Global = True
End If
If objRe.test(buf2) Then
Set Matches = objRe.Execute(buf2)
For Each Match In Matches
ReDim Preserve ar(n)
buf4 = objRe.Replace(Match.Value, "$1")
'旧バージョン仕様
bufar = Application.Match(buf4, ar(), 0)
If IsError(bufar) Then
ar(n) = buf4
n = n + 1
End If
Next
ReDim Preserve ar(n - 1)
End If
Next m
If Application.ReferenceStyle = xlR1C1 Then
bufar = Application.ConvertFormula(Join(ar(), ","), xlA1, xlR1C1, xlAbsolute)
BPRC = Replace$(bufar, "[" & ThisWorkbook.Name & "]", "")
Else
BPRC = Join(ar(), ",")
End If
Set objRe = Nothing
End Function
お礼
Formulaを使えばよかったんですね! 期待の結果が得られました。有難うございました。