
DirectPrecedentsプロパティが同一シート内しかトレースできないことを利用して、他シートを参照しているセルを判定できないかと思い、下記のマクロを書いてみました。
残念ながら他シートを参照しているセルでエラーになってしまいます。
どのよに修正すればよいでしょうか?
なお、他シート参照の判定に"!"の存在を使わないのは、「名前定義」されたセルを参照している場合を想定しているためです。
Sub TEST01()
With ActiveSheet
On Error GoTo line
For Each c In .UsedRange.SpecialCells(xlCellTypeFormulas, 23)
On Error GoTo 0
c.Select
If c.DirectPrecedents.Address = "" Then'ここでエラー
MsgBox c.Address & "は他シート参照"
Else
MsgBox c.Address & "は" & c.DirectPrecedents.Address & "参照"
End If
Next
End With
line:
MsgBox "数式がありません。"
End Sub
No.5ベストアンサー
- 回答日時:
このエラーはプログラムのエラーだから、IsError()では取れない。
IsError()は、引数を評価して、その評価の結果がエラー値かどうか判定してtrueとかfalseを返す。引数には有効な任意の式を指定する。
IsError(c.DirectPrecedents.Address)は、c.DirectPrecedents.Address
が、他シート参照のセルのAddressをとろうとしたエラーだ(有効ではない)から、評価のしようが無いということではないか。
ところで、目的は、どうしてもc.DirectPrecedents.Addresを使いたいということですか。参照のアドレスを取りたいだけなら、単にc.Formulaとすればとれるけど・・・。
ありがとうございます。
> 目的は、どうしてもc.DirectPrecedents.Addresを使いたいということですか。
いいえ、アクティブなシートに他のシートを参照しているセルがあるかどうかの判定をしたいだけです。
最初はc.Formulaに"!"があれば他のシート参照としてたのですが、それでは他シートにある名前を定義されたセルを参照した場合、シート名の!が出ないので、逆に他のシートの参照元をトレースしたらエラーになるDirectPrecedentsが使えないかと考えたのです。
No.6
- 回答日時:
こんばんは。
#4 のお礼側の件ですが、
>では、他シートを参照しているセルのDirectPrecedentsは何を返すのでしょうか?
重複しますが、プログラムとしてのエラー=実行時エラーですね。
そうすると、コード全体がとまってしまいます。
たぶん、お分かりにはなっているとは思いますが、値自体も取れませんので、そういう場合は、
On Error Resume Next
'実行時エラーの可能性のあるコード
buf = Empty
buf= c.DirectPrecedents.Address
On Error Goto 0
変数 buf は、Variant 型としたら、Empty ですが、エラーが発生すると、変数の中がクリアされませんので、前の値が残っています。だから、一旦、その変数は、Empty にしてあげないといけませんね。文字型なら、「""」 ということになります。
この件は、確かに、#5さんの c.Formula もご指摘の通りなのですが、このマクロの発展型としては、ツールの中の[ワークシート分析]と同じことをしてもしょうがないので、数式自体を分解し、再構築して、参照先を明示するということを考えたほうがよいのかもしれません。出来る出来ないは別として。
No.4
- 回答日時:
こんばんは。
>たとえば、IsError(c.DirectPrecedents.Address)
それ自体に、エラーを吐くわけではありません。
例えば、Application.Sum(...) というのは、エラー値を返すような仕組みが出来ていますが、c.DirectPrecedents.Address 自身の内部でエラーが起きるので、IsError では囲えません。エラー値は、一つの型の値なのです。
それと、#3のコードは今回の質問内容とは違うコードでしたので、もう少し言い訳させていただきたいのですが、この件に関しては、過去2度行っていて、昨年だったと思いますが、数式の参照先にジャンプでそこに飛ぶというものだったので、その記憶が強く残っていました。改めて訂正させていただきます。
>#3のコードは今回の質問内容とは違うコードでしたので、
今回のわたしの質問と直接の関係はないですが、すばらしいユーザー定義関数です。勉強させていただきます。ありがとうございました。
>> たとえば、IsError(c.DirectPrecedents.Address)
> それ自体に、エラーを吐くわけではありません。
では、他シートを参照しているセルのDirectPrecedentsは何を返すのでしょうか?
"" でも Nothing でもないようです。どうやったらしらべられるのでしょうか?
No.3
- 回答日時:
#2 のことわりを入れておきますが、
#2のコードのユーザー定義のアドレスの切り分けは、そのままでは、まったく意味がありません。取れたアドレスは、そのまま、表示すればよいだけのことです。ただ、それをVBAで再利用するときにだけ、「[ブック名]シート名! セル座標」の切り分けが必要になるというものです。
だから、そのユーザー定義関数は、今回の内容からすれば無意味です。
Wendy02さま、いつもありがとうございます。
Sub TEST03()
Dim c As Range
Dim buf As Variant
With ActiveSheet
On Error GoTo line
For Each c In .UsedRange.SpecialCells(xlCellTypeFormulas, 23)
On Error GoTo 0
On Error Resume Next
buf = Empty
buf = c.DirectPrecedents.Address
On Error GoTo 0
If IsEmpty(buf) Then
MsgBox c.Address & "は他シート参照"
Else
MsgBox c.Address & "は" & c.DirectPrecedents.Address & "参照"
End If
Next
End With
Exit Sub
line:
MsgBox "数式がありません。"
End Sub
いったんBufに取り込むようにしたことでできました。
ただ、たとえば、IsError(c.DirectPrecedents.Address) というような感じでなぜエラーを判定できないのが腑に落ちないのです。
No.2
- 回答日時:
こんにちは。
うーん、今の状態では、基本的に無理があるかなって思います。
私の作ったものでも、名前定義とか関係なく、数式が複合的になると、うまくいきません。数式を切り分けする必要があるようです。
'-------------------------------------------
Sub FindReferencesMacro()
'DirectPrecednts を使ったマクロ
Dim c As Variant
Dim buf As Variant
Dim pAddr As String
With ActiveSheet
On Error GoTo ErrHandler
For Each c In .UsedRange.SpecialCells(xlCellTypeFormulas, 23)
On Error Resume Next
buf = Empty
buf = c.DirectPrecedents.Address
On Error GoTo 0
If IsEmpty(buf) Then
FindPrecedent c.FormulaLocal, pAddr
Else
pAddr = c.DirectPrecedents.Address
End If
MsgBox c.Address & " は " & pAddr & " を参照"
pAddr = ""
Next
End With
Exit Sub
ErrHandler:
MsgBox Err.Number & ": " & Err.Description
End Sub
Function FindPrecedent(ByVal strForml As String, ByRef strAdd As String)
Dim Matches As Object
Dim Match As Object
Dim w As String, s As String, c As String
If Not strForml Like "=?*" Then Exit Function
If InStr(strForml, "!") > 0 Then
With CreateObject("VBScript.RegExp")
.Pattern = "=(\[.*\])?(.*)\!(.*)"
.Global = True
Set Matches = .Execute(strForml)
If Not Matches Is Nothing Then
On Error Resume Next
w = Matches(0).SubMatches(0)
s = Matches(0).SubMatches(1)
c = Matches(0).SubMatches(2)
On Error GoTo 0
End If
End With
Else
FindPrecedent Application.Names(Mid$(strForml, 2)), strAdd
End If
If strAdd = "" Then
strAdd = w & s & "!" & c
End If
End Function
'-------------------------------------------
No.1
- 回答日時:
基本的には直っていないだろうが、目的の動作はするけど。
こういう姑息なことではない?
アクティブ シートでしかできないといっているのを使うのだからこうなっても・・・。
Sub TEST01()
With ActiveSheet
On Error GoTo line
For Each c In .UsedRange.SpecialCells(xlCellTypeFormulas, 23)
'On Error GoTo 0
c.Select
Debug.Print Selection.Row, Selection.Column
'Debug.Print c.DirectPrecedents.Address
If c.DirectPrecedents.Address = "" Then 'ここでエラー
'MsgBox c.Address & "は他シート参照"
Else
MsgBox c.Address & "は" & c.DirectPrecedents.Address & "参照"
End If
Next
End With
Exit Sub
line:
MsgBox c.Address & "は他シート参照"
Resume Next
End Sub
ありがとうございます。
姑息だなんてとんでもない。エラーハンドラーからResume NextでまたFor Nextの続きに戻れるとは知りませんでした。
ということはこれでいけますね。↓
Sub TEST02()
With ActiveSheet
On Error GoTo line1
For Each c In .UsedRange.SpecialCells(xlCellTypeFormulas, 23)
On Error GoTo line2
MsgBox c.Address & "は" & c.DirectPrecedents.Address & "参照"
Next
End With
Exit Sub
line1:
MsgBox "数式がありません。"
Exit Sub
line2:
MsgBox c.Address & "は他シート参照"
Resume Next
End Sub
ただ、たとえば、IsError(c.DirectPrecedents.Address) というような感じでなぜエラーを判定できないのが腑に落ちないのです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
- Visual Basic(VBA) 【VBAエラー】Nextに対するForがありません 対策について 5 2022/11/21 21:26
- Visual Basic(VBA) Changeイベントで複数セルへの貼り付けおよび値削除時に1個目のセルのみエラーになる 3 2022/12/21 09:07
- Visual Basic(VBA) エクセルのマクロとシートの保護について教えてください。 1 2022/10/18 08:36
- Visual Basic(VBA) VBA Userformで一部別シートに転記がしたいのですが 2 2023/05/24 13:08
- Excel(エクセル) vba シート名の一覧を2列に分けるには 5 2023/04/24 08:56
- Excel(エクセル) なぜExit Subがあるのかわかりません 4 2023/02/19 12:34
- Visual Basic(VBA) 【追加】ファイルを閉じてダイアログで保存した時だけ処理の実行をする 3 2022/03/23 15:43
- Visual Basic(VBA) VBAの繰り返し処理について教えてください。 3 2022/08/02 13:21
- Visual Basic(VBA) マクロVBA 1シートをまとめる 閉じ方 初心者 SOS! 1 2022/06/17 14:54
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
実行時エラー 438になった時の...
-
VBAがブレークモードになっ...
-
実行時エラー48発生時のDLL特定...
-
実行時エラー -'-2147417848
-
VBAのコードがエラーになっ...
-
なぜこんな初歩的なVBAのIf文で...
-
Application.ActiveInspectorで...
-
EXCEL/VBAで、自分のPCだけエラ...
-
マクロについて教えてください...
-
『実行時エラー 5 プロシージャ...
-
VBA:「中断モードでは入力でき...
-
VBAでのエラー
-
ExcelのVBAのAutoFillの使い方...
-
VBからAccessへの接続でエラー
-
Outlook.ApplicationをCreateOb...
-
実行エラー9 インデックスが...
-
カーソルオープンでエラー(ORA...
-
ACCESSのエラーで困っています
-
JSP/サーブレットを用いたWebア...
-
VBSで変数の宣言はできないので...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
実行時エラー 438になった時の...
-
なぜこんな初歩的なVBAのIf文で...
-
VBAがブレークモードになっ...
-
実行時エラー -'-2147417848
-
ExcelVBA Range クラスの Page...
-
マクロについて教えてください...
-
VBAでのエラー
-
【Excel VBA】マクロをボタンに...
-
実行時エラー48発生時のDLL特定...
-
EXCEL VBAマクロ中断でデバッグ...
-
なぜエラーになるのでしょうか...
-
実行時エラー3001「引数が間違...
-
OLEDB.NETで接続できない
-
INSERT INTOステートメント構文...
-
VBAのエラー発生場所をメッセー...
-
VB6+SQL サーバー 2000 で 実行...
-
Outlook.ApplicationをCreateOb...
-
ADODB.Streamを使用してUTF-8を...
-
カーソルオープンでエラー(ORA...
-
Invalid procedure call or arg...
おすすめ情報