AccessVBAで、AllTablesという文字列をオブジェクトブラウザで探すと、以下画像のような結果になりました。
AccessVBAで、AllTablesという文字列をオブジェクトブラウザで探すと、以下画像のような結果になりました。 これを踏まえて以下のようなコードを書いたのですが、AllTablesのところで、「メソッドまたはデータメンバーが見つかりません」と出てしまいます。 Sub test() Dim obj As Object For Each obj In Access.AllTables Debug.Print obj.Name Next obj End Sub 別にAllTablesにこだわりはなくて、使いたいわけではないのですが、オブジェクトブラウザの見方が一生分かる気がしなくて泣きそうです・・・。「Accessのメンバー」だとはっきり書いているのに、なぜAccess.AllTablesで認識されないのかが分かりません。メンバーなんだから、ドットで繋げて書けるってことじゃないんですか?? ちなみにですが、「Access.CurrentData.AllTables」とすればこのコードは意図した結果になります。こっちはこっちで納得はできます。AccessのメンバーにCurrentdataがあるから、Access.Currentdataと書けて、CurrentdataのメンバーにAllTablesがあるから、さらに続けてAccess.Currentdata.AllTablesですよね。全然納得できます・。 ただ、AllTablesがAccessのメンバーでもあると言うんだから、「Access.AllTables」という表記もいけるでしょ!って思うんですが。 メンバー ⇔ ドットで繋げる という認識は間違っているのですか?
Microsoft Access | プログラミング・355閲覧・250
ベストアンサー
「Access」は「ライブラリ」の名前で、とりあえず、オブジェクト名ではないです。 「Access」ライブラリの実体は、オブジェクトブラウザの下のほうの「説明ペイン」の「Access」という緑のリンク文字をクリックするとわかります。 例えばバージョン2007以降の場合ですと 「C:\Program Files\Microsoft Office\Office×××\MSACC.OLB Microsoft Access ××× Object Library」 というのが、Accessライブラリの本体ファイルです(OLB拡張子)。 で、 Excelでもそうなんですけど、 AccessやExcelの次に来るのは、 「Application」というオブジェクトです。 AccessもExcelもオブジェクトが階層構造になっているので、 階層を省略する(あるいは書き忘れる・書き間違える)と、 「基本的には」、エラーになります。 で、 今回の場合の階層を省略しない「正式な」オブジェクト式の書き方は Access.Application.CurrentData.AllTables となります。 Applicationの前にAccessやExcelとつけるのは、例えば、AccessVBAからCOMオートメーションでExcelVBAを操作したいときなどにOfficeのなかのどのアプリケーションかの区別をつけるために、つけます。 Appliationだけだと、Excelなのか、Wordなのか、Accessなのか、PowerPointなのか、Outlookなのか、どれなのかわからないので。 「Access.Application」なら、「Access」というライブラリ(OLBファイル)の中に含まれる、「Applicationオブジェクト」という意味ですし、 「Excel.Application」なら、「Excel」というライブラリ(OLBファイル)の中に含まれる、「Applicationオブジェクト」という意味になります。 で、 Access.Application.CurrentData.AllTables に戻りますが、 イミディエイトで例えば ? Access.Application.CurrentData.AllTables.Count と書いてEnterすると、テーブルの個数が出てきます。 テーブルの個数を数えたい場合、 Access.Application.CurrentData.AllTables.Count が 「オブジェクトの階層構造」のなかで、「省略がない」「正式な」「オブジェクト式」の書き方になります。 本来なら、「AllTables」に辿りつくまで、 「Access」 「Application」 「CurrentData」 どれを書き忘れてもエラーになるはずでなんです。 でもそうならないケースがあります。 「Access」は、まあ、多分ですが、「今開いているソフトAccessって分かりきってるもんね」という理由からか、はたまた、オブジェクト名ではなくて「ライブラリ名」だから、という理由なのか、どうなのかはわかりませんが、書かなくてもエラーは出ません。 「Application」を書かなくても、エラーが出ないのは「そういう風に前もって」、「省略して書いていいよ」と「グローバル」というカテゴリで許可されている仕様になっているからです。これはExcelでもWordでも同じです。 オブジェクトブラウザの左側のペイン(「クラス」のペイン)のてっぺんに「グローバル」というものがあると思いますが、これは、「上位の階層のオブジェクトの記述を省略してもいいオブジェクトの集まり」です。 「グローバル」をクリックすると、右側の「メンバ」のペインに「CurrentData」というプロパティがあります。 これは「CurrentData」という単一オブジェクトをゲットするためのプロパティです。 「グローバル」の中に、「CurrentData」プロパティがある、ってことは、 『 CurrentData の上位(前部)の記述は省略していいよ!」っていうお墨付きをもらってる、という意味になります。 なので、もし仮に、「グローバル」の中に、「CurrentData」プロパティが「無い」となると、 Application.CurrentData.AllTables と書かないとエラーになります。 でも現実には、「グローバル」の中に、「CurrentData」プロパティが「在る」ので、 CurrentData.AllTables と書いてもエラーになりません。 Accessは今回は「Application」を省略しているためにエラーにならないので、 Access.CurrentData.AllTables と書いてもエラーになりません。 (「Application」以外を省略している場合は、Accessを付けるとエラーになるケースもあるかも?です。オブジェクト名ではなくてライブラリ名、なので。試してませんけど。) で、じゃあ、 「Application.CurrentData.AllTablesって正式な書き方はどうやってみつけるの?」 ということですが、 「AllTables」で完全一致で検索すると、ご質問の図のようになりますが、 これは 「Accessライブラリ」の中には「確かにAllTablesっていうオブジェクトがあります。それはsが付いているのでコレクションオブジェクトになります」という意味がまず読み取れます。 次に、その「AllTables」コレクションオブジェクトをゲットするには、 「CodeData」単一オブジェクトの「AllTables」プロパティでゲットするか 「CurrentData」単一オブジェクトの「AllTables」プロパティでゲットするか 2つにひとつ、ということが読み取れます。 つまり、「AllTables」コレクションオブジェクトをゲットするには、 「CodeData」かもしくは「CurrentData」ってオブジェクトの分の記述も要るんやな~ 「AllTables」て書いただけじゃあかんのやな~ とわかります。 で、 「CodeData」と「CurrentData」のヘルプを見ます。 オブジェクトブラウザは、ヘルプと一緒に使わないと、「正式な階層構造の省略のないオブジェクト式を見つけたい場合」は難しいです。 それ以外の場合はヘルプが無くても色々わかることもありますが、でも、基本、ヘルプを併用しないと分からないことのほうが多いかも?です。 「CodeData」と「CurrentData」のヘルプを見ると 『 AllTables コレクションおよびその関連プロパティを参照します。値の取得のみ可能です。AllTables オブジェクト型の値を使用します。』 という意味不明の内容です。 なので、今度はAllTables コレクションのヘルプを見ます。 おお!色々と書いてあります。 サンプルコードもある! というか、サンプルコードに答えが書いてある、みたいにわかります。 サンプルコードには「CurrentData」という単語が見えます。 先ほど、「CodeData」と「CurrentData」のどっちかを使うというところまでは判明してましたたので「とりあえずサンプルでも使われてるCurrentData使おっと」と決めることができます。 で、今度は「CurrentData」をオブジェクトブラウザで完全一致検索します。 2行出てきて、 上の行では「Accessライブラリ」の中には「CurrentData」単一オブジェクトがあるよー」とわかります。 んで、それをゲットするには 「Application」オブジェクトの「CurrentData」プロパティを使ってちょ! というのもわかります。 というわけで、 「ってことは、Application.CurrentData.AllTables ってつなげて書けばいいんだな~」と わかります。 ここで、 「オブジェクトを返す/オブジェクトをが返る」 =「オブジェクトをゲットする、ゲットできる」 =「オブジェクトにアクセスする、アクセスできる」 と考えて下さい。 というわけで、だいぶ端折りますが、 Application.CurrentData.AllTables の、これの意味は、 『 Application単一オブジェクトの中の、 「CurrentData」ってプロパティを使って「CurrentData」単一オブジェクトにアクセスし、 で、「CurrentData」単一オブジェクトにアクセス出来たら、こんどは その中に含まれる 「AllTables」っていうプロパティを使って「AllTables」コレクションオブジェクトにアクセスしますよ~ 』 という意味になります。 というわけで、 『 Application.CurrentData.AllTables 』 が正式な省略のないオブジェクト式の書き方だとわかりました。 ちなみに、今回に場合は、 「グローバル」のCurrentDataの説明ペインに 「Access.Application のメンバー」とも書いてあるので、 そこ見ても 『 Application.CurrentData.AllTables 』 が正式な省略のないオブジェクト式の書き方だとわかります。 ありるいはあたりが付きます。
2人がナイス!しています
『 Application.CurrentData.AllTables 』にはもちろん先頭jに「Acceess.」を付けてもかまいません。 というわけで、ご質問のエラーの部分は、 Access.AllTables ではなくて、以下のようになります。 Sub test() Dim obj As Object For Each obj In Access.Application.CurrentData.AllTables Debug.Print obj.Name Next obj End Sub あるいは、「グローバル」にて、「CurrentData」は上位の階層の記述の省略を認められていますので以下でもIOKです。 Dim obj As Object For Each obj In CurrentData.AllTables Debug.Print obj.Name Next obj
質問者からのお礼コメント
ありがとうございました! 見方がわかってきました!
お礼日時:6/26 10:39