こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

シートモジュールからのErr.Raiseについて

Excel(Office 2007)で以下のようにシートモジュールで
発生したエラーの詳細を標準モジュール側で取得しようとしたところ
SourceとDescriptionで指定した文字列が取得できませんでした。

どうすれば指定した元の文字列を取得することができるでしょうか。
どなたかお知恵をお貸しください。

【シートモジュール(Sheet1)内のソースコード】
Public Sub Hoge()
    Err.Raise Number:=1000, Source:="Fugo", Description:="Fuga"
End Sub

【標準モジュール内のソースコード】
Public Sub Piyo()
    On Error Goto Error1
    Sheet1.Hoge
    Exit Sub
Error1:
    MsgBox "Num=" & Err.Number & ", Src=" & Err.Source & ", Dsc=" & Err.Description
End Sub

【MsgBoxの表示結果】
Num=1000, Src=VBAProject, Dsc=アプリケーション定義またはオブジェクト定義のエラーです。
 

投稿日時 - 2013-04-20 16:48:52

QNo.8051640

困ってます

質問者が選んだベストアンサー

> Object型やVariant型経由だとうまくいく理由
わかった気がします。バインディングがナントカって話かも。
 ・Object型ならクラス定義なしで遅延バインディング
 ・Sheet1型なら定義を使って事前バインディング
たしか、関数名の差し替えもできたはず。定義が噛むことで呼び出しが変わり、エラー処理をもった関数にラッピングされる、ってコトじゃないかな。

そして、このMsgBox・・・UI絡みの配慮かと思ったけど、イベント契機だと出ない。旧仕様の名残ですかね。そう考えると、ちぐはぐな挙動にも納得いきます。


> Sheet1.XXの書き方ってあまりされませんか?
動的なシート生成/削除や、他Book操作もあるので、僕は基本Nameで統一してます。Nameは定数にすると処理と定義を分けやすいです。
ユーザ操作の話をすると、Sheet1もシート複製→元シート削除で再起不能。シートを複製して設定のバックアップを・・・とかされるとアウトなんです。目に見えるシート名で縛った方が安定するかな、っていうのが悩んだ末の結論でした。

僕はほとんどシートモジュール使わなんですが、使うならSheet1のがしっくり来ますよね。
使い分けたらいいと思いますよ。

投稿日時 - 2013-04-23 23:49:23

お礼

レスが遅くなりすみません。

> 定義が噛むことで呼び出しが変わり、エラー処理をもった関数にラッピングされる、ってコトじゃないかな。
なるほど、確かにそんな感じのようですね。

シートモジュール内にマクロを実装する際は、呼び出し方を変えてみたり、そもそもエラーを外に出さないように実装するなど工夫してみます。

ご回答頂きありがとうございます。
非常に助かりました。

投稿日時 - 2013-05-09 22:45:45

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

> Sheet1.Hoge
Sheets(1).Hoge か Sheets("Name").Hoge で大丈夫。

Hogeを直接実行(F8)すると、見慣れたデバッグダイアログじゃなく、「メッセージボックス」でエラーが通知されます。シートはイベントなどユーザ操作と直接関わるため、エラー処理をしてくれるようです。
Sheet1.XXだとユーザ操作と同じ扱い、ってコトですかね。
テストコードでもない限り、Sheet1.XX なんて書くコトはないでしょうから、問題はないと思いますが。混乱しますよね。

投稿日時 - 2013-04-22 21:42:28

補足

Sheets(1).HogeやSheets("Name").Hogeの書き方でうまくいくのは、
どうやらObject型を経由してプロシージャを呼び出していることにあるようですね。
(Sheetsの既定のプロパティの戻り値はObject型)
なので以下の書き方でもうまくいきました。

Dim obj As Object '←Variant型でもうまくいきました。
Set obj = Sheet1
obj.Hoge

なお、Object型やVariant型経由だとうまくいく理由については
思いつかなかったのですが御心当たりはございますでしょうか?

※エラートラップを「クラス モジュールで中断」に設定すると
いつものデバッグダイアログが出てその時点では、
Descriptionで設定した文字列も元のままでした。
シートモジュールでは最終的にエラーをトラップしないと
例の「メッセージボックス」で通知するよう仕込まれており、
そこが何やら悪さをしているように思うのですが、
それ以上のことがちょっとわかんなかったです。


ちなみに、自分としてはSheets(1)やSheets("Name")の書き方では
シートの場所や名前を変更しただけでソースコードまで変更しなければならず、
意図せずユーザに変更されてしまいバグる恐れもあるので、
Sheet1.XXなどのオブジェクト名による書き方のほうがいいと思うのですが、
Sheet1.XXの書き方ってあまりされませんか?

投稿日時 - 2013-04-23 02:51:50

お礼

ご回答ありがとうございます。
普段、Sheet1.XXな書き方なので、こちらの書き方を試せてませんでした。
助かりました。

投稿日時 - 2013-04-23 02:43:31

あなたにオススメの質問