電子書籍の厳選無料作品が豊富!

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

A 回答 (4件)

#3>参照設定することの意義


良くわからない、ActiveXのプロパティやメソッドを調べるためにオブジェクトブラウザを使う場合がありますが、
一般的には、参照設定することで、
dim oFolder as Folder
のように、エディタで as としての候補としてでてくるコードを補ってくれるので便利ということや、あらかじめそのクラスのオブジェクトを宣言できる。(コレを事前バインディングといいます)というような意味合いがあると思います。
逆に、CreateObjectによってオブジェクトを作成して使うのは、実行時バインディングといいます。
事前バインディングの場合、(コンパイラにとって)あらかじめプロパティやメソッドに関する情報が得られるので、パフォーマンスが良くなります。

上記のような説明は、エクセルVBAのCreateObjectのヘルプに書いてあります。

>例のAPIのややこしい宣言文が今回のコードではなぜ必要でないのか?
(説明が適切かちょっと自信がありませんが)
APIを利用する方法は、ダイナミックリンク(DLL)による静的な結合と言えると思います。
ActiveXを利用する方法は、動的にオブジェクトを得る(作成する)方法で
ActiveX自身がメソッドやプロパティの情報を提供できるからと思います。
    • good
    • 0
この回答へのお礼

いろいろと貴重なヒントをありがとうございました。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 アプリケーションでは、そのアプリケーションのタイプ ライブラリへの参照を別のアプリケーションで設定でき、そのオブジェクトを制御できます。

お礼日時:2005/08/21 02:34

#1>質問文中の一方のFolderオブジェクト(oFolder)はメンバがオブジェクトブラウザで確認できるのに…


それ(oFolder)が、オブジェクトブラウザで確認できるのは、
ツールから参照設定でshell32.dllが参照設定されているからです。
参照設定で、Microsoft Scripting Runtime(scrrun.dll)を参照設定すればオブジェクトブラウザで確認できるようになります。

>VBで呼び出せるオブジェクトはすべてブラウザで確認できるのではないかと思っているのですが・・・。
参照設定をちゃんとすれば、ほとんどのオブジェクトをオブジェクトブラウザで確認できます。

>VBのヘルプには
多分、FSOのオブジェクトについて記載されているのだと思います。
#2様もおっしゃっていますが、ヘルプに全てのオブジェクトを載せるのはムリがあると思います。
MSDNの
http://msdn.microsoft.com/library/default.asp?ur …
にシェルオブジェクトのフォルダーオブジェクトのヘルプがあります。

FSOについては、VBScriptとかのスクリプティングのドキュメント(日本語)がMSからダウンロードできます。それに詳しく載っています。
http://www.microsoft.com/japan/msdn/scripting/de …
    • good
    • 0
この回答へのお礼

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

お礼日時:2005/08/18 08:18

※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のヘルプは、どっちが出ているかわかりませんが、、、
    • good
    • 0
この回答へのお礼

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

お礼日時:2005/08/18 08:05

ShellオブジェクトとFileSystemオブジェクトの違い(それぞれ別のActiveX)かと思います。


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

この回答への補足

早速のご回答誠にありがとうございます。

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

補足日時:2005/08/17 17:06
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!