• ベストアンサー

Excel:ThisWorkbookオブジェクト内にプロシージャを追加し、それを標準モジュールから呼び出すことは可能?

(おかしなことを言っているかもしれませんし、 VBAについて正しく理解できていないのかもしれません) ThisWorkbookオブジェクト内にプロシージャ(Public)を追加して、 それを標準モジュールから呼び出すことが出来るのでしょうか? 質問内容のことを行いたいのです。 しかし、それ以前にThisWorkbookオブジェクト内にプロシージャを追加して、 それをThisWorkbookオブジェクト内から呼び出すことも今現在出来ていないません。 (ThisWorkbookオブジェクトにプロシージャの追加、またそれの呼び出しが可能か不可能かも分かっていません)

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

  • ベストアンサー
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

ThisWorkbookの所に Public Function test(A, B) test = A + B End Function と記述したとしたら 標準モジュールから Public Sub mtest() dim ans ans=ThisWorkbook.test(10, 20) End Sub のように呼び出せます

googan
質問者

お礼

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

その他の回答 (1)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんにちは。 私は、この件について、多くのテキストには載っていることですが、一度、自分自身でまとめようと思いました。 VBAでは、Public キーワードの使い方は、基本中の基本なのですが、VBAは、標準モジュールが優先されるので、Visual Basic とは異なる点を持っています。 ThisWorkbook オブジェクトではなくて、ThisWorkbook モジュールだと思いますが、Public キーワードをプロシージャにつけたからと言って、それで呼び出されるようにはなりません。良いVBAのテキストをみると、Public キーワードの説明は、変数に関してのみのはずです。 VBAでは、Public キーワード/ステートメントは、プロジェクトの範囲をスコープ(適用範囲)とするもので、また、VBAでは、変数につけるものです。基本的には、標準モジュールに書かれたプロシージャは、暗黙的にPublic をつけたものとみなされます。つまり、明示的にPublic キーワードを用いるだけです。 サンプルを用意しましたので、試してみてください。 プロシージャのスコープと、変数のスコープを比べられると思います。 二つのブック(Book1とBook2)を使います。なお、最初の二つのプロシージャは、状況がわかったら、コメントアウトして切り替えてみたりしてください。実行は、カーソルをそのプロシージャ内で、F5かF8(ステップイン)で行ってください。 最初、Book2 のほうは閉じてお使いください。 全て、標準モジュール側から実行させます。 全体のおおよそのことが分ったら、三つ目のブックを用意してみてください。単に開けるだけで結構です。また、反応が変わるはずです。 'Book1の標準モジュール '---------------------------------------------- Public myTime1 As String Sub TestSample1() 'ThisWorkbook への呼び出し  '最初のコードはプロシージャを呼び出せません  'コメントアウトしたものを入れ替わり使ってみてください。   Test1  'ThisWorkbook.Test1   MsgBox myTime1   Test2  'ThisWorkbook.Test2   MsgBox myTime2   'MsgBox myTime1  End Sub Sub TestSample2() 'ThisWorkbookへの呼び出し  On Error Resume Next  'この二つのプロシージャは呼び出せません  'TestSamle1 のようにThisWorkbook. をつけると呼び出せます。   Call Test1   MsgBox myTime1   Call Test2   MsgBox myTime2 End Sub Sub TestSample3() '変数のスコープの違い  Call ThisWorkbook.Test2  MsgBox myTime1  MsgBox myTime2 '失敗  MsgBox myTime3 '失敗 End Sub Sub TestSample4()  'TestBook2へのThisWorkbookの呼び出し  Application.Run "Book2.xls!ThisWorkbook.Test4"  MsgBox myTime4 End Sub Sub TestSample5a() 'TestBook2へのThisWorkbookの引数付きの呼び出し Dim myTime5 As String  Application.Run "Book2.xls!ThisWorkbook.Test5", myTime5  MsgBox myTime5  MsgBox myTime1 '状況によって反応が変わります。 End Sub Sub TestSample6a() 'TestBook2への標準モジュールの関数の呼び出し Dim myTime6 As String  myTime6 = Evaluate("'Book2.xls'!Test6()")  MsgBox myTime6 End Sub Sub TestSample6b() 'TestBook2への標準モジュールのPublic関数の呼び出し Dim myTime6b As String  myTime6b = Evaluate("Test6b()")  MsgBox myTime6b End Sub '---------------------------------------------- 'Book1 のThisWorkbook Public myTime2 As String Public Sub Test1()  myTime1 = "myTime1:" & Format$(Now) End Sub Sub Test2() Dim myTime3 As String  myTime1 = "myTime1:" & Format$(Now)  myTime2 = "myTime2:" & Format$(Now)  myTime3 = "myTime3:" & Format$(Now) End Sub '============================================= 'ブックを開いた状態と閉じた状態で比較します。 'ただし、Book2は、Book1 と同一のフォルダにあるとします。 'Book2 の標準モジュール Function Test6(Optional myTime6 As String)  Test6 = "myTime6:" & Format$(Now) End Function Public Function Test6b(Optional myTime6b As String) Test6b = "myTime6b:" & Format$(Now) End Function '---------------------------------------------- 'Book2 のThisWorkbook Public myTime4 As String Public Sub Test4()  myTime4 = "myTime4:" & Format$(Now) End Sub Sub Test5(myTime5 As String)  myTime5 = "myTime5:" & Format$(Now)  myTime1 = myTime5 End Sub 'Book2 の標準モジュール Function Test6(Optional myTime6 As String)  Test6 = "myTime6:" & Format$(Now) End Function '// サンプルを試してみると良く分るかと思います。 結論: ThisWorkbookのプロシージャにPublic キーワードをつけても、つけなくても変わりはありません。#1 さんの例も良いと思います。そのコードから、Public を取り除いて、実行してみてください。結果は同じです。つまり、逆に、呼び出されたくないものがあります。その場合は、必ず、Private キーワードを付けなくてはなりません。 なお、他のブックと連結して使うときは、基本的には、「参照設定」して、共有する方法があります。参照設定すると、他のブックの連結状態は、また変化しますが、それはご自身で確認してみてください。基礎とは言うものの、なかなか覚えにくく、分りにくいものだと私は思います。VBAは、時々、可読性よりも実効性を優先するために変則的な書き方をします。これは、チームを組んで開発することがないから、ということと、スクリプト言語というのが理由です。その点で、実際のコードの書き方(最適化法)は、原則からは多少外れているように感じます。

