• ベストアンサー

Folderオブジェクトでsubfoldersプロパティが使えない

Excel2000のVBAで、ユーザーがダイアログで選択したフォルダのサブフォルダのコレクションを取得しようとしています。 次のようなコード1にしたら、oFolderオブジェクトでは「Subfoldersプロパティをサポートしていない」旨のエラーが出ます。そこで、もう一段関数をかませて、その関数中でSet oFileSys = CreateObject("Scripting.FileSystemObject")    Set folder1 = oFileSys.GetFolder(folder_name)のようにして、別途folderオブジェクトを作成し、コード1の「colFolder」へ返すようにしてみたところ、うまく動きました。下記コード1中の「oFolder」と上の関数内の「folder1」は、いずれもFolderオブジェクトなのに、プロパティの種類が違うのはなぜでしょうか? ちなみに、オブジェクトブラウザで調べると、Folderクラスには、subfoldersプロパティというのが確かにありません!が、VBのヘルプにはしっかりとFolderオブジェクトの中にSubfoldersプロパティが載っています。 <コード1> Function フォルダ選択(メッセージ As String) As Object Dim oShell As Object,oFolder As folder,colFolder As Object Set oShell = CreateObject("Shell.Application") Set oFolder = oShell.BrowseForFolder(0, メッセージ, 1, "S:\")   If Not (oFolder Is Nothing) Then Set colFolder = oFolder.subfolders Set フォルダ選択=colFolder Else MsgBox "フォルダを選択しないと継続できません。" End;End If;END SUB

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

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

#3>参照設定することの意義 良くわからない、ActiveXのプロパティやメソッドを調べるためにオブジェクトブラウザを使う場合がありますが、 一般的には、参照設定することで、 dim oFolder as Folder のように、エディタで as としての候補としてでてくるコードを補ってくれるので便利ということや、あらかじめそのクラスのオブジェクトを宣言できる。(コレを事前バインディングといいます)というような意味合いがあると思います。 逆に、CreateObjectによってオブジェクトを作成して使うのは、実行時バインディングといいます。 事前バインディングの場合、(コンパイラにとって)あらかじめプロパティやメソッドに関する情報が得られるので、パフォーマンスが良くなります。 上記のような説明は、エクセルVBAのCreateObjectのヘルプに書いてあります。 >例のAPIのややこしい宣言文が今回のコードではなぜ必要でないのか? (説明が適切かちょっと自信がありませんが) APIを利用する方法は、ダイナミックリンク(DLL)による静的な結合と言えると思います。 ActiveXを利用する方法は、動的にオブジェクトを得る(作成する)方法で ActiveX自身がメソッドやプロパティの情報を提供できるからと思います。

ptano99
質問者

お礼

いろいろと貴重なヒントをありがとうございました。VBAのヘルプで、以下のようなものも見つけました。ヘルプは探したつもりでも、見えていないことがあるものですね。 <タイプ ライブラリへの参照設定> オートメーション (以前の OLE オートメーション) によって、別のアプリケーションにあるオブジェクトを Visual Basic コードの中から使用できます。別のアプリケーションで使用されるオブジェクトを提供するアプリケーションにも、タイプ ライブラリにあるオブジェクトに関する情報を提供しています。別のアプリケーションのオブジェクトを最大限に活用するには、そのアプリケーションのタイプ ライブラリへの参照を設定する必要があります。 ~(中略)~ 別のアプリケーションにあるオブジェクトを操作するコードを記述している場合、そのオブジェクトへのアクセスを最適なものにするため、そのアプリケーションのタイプ ライブラリへの参照を設定することをお勧めします。別のアプリケーションのオブジェクトを使用するのに、参照を設定することは必ずしも必要ではありませんが、(中略) 別のアプリケーションのオブジェクトを使用する前に、そのアプリケーションのタイプ ライブラリへの参照を設定しておくと、コードの実行速度が向上します。参照を設定すると、別のアプリケーションにあるオブジェクトを表すオブジェクト変数を最適な型で宣言できます。たとえば、Microsoft Excel オブジェクトを使用するコードを記述している場合、Microsoft Excel タイプ ライブラリへの参照を設定しているときは、Excel.Application 型のオブジェクト変数を宣言できます。Microsoft Excel Application オブジェクトを表す変数を作成する最も実行が速いコードを次に示します。 Dim appXL As Excel.Application Microsoft Excel タイプ ライブラリへの参照を設定していない場合は、オブジェクト型 (Object) の総称変数として変数を定義する必要があります。次のコードは、実行速度が遅くなります。 Dim appXL As Object (中略) オートメーション サーバーとしても機能する Microsoft アプリケーションでは、そのアプリケーションのタイプ ライブラリへの参照を別のアプリケーションで設定でき、そのオブジェクトを制御できます。

すると、全ての回答が全文表示されます。

その他の回答 (3)

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

#1>質問文中の一方のFolderオブジェクト(oFolder)はメンバがオブジェクトブラウザで確認できるのに… それ(oFolder)が、オブジェクトブラウザで確認できるのは、 ツールから参照設定でshell32.dllが参照設定されているからです。 参照設定で、Microsoft Scripting Runtime(scrrun.dll)を参照設定すればオブジェクトブラウザで確認できるようになります。 >VBで呼び出せるオブジェクトはすべてブラウザで確認できるのではないかと思っているのですが・・・。 参照設定をちゃんとすれば、ほとんどのオブジェクトをオブジェクトブラウザで確認できます。 >VBのヘルプには 多分、FSOのオブジェクトについて記載されているのだと思います。 #2様もおっしゃっていますが、ヘルプに全てのオブジェクトを載せるのはムリがあると思います。 MSDNの http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/objects/folder/folder.asp にシェルオブジェクトのフォルダーオブジェクトのヘルプがあります。 FSOについては、VBScriptとかのスクリプティングのドキュメント(日本語)がMSからダウンロードできます。それに詳しく載っています。 http://www.microsoft.com/japan/msdn/scripting/default.asp

ptano99
質問者

お礼

大変勉強になりました!!(つい英語のヘルプは敷居が高くて・・・。) ところで、参照設定することの意義は「オブジェクトブラウザで見るため」というのが本筋ではないですよね?プログラムの高速化とかと関係があるのでしょうか。小生は多分「参照設定」とか「オートメーション」とか「API関数」の関連性が理解できていないのでわからないのだと思いますが・・・(例のAPIのややこしい宣言文が、今回のコードではなぜ必要でないのか?など)。 できればそのあたりの参考先などをお教え願えませんでしょうか・・・。重ね重ねですみません・・・。

すると、全ての回答が全文表示されます。
回答No.2

※1.CreateObject("Shell.Application")のFolder ※2.CreateObject("Scripting.FileSystemObject")のFolder 名前が一緒なだけで、全く別物です。 プロパティも全く異なります。 Dim objShell Dim objSelectDir Set objShell = CreateObject("Shell.Application") Set objSelectDir = objShell.BrowseForFolder(0, "フォルダの選択", 0) MsgBox TypeName(objSelectDir) Dim objFso Dim objDir Set objFso = CreateObject("Scripting.FileSystemObject") Set objDir = objFso.GetFolder(Environ$("windir")) MsgBox TypeName(objDir) ヘルプはヘルプです。説明書ではありません。 全ての関数が網羅されているわけではありません。 >「しかもVBのヘルプには、逆に~が解説されており、いよいよ混乱しています。」 記憶があいまいですが、どっちもMSDNに解説されていたと思います。 (※1の詳細は英語版だったいような気が・・・) Excelのヘルプは、どっちが出ているかわかりませんが、、、

ptano99
質問者

お礼

ありがとうございます。 MSDN(英語のほう)調べてみましたが、Folderオブジェクトの、Shellのほうはすぐ出てくるのですが、FileSystemObjectのほうはなかなか引っかかりません。でSubfoldersプロパティのページからのリンクでやっとたどり着きました。勉強してみます。

すると、全ての回答が全文表示されます。
  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

ShellオブジェクトとFileSystemオブジェクトの違い(それぞれ別のActiveX)かと思います。 名前は同じFolderオブジェクトだけども、利用しているActiveX(プログラム)が違います。 つまり、プログラムの外に一般的なフォルダオブジェクトというのがあるのではなくて、 それぞれのプログラムで定義したフォルダオブジェクトだということかと思います。

ptano99
質問者

補足

早速のご回答誠にありがとうございます。 さらに追加質問みたいですみませんが、質問文中の一方のFolderオブジェクト(oFolder)はメンバがオブジェクトブラウザで確認できるのに、もう一方(folder1)はそのFolderオブジェクト自体が掲載されていない(当然subfoldersプロパティも載っていない)という事態はなぜ起きるのでしょうか?VBで呼び出せるオブジェクトはすべてブラウザで確認できるのではないかと思っているのですが・・・。 しかもVBのヘルプには、逆にオブジェクトブラウザに掲載されていないほうのFolderオブジェクトが解説されており、いよいよ混乱しています。 そもそもオブジェクトブラウザについてよくわかっていないので、恥ずかしい質問かもしれませんが、どうかもう少しお付き合いをお願いいたします。

すると、全ての回答が全文表示されます。

関連するQ&A