こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ダイアログボックスで複数フォルダの複数ファイルの選択

ダイアログボックスで複数フォルダの複数ファイルの選択がうまくいきません。
単一フォルダ内からの複数ファイルの選択は機能しているのですが、ダイアログボックスで他のフォルダを選択して他のファイルを選択すると最終的に選択したファイルのみが残り、先に選択した分が累積されません。  OpenFileNameが上書きされるのが原因な気がするのですが配列への累積処理が解りません。
その後の処理で選択したファイルを全て開いて加工したいので、累積させる方法を知りたいのです。下記コードはLoop処理で行おうとして累積が解らないままのものです。
一度のダイアログ表示で複数フォルダの複数ファイルを選択出来る方法があればそれでもかまいません。どなたか助けては頂けないでしょうか。お願いします。

'**明細の選択(複数同時)**
Do
BN = Application.InputBox("対象明細書の年月を入力してください。1桁の月は02月のように入力)", , Default:="2009.04", Type:=2)
If BN = False Then '入力なければ
GoTo OWARI
End If
WorkPath = ThisWorkbook.Path & "\明細書一覧" & BN & "月"
ChDrive WorkPath
ChDir WorkPath

OpenFileName = Application.GetOpenFilename(FileFilter:="Microsoft Excelブック,*.xls", _
Title:="対象の明細書を選んで下さい。Ctrlキーを押しながら複数ファイルを同時に選択出来ます。", MultiSelect:=True)

Rtn = MsgBox("他にも対象ファイルがありますか?", vbYesNo, "選択")
If Rtn = vbNo Then
Exit Do
End If
Loop

Mypath = ThisWorkbook.Path
MyFile = "\請求制御.xls" 'ここにファイル名記入
If IsArray(OpenFileName) Then
For i = 1 To UBound(OpenFileName)
If OpenFileName(i) = Mypath & MyFile Then
MsgBox "同じファイルが含まれてます。", vbInformation, "同じファイルは選択出来ません"
GoTo OWARI
End If
tmp = tmp & Dir(OpenFileName(i)) & vbCrLf
Next
MsgBox vbCrLf & tmp & vbCrLf & "の全" & i - 1 & "枚です" & vbCrLf & "これらでよろしいですか? ", vbInformation, "選択したファイルは "

投稿日時 - 2009-05-07 21:32:34

QNo.4939802

困ってます

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

方法はいくつかあるでしょうが、Collectionを使ったサンプル。
但し、質問者提示のコードは動作しているものとする。


'=====================
'●●●変数宣言
  Dim myGetFiles As New Collection
  Dim mySelectFile
'---------------------

Do
BN = Application.InputBox("対象明細書の年月を入力してください。1桁の月は02月のように入力)", , Default:="2009.04", Type:=2)
If BN = False Then '入力なければ
GoTo Owari
End If
WorkPath = ThisWorkbook.Path & "\明細書一覧" & BN & "月"
ChDrive WorkPath
ChDir WorkPath

'--------------------------------------
'●変数を、mySelectFile に変更

mySelectFile = Application.GetOpenFilename(FileFilter:="Microsoft Excelブック,*.xls", _
Title:="対象の明細書を選んで下さい。Ctrlキーを押しながら複数ファイルを同時に選択出来ます。", MultiSelect:=True)

'●●●選択ファイルをCollectionに登録

 If IsArray(mySelectFile) Then
   myGetFiles.Add mySelectFile
 End If
'-------------------------------------


Rtn = MsgBox("他にも対象ファイルがありますか?", vbYesNo, "選択")
If Rtn = vbNo Then
Exit Do
End If
Loop


'●●●Collectionの展開
'-----------------------------

 If myGetFiles.Count = 0 Then
   MsgBox "ファイルがひとつも選択されていないよ!"
   GoTo Owari '●ここは適宜修正のこと
 End If


Mypath = ThisWorkbook.Path
MyFile = "\請求制御.xls" 'ここにファイル名記入

'●下記のように展開する-------

 For Each OpenFIleName In myGetFiles
   For i = UBound(OpenFIleName) To UBound(OpenFIleName)
     If OpenFIleName(i) = Mypath & MyFile Then

   ・・・・・以下省略・・・・・・

==========================

なお、質問提示のコードにあった
>If IsArray(OpenFileName) Then
これはここでは不要、Collectionに登録するときチェック済
 
 

投稿日時 - 2009-05-08 14:10:59

補足

myRangeさん ありがとうございます。
Collectionで試してみることにしました。
ご提示の
For i = UBound(OpenFIleName) To UBound(OpenFIleName)を
For i = LBound(OpenFIleName) To UBound(OpenFIleName)に

変えさせて頂き、動いております。
その後の全選択枚数のためにカウンタを加え(上記コードの直下にcnt=cnt+1)枚数を出しているのですが、更にその後の処理で選択したファイルを開く過程があるのですが、OpenFIleName(i)では開けないので、どこの段階でどのような配列に入れればよいかが解りません。つまづいております。助けてはもらえませんか?