googan
質問者

お礼

回答ありがとうございました。 詳しい説明とサンプルまで書いて頂き、ありがとうございました。

関連するQ&A

  • ThisWorkbookのオブジェクトが消えた

    エクセルVBAで VBAproject(book1) Excel objects sheet1 sheet2 sheet3 ThisWorkbook と こうなるのが 標準だと思うのですが、ThisWorkbook が 消えました。 困るのが、ThisWorkbook-OPEN で 初期値などセットするのですが、各シートには OPEN は ありませんし。 ThisWorkbook を 追加というか、復活というか 何かうまい方法は無いでしょうか。 また、新規から というのも・・・いささか。 シートを うまく取り込む方法ってあれば 、それはそれで、ありかなとも 思うのですが。

  • 【VBA】SUBプロシージャーは標準モジュール以外に書いてもいい?

    ThisWorkbookのコードを書く場所や Sheetのイベントプロシージャーが実行されるところに Sub test() MsgBox "あああ" End Sub と書いて実行するとメッセージボックスが表示されます。 クラスモジュールとフォームのイベントプロシージャーを書くところではできませんでした。 ということはSUBプロシージャーは 標準モジュールでなくてもいいのでしょうか?

  • subプロシージャーは標準モジュールではなくフォームのコードを書く部分

    subプロシージャーは標準モジュールではなくフォームのコードを書く部分に書いても問題ないのでしょうか? エクセルにVBAでフォームを挿入し、 「Private Sub UserForm_Initialize()」 などのフォームのモジュールに、 Sub test() MsgBox "あああ" End Sub という標準モジュールに書くべきのsubプロシージャーを書いてもなにもエラーにならないし正常に動きます。 subプロシージャーは標準モジュールではなくフォームのコードを書く部分に書いても問題ないのでしょうか? それともエラーにならなくても標準モジュールに書いた方がいいですか?

  • VBとVBAのコードの違い プロシージャー呼び出し方法

    何度かお世話になっておりおります 毎回アドバイスありがとうございます 早速なのですがまた躓いてしまいアドバイスお願いします。 ~質問内容~ 標準モジュールからフォームのプロシージャーを呼び出す エラー内容 オブジェクトが必要である       オブジェクト修飾が必要など 出てきました オブジェクト修飾 というのが もう理解出来ず 本当にスタートの時点ではありますが アドバイスお願いします VBのコード 標準モジュール Sub Main() MainForm.Initialize End Sub フォームのコード Public Sub initialize()  ”コード内容”  End Sub ↑上記で記入しました フォームで宣言されているInitialize を呼び出したいのですが VBでは このままで出来るはずなのですが VBAでは オブジェクト修飾が必要です CALL をつけても エラーのままでした 少し質問がわかりにくくなってしまいましたが 標準モジュールから フォームのプロシージャーを呼び出すには なんと入れれば宜しいでしょうか? アドバイスお願いします

  • オブジェクトモジュールにメンバーの追加(エクセルVBA)

    エクセルのVBAで、オブジェクトモジュールに(クラスの?)メンバーを追加したいと考えています。(そんな使い方すべきでないとの意見もありそうな問題ですが・・?) Thisworkbookのモジュールに次のコードを書いてみたのですが、test_bookを動かすと(1)~(3)は問題ないのですが、(4)がエラーになります。(自動メンバー表示もされません。且つ、???に何を入れればいいのか?判りません) で、質問ですが、オブジェクトモジュールに、プロパティ、メゾッドは追加できるのでしょうか?追加したプロパティ、メゾッドは、自動メンバー表示に加えることが出来るのでしょうか?その時は、やはり、Enum を使うのでしょうか?ご指導のほどよろしくお願い致します。 Private enum ?? ???? End Enum dim ??? as ??? Sub test_book()   MsgBox Name & FullName & FolderName  '(1) MsgBox ThisWorkbook.Name & _      TisWorkbook.FullName       '(2) MsgBox Me.Name & Me.FullName      '(3) MsgBox Name & FullName & _      ThisWorkbook.FolderName      '(4) End Sub Private Property Get FolderName() As String FolderName = "test"   '所属するフォルダー名を返すプロパティーを借りに想定して単に"test"を返して実験してみました。実際にやりたいことは、別にあります。 End Property 具体的に何をやりたいのかを明示できなくてすみません。宜しくお願い致します。

  • Excel:アドイン(ThisWorkbook)内のプロシージャからシートの操作は可能なのでしょうか?

    アドインとして登録して、 そのThisWorkbook内のプロシージャからシートの操作(削除、追加、コピーなど)を行おうとしています。 これを行うにはどうすればいいのでしょうか? まだXLSファイルの状態の時はうまく動作しましたが、 アドインとして登録すると、 >実行時エラー'91' >オブジェクト変数またはWithブロック変数が設定されていません。 という旨のエラーメッセージが出て終了してしまいます。 (ActiveSheet.Delete の処理でエラーが起こっています) 昨日質問させていただいたとき、 >また、ThisWorkBook などの記述があるとアドインのブックになってしまうので、 >処理上の不都合が起きないようにする事が大切かと思います。 ということをお聞きしました。 おそらく、今回の問題となっている点にあたるものだと思います。 回避する方法はあるのでしょうか?

  • 標準モジュールとクラスモジュールの違い

    マイクロソフトのAccess2000でVBAプログラミングを行なっておりますが、 基本的なことを教えてください。 「標準モジュール」と「クラスモジュール」の違いはなんですか? 例えば、どこからでも使えるプロシージャ Public Function getSum( i1 as integer, i2 as interger ) getSum = i1 + i2 End Function を定義したとして、標準モジュール内に書くのとクラスモジュール内に 書くのとでは、何が違ってきますか?その他とにかく「標準モジュール」 とクラスモジュールの違いを教えてください。

  • Access VBA標準モジュールについてです。

    Access VBA標準モジュールについてです。 現在、仕事上必要にかられAccessVBAを勉強中の初心者です。初歩的な質問で申し訳ありませんが、ご存知の方教えて下さい。 フォーム上のコマンドボタンを押した時に標準モジュールを作動させたいのですが、そんな方法はありますか?【クラスモジュールについての本は沢山あって何とか理解できつつありますが、標準モジュールに関しての記述があまり無い気がします。】 宜しくお願いします。

  • 標準モジュールについてなのですが

    すみません。教えてください(/_;)VB6にて理解できないことがあります。いくつものパスを標準モジュールに記述できると知り、早速見やすいプログラムにしようと思い、標準モジュールを追加しました。サンプルなどを調べ、Function Apath() as stringを理解しました。フォームの方にはpath = Apathって書いておけばいいと書かれていたのでその通りにしました。しかし、見に行ってはくれません(>_<)で、いろいろやってみてあることに気づきました。変数を宣言してたら、ダメでしてなかったらちゃんと見に行ってくれます。 Dim path as string,Dim Apath as string.Apathを消すと働いてくれます。宣言が間違っているのでしょうか?標準モジュールをこのような感じで利用するには何か重大なルールがあるのでしょうか?すいません、初心者すぎる質問で<(_ _)>しかし、聞かぬは一生の恥と思い質問しました(>_<)よろしくお願いいたします<(_ _)>

  • 標準モジュールを削除したい。(VBA)

    VBAで、VBAの標準モジュールを削除したいのですが、なかなか出来ません。たぶん、コレクションについての認識があまいからだと思います。VBComponents コレクションのobject.Remove(component)のヘルプには、VBProjects コレクションには、スタンドアロン プロジェクトを指定します。とありますが、そもそもスタンドアロンプロジェクトって何ですか?Application.VBE.VBProjects(4).VBComponents(1).とするとコレクションでなくなってしまいますが、どうやってモジュールと特定するのでしょうか?どなたか詳しい方いらっしゃいましたらご指導願います。よろしくお願いいたします。 VBIDEのライブラリーです。

専門家に質問してみよう