For Eachで実行時エラー424が発生する理由

まず最初に実行時エラー424の基本的な対応方法については「エラー424対応方法(オブジェクトが必要です)」に記載しています。ここではFor Eachを使ってエラーが発生した場合について対応方法を書いています。

ループ処理の書き方にはいくつかの方法がありますが、その1つがFor Eachです。

For Eachは配列や複数データを持つオブジェクトなどの「データの集まり」を1件ずつ取得しますが、その1件のデータを格納する変数が必要になります。このループごと変数に格納する際に実行時エラー424が発生することがあります。

これは、格納先のデータ型が格納元の「データの集まり」が持つデータ型と異なることが原因です。

以下のコードは実行時エラー424が発生します。詳細は後述します。



実行時エラー424の原因

エラーが発生するサンプルコードで、なぜ実行時エラー424が発生するのかを説明します。

なお、以下のコードを動かすにはDictionaryオブジェクトを利用しているため、事前にVBA画面→ツールメニュー→参照設定、を選択し、参照設定ダイアログで「Microsoft Scripting Runtime」にチェックを付ける必要があります。

このコードは、格納元であるDictionaryオブジェクト(変数dic)に4件のデータを追加し、それをFor Eachループで回して、oFile変数にループ1回ごとに格納したい、という内容です。

DictionaryオブジェクトのItemsプロパティをFor Eachで回すと、Dictionaryオブジェクトのキーが返されます。このコードの場合、「”C:\a.txt”」「”C:\b.txt”」「”C:\c.txt”」「”C:\d.txt”」の4件が4回のループそれぞれで取得できます。

この「”C:\a.txt”」などはファイルパスを表していますが、ファイルパスである前に文字列のデータです。

そのため、VBAの実行時に「文字列をFileデータ型にコピーしようとしてもできないからエラーです。ファイルパスなのかもしれんけど、正しいファイルパスかどうかまだわからんしそれ以前の問題やし」という意味のエラーとして実行時エラー424が発生します。

「Fileオブジェクト = 文字列」という代入がダメ、というわけです。

「Set oFile = “abc”」と書いてOKか?と言われると、”abc”は全然ファイルじゃないしそりゃダメよね、って理屈です。

でも、言いたいことは分かります。「ファイルパスなんだからFileオブジェクトに格納してよ」と。これは別の書き方で解消しなければなりません。それを後述します。


ファイルパス文字列をFileオブジェクトに入れる方法

上のコードの場合の解消方法は、FileSystemObjectのGetFileメソッドです。GetFileメソッドは文字列をFileオブジェクトに変換します。

この方法で実行時エラー424を解消したコードが以下になります。

For EachのループではDictionaryのItemsプロパティではなくKeysプロパティを使って、キー文字列を取得します。このとき、キーが文字列かどうか分からないため、格納する変数のデータ型はVariant型でなければなりません。String型にしたいところですが、Dictionaryのキーが文字列かどうかはこの時点では確証が得られないためエラーになります。

あとは取得したキー文字列であるsPath変数のファイルパスが実際に存在するかをFileSystemObject.FileExistsメソッドで判定します。存在していれば、FileSystemObject.GetFileメソッドでFileオブジェクトに変換しています。

これでデータ型の不整合が解消され、実行時エラー424が出なくなります。

なお、GetFileメソッドについての詳細は「FileSystemObjectのGetFileメソッド」をご参照ください。



実行時エラー424はコピー元と先のデータ型が違う

上のコードはFor Eachの行でFileオブジェクトに文字列を代入しようとして実行時エラー424になる例ですが、別のデータ型の場合も同様です。

違うデータ型同士の代入は、同じデータ型になるような変換をしてあげる必要があります。

Fileオブジェクトに文字列のファイルパスを設定したい場合はFileSystemObject.GetFileメソッド、というように、他のデータ型でも文字列から変換する関数が大抵用意されています

例えば、日付を表すDate型に文字列の日付”yyyy/mm/dd”を格納したい場合はCDate関数を使う、などです。

ちなみ、Date型と日付文字列の変換については以下をご参照ください。
・「VBAで日付(Date型)から文字列に変換する
・「VBAで文字列から日付(Date型)に変換する

実行時エラー424が発生した場合は、そのような変換関数がないか探してみてください