投稿日時 - 2009-05-08 15:27:23

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

>二回目以降の選択ファイルも配列内に組み入れ開けるようにしたい

そのためのコードですよ。。。(^^;;;

>For i = LBound(OpenFileName) To UBound(OpenFileName)は1To3となってしまい(ダイアログ二回目以降のファイルが反映されない)

それは1回目(3個選択)の選択ですからそうなるのは当然です。
1回目と2回目でそこは違ってくるのです。

まだCollectionの中がどうなってるか理解されてないようなので
  1回目:ファイルを3個選択
  2回目:ファイルを1個選択
全部で4個選択した場合で説明します。

1回目: myGetFiles(1) に、File1,File2,File3 が入る
2回目: myGetFiles(2) に、File4 が入る

この状態で下記のコードは、、

For Each OpenFileName In myGetFiles
  For i = LBound(OpenFileName) To UBound(OpenFileName)

●先ず、myGetFiles(1) が OpenFileName に入る
myGetFiles(1) には、File1,2,3が入っているので
For i = LBound(OpenFileName) To UBound(OpenFileName)
これは、
For i= 1 to 3
になる

●次に、myGetFiles(2) が OpenFileName に入る
myGetFiles(2) には、File4 がひとつ入っているので
For i = LBound(OpenFileName) To UBound(OpenFileName)
これは、
For i= 1 to 1
になる

どうですか、ちゃんと4個のファイルを呼び出していますよね。

For Each OpenFileName In myGetFiles
  For i = LBound(OpenFileName) To UBound(OpenFileName)

要するに、この2行で、4個のファイルを呼び出しているわけです


●これでも納得がいかない場合は、修正した現在のコードを

---------------------------------
'**明細の選択(複数同時)**
Do
BN = Application.InputBox("対象明細書の年月を入力してください。1桁の月は02月のように入力)", , Default:="2009.04", Type:=2)

この部分からファイルを読み込むところまで全て省略しないでアップしてください。
 
ここまでくれば完成したようなものです。
 

投稿日時 - 2009-05-08 22:39:10

お礼

myRangeさんへ あれれ本当だ。何度もチェックしたつもりだったのですが、きっと同じ動作の作りかけプロシージャが隣のモジュールにあったのでそちらをチェックしていたのだと思います。
動いてます。ありがとうございました。
何度も、また遅くまでお付き合い下さったこと。そして具体的なコード及び解説まで下さり本当に感謝しております。今回のはまだ作りかけですのでこの先も近々行き詰る気がします。その際は、yokokama46
(本当はyokohama46と入力したかったけどうっかりさんなので)を質問コーナーで見かけたらまた相手して下さい。助かりました。

投稿日時 - 2009-05-08 23:48:29

ANo.4

いま帰宅。
ちょと気になって覗いてみたら。。。(^^;;;

>’●選択したファイル開く
>For i = 1 To cnt
>Workbooks.Open OpenFileName(i)   ←ここで実行時エラー 13
> 型が一致しませんとなります

それは当然のことです。
回答2のCollectionの展開にはどう書いてありますか?

 For Each OpenFIleName In myGetFiles
   For i = UBound(OpenFIleName) To UBound(OpenFIleName)

となってますよね。
そして、質問者は、’●myGetFilesのチェックではちゃんと

cnt = 0
For Each mySelectFile In myGetFiles
For i = LBound(mySelectFile) To UBound(mySelectFile)

こうやってますよね。
なのになぜ、ファイルをオープンするときは、

For i = 1 To cnt
Workbooks.Open OpenFileName(i)

と、For i=1 to cnt とするのでしょうか。

それから変数OpenFileNameは質問者が提示したコードにありますので
それを極力使うようにした方がいい、と当方が考えてのことです。
(変数mySelectFileはCollectionの登録のときのみ使用)
よって、変数も当方の回答のとおり使うようにしてください。
(もちろん今回のエラーは変数の問題ではありませんが)


'---------------------------------------
’●myGetFilesのチェック

▲▲変数mySelectFileをOpenFileNameに変更した▲▲

cnt = 0
For Each OpenFileName In myGetFiles
 For i = LBound(OpenFileName) To UBound(OpenFileName)
   cnt = cnt + 1
   If OpenFileName(i) = Mypath & MyFile Then
     MsgBox "同じファイルが含まれてます。", vbInformation, "同じファイルは選択出来ません"
     GoTo OWARI
   End If
   tmp = tmp & Dir(OpenFileName(i)) & vbCrLf
 Next i
Next OpenFileName

’●選択したファイルの一覧化及び数量の表示
MsgBox vbCrLf & tmp & vbCrLf & "の全" & cnt & "枚です" & vbCrLf & "これらでよろしいですか? ", vbInformation, "選択したファイルは "


’■■■選択したファイル開く■■■

For Each OpenFileName In myGetFiles
 For i = LBound(OpenFileName) To UBound(OpenFileName)

   Workbooks.Open OpenFileName(i)  

'-----------------------------------------------

これでお分かりでしょうか?
それから、前の回答の質問に答えてないとところがありますよ。
 
>>どこの段階でどのような配列に入れればよいかが解りません

>また、これも言いたいことが分かりません。
>何を配列に入れるのかそれを提示してもらわないと。。

これにもちゃんと答えてもらわないといけませんね。
 

●Collectionの中がどうなっているのか理解してますか?

ま、この回答で完璧に理解できたとは思いますが。
理解できない部分があったら、遠慮なく質問すること。
 
頑張ってください。
 

投稿日時 - 2009-05-08 20:15:42

補足

myRangeさん 何度もおつきあい有難うございます。
For Eachで開けということですよね。そうですね。理解しました。
しかし数が合わないのです。ダイアログからのファイル選択をDo Loopでまわして、つど追加という流れなのですが、UBound(OpenFileName)は常にダイアログ1回目の選択ファイル数にしかならないのです。(一回目3ファイル選択で二回目1ファイル選択だと3となり) ←4になってほしい   選択ファイルを開く部分の
For i = LBound(OpenFileName) To UBound(OpenFileName)は1To3となってしまい(ダイアログ二回目以降のファイルが反映されない)
よって開けるファイルは一回目のダイアログでの選択ファイルのみになってしまいます。
(私が間違っているのかもしれませんが)ために今回の例では1To4になるようにさせるために、別途配列に組み入れる必要があるのかなと(ReDim Preserve等で)思い
>どこの段階でどのような配列に入れればよいかが解りません
などと書き込んだのです。何か私が単純なミスでもしているのであればよいのですが。二回目以降の選択ファイルも配列内に組み入れ開けるようにしたいのです。すみませんの連発ですが、何卒見捨てずにお付き合いお願いします。

投稿日時 - 2009-05-08 21:18:20

ANo.3

No2,myRangeです。
タイプミスがあったようですね。
ま、それはご愛嬌ということで。。(^^;;;

>選択したファイルを開く過程があるのですが、OpenFIleName(i)では開けないので

 Workbooks.Open OpenFileName(i)

これで開けますよね?
これでは何か拙いことでもあるのでしょうか?
そこらは質問者以外は分かりませんので、補足が必要でしょう。


>どこの段階でどのような配列に入れればよいかが解りません

また、これも言いたいことが分かりません。
何を配列に入れるのかそれを提示してもらわないと。。


何れにしろ、処理の流れ(最初のは解決したので、その後の流れ)が
明確に読者に伝わるように詳しく説明するべきでしょう。
 

投稿日時 - 2009-05-08 17:12:41

補足

myRangeさん お手数かけてすみません。
Workbooks.Open OpenFileName(i) で開こうとすると実行時エラー 型が一致しませんとなります。

その後の流れは、

’●myGetFilesのチェック
cnt = 0
For Each mySelectFile In myGetFiles
For i = LBound(mySelectFile) To UBound(mySelectFile)
cnt = cnt + 1
If mySelectFile(i) = Mypath & MyFile Then
MsgBox "同じファイルが含まれてます。", vbInformation, "同じファイルは選択出来ません"
GoTo OWARI
End If
tmp = tmp & Dir(mySelectFile(i)) & vbCrLf
Next
Next
’●選択したファイルの一覧化及び数量の表示
MsgBox vbCrLf & tmp & vbCrLf & "の全" & cnt & "枚です" & vbCrLf & "これらでよろしいですか? ", vbInformation, "選択したファイルは "
’●選択したファイル開く
For i = 1 To cnt
Workbooks.Open OpenFileName(i)   ←ここで実行時エラー 13 型が一致しませんとなります。mySelectFile(i)に変更しても同じ結果でした。
なんとなくではありますが、myGetFilesに入れているのでその段階でOpenFileName(i)もmySelectFile(i)も情報を持たなくなっているのかな?と素人ながら思ってる次第です。お願いばかりですが、なんとか教えてはもらえないでしょうか?お願いします。

投稿日時 - 2009-05-08 17:55:15

ANo.1

ダイヤログボックスにはご希望の機能はありません。
ダイアログボックスが開いた時点でバッファーがクリアされるので、その都度別の方法で取得して配列に保存するしか無いと思います。

投稿日時 - 2009-05-07 21:57:43

お礼

hana-hana3さん 早速の回答有難うございます。
そうだったんですか。
では、提示コードのようにDo~Loopでダイアログを廻し、複数選択したときは複数を配列に順次累積させて行きたいのですが、また提示コードのようにその選択の結果のファイル名一覧及び件数をMsgBoxで表示させたいのですが、良きコードを教えて頂ければ幸いです。
お礼と共にお願いまでいたしまして恐縮ですが、良ければご教示願えませんでしょうか?

投稿日時 - 2009-05-07 22:19:15

あなたにオススメの質問