Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


2580 / 13646 ツリー ←次へ | 前へ→

【67086】すべてのフォルダ ミーコ 10/11/2(火) 22:14 質問[未読]
【67087】Re:すべてのフォルダ neptune 10/11/2(火) 22:43 発言[未読]
【67102】Re:すべてのフォルダ ミーコ 10/11/3(水) 21:37 質問[未読]
【67103】Re:すべてのフォルダ neptune 10/11/3(水) 22:41 回答[未読]
【67104】Re:すべてのフォルダ kanabun 10/11/4(木) 0:36 発言[未読]
【67106】Re:すべてのフォルダ kanabun 10/11/4(木) 2:08 発言[未読]
【67112】Re:すべてのフォルダ ミーコ 10/11/4(木) 20:33 お礼[未読]
【67113】Re:すべてのフォルダ kanabun 10/11/4(木) 21:00 発言[未読]
【67114】Re:すべてのフォルダ neptune 10/11/4(木) 22:46 発言[未読]

【67086】すべてのフォルダ
質問  ミーコ  - 10/11/2(火) 22:14 -

引用なし
パスワード
   C:\Documents and Settings\AAAの中にサブフォルダが10個あり、それぞれのサブフォルダには、エクセルブックが格納されています。

今したいのは、C:\Documents and Settings\AAAの直下及びサブフォルダに存在するすべてのエクセルブックを開きたいと考えていますが、どのようにコードを書けばよいかわかりません。
教えてもらえないでしょうか?
よろしくお願いいたします。

【67087】Re:すべてのフォルダ
発言  neptune  - 10/11/2(火) 22:43 -

引用なし
パスワード
   ▼ミーコ さん:
過去ログですが、同様の質問がありますからそちらを研究してみては如何?

ht tp://www.vbalab.net/vbaqa/c-board.cgi?cmd=one;no=58198;id=excel
ht tp://www.vbalab.net/vbaqa/c-board.cgi?cmd=ntr;tree=24228;id=excel
ht tp://www.vbalab.net/vbaqa/c-board.cgi?cmd=ntr;tree=48577;id=excel

【67102】Re:すべてのフォルダ
質問  ミーコ  - 10/11/3(水) 21:37 -

引用なし
パスワード
   ▼neptune さん:

チャレンジしてみましたが、難しすぎて手に負えませんでした。
VBAを学び始めてからまだ期間が浅いもので。

X = Dir ("C:\Documents and Settings\AAA\" , vbdirectory)
Y = Dir (X & "*.xls")

Do while Y <> ""
 処理
 Y = dir()
loop


を使ってやればいいのかなというところまでは行き着いたのですが
どうもうまく実行できなくて…。
申し訳ありませんが、どうすれば正しく動くようになるのか教えていただけないでしょうか?

【67103】Re:すべてのフォルダ
回答  neptune  - 10/11/3(水) 22:41 -

引用なし
パスワード
   ▼ミーコ さん:

>チャレンジしてみましたが、難しすぎて手に負えませんでした。
はい、手法としては初心者の方には難しいです。
その難しいことをやろうとしているのですからしっかり理解してくださいね。

で、おそらくそのまんま使えそうなプログラムが下記にUPしてくれています。
【48618】Re:複数フォルダの全ファイル取得方法  ichinose - 07/4/25(水) 19:52 
ht tp://www.vbalab.net/vbaqa/c-board.cgi?cmd=ntr;tree=48577;id=excel#48618

このプログラムではファイルのパスはイミディエイトウィンドウに出力
されます。

その出力先をミーコ さんのお好きなところに変えるだけだと思います。
勿論、
・対象フォルダパスは変更する必要があります。
・拡張子がxlsである事を判断する必要があります。
 VBAのRight 関数又は、filesystemobjectのGetExtensionName メソッド
 を利用すると良い。Right 関数の方が簡単と思います。
 ht tp://msdn.microsoft.com/ja-jp/library/cc428060.aspx

>VBAを学び始めてからまだ期間が浅いもので。
上記2点はヒントを書いたから↑でもやればできるはずです。

また、ご自分で挑戦してみてわからなければ聞いて下さい。

【67104】Re:すべてのフォルダ
発言  kanabun  - 10/11/4(木) 0:36 -

引用なし
パスワード
   ▼ミーコ さん:
こんにちは。
▼neptune さん、横入り失礼しますm(_ _)m
> ▼neptune さん:
>
> チャレンジしてみましたが、難しすぎて手に負えませんでした。
> VBAを学び始めてからまだ期間が浅いもので。
>
> X = Dir("C:\Documents and Settings\AAA\", vbDirectory)
> Y = Dir(X & "*.xls")
>
> Do While Y <> ""
>  処理
>  Y = Dir()
> Loop

あるフォルダ内の*.xlsファイルだけリストをとるのなら、
VBAの 「Dir関数」のLoopが簡単ですが、
サブフォルダもいっしょに、となると、いわゆる再帰処理
を書かないといけないので初心者にはすこし難しいです。

ところが、
同じ Dir でも、DOS-プロンプトの「DIRコマンド」を使うと
これがパラメータ /s を使うだけで、サブディレクトリ内の
ファイルも同時に検索してくれます。
しかも高速に(^^

スタートメニュ−の[コマンドプロンプト]で
dir "C:\Documents and Settings\AAA\*.xls" /s /b /o:D
とタイプして[Enter]してみてください。
画面に
C:\Documents and Settings\AAA\ 直下とサブディレクトリ内の
すべての*.xlsファイルがリストされるはずです。
/のあとにオプションを
 /s が サブディレクトリも検索するオプション
 /b は ファイルのみ表示するオプション(日付やサイズは表示しない)
 /o はファイルリストの表示順を指定するオプションで、
  /o:N とすると、ファイル名順、
  /o:S とすれば、ファイルサイズの小さい順、
  /o:-S とすると、サイズの大きい順(降順)、
  /o:D なら Date順つまり古い方から、
 /o:-D なら 新しい更新日時順
など、
指定することにより、Dir関数や Fso では難しかった
サブディレクトリの検索やファイルリストの指定順でソートなど
パラメータをセットするだけで、やってくれますので、
これを利用しない手はないと思います。

ただ、
DOS窓にリストされても、Excelに取り込みようがないので、
dir "C:\Documents and Settings\AAA\*.xls" /s /b /o:D >"C:\dirList.txt"
のようにすると、画面に表示する代わりに > のあとに指定した
ファイルに書き出してくれます。

以上のことを確認されたら、それをVBA上で実行して
指定フォルダの(サブフォルダも含めた)*.xlsファイルの
リストが取得できるように、DIRコマンドをつかうマクロを
書いてみましょう。
↓こんな感じです。(エラー処理は入れてません。)

'------------------------------------ 標準モジュール
Option Explicit
Sub Try1()
 Dim i As Long
 Dim fList() As String
 
 ''検索パスとファイル拡張子を指定してSubDir付き検索
 fList = SubDir("C:\Documents and Settings\AAA\*.xls")
 
 For i = 0 To UBound(fList)
   Debug.Print fList(i)
 Next
  
End Sub

'サブフォルダを含むファイルの検索(ファイルリストを返す)
Private Function SubDir(Filename As String) As String()
  Dim v
  Dim tmpPath As String
  Dim sCmd As String
  Dim ko As Long
  
  tmpPath = Environ$("Temp") & "\Dir.tmp"
  sCmd = "DIR """ & Filename & """ /b/s /o:N > """ _
      & tmpPath & """"
  With CreateObject("WScript.Shell")
    ko = .Run("CMD /C " & sCmd, 7, True) 'Dirコマンド実行
  End With

  Dim io As Integer
  Dim buf() As Byte
  io = FreeFile()
  Open tmpPath For Binary As io '出力ファイルリスト取得
   ReDim buf(1 To LOF(io))
   Get #io, , buf
  Close io
  Kill tmpPath
  SubDir = Split(StrConv(buf, vbUnicode), vbCrLf)
End Function
'--------------------------------------------------
上は
Dir検索結果得られたフィル名リストをイミディエイト・
ウィンドウに表示しているだけですが、

>   Debug.Print fList(i)

ここを

  Set Wb = Workbooks.Open(fList(i))
  '開いたファイルに対する処理 〜〜〜 〜〜〜
  Wb.Close SaveChanges:=True
  Set Wb = Nothing

のように、処理を追加していけばいいでしょう。

【67106】Re:すべてのフォルダ
発言  kanabun  - 10/11/4(木) 2:08 -

引用なし
パスワード
   ちょっと余談です。

ご存知かもしれませんが、Excelには
C:\Documents and Settings\AAA 内を
・サブフォルダも含めて
・すべての *.xls ファイルを
・ファイル名または日付順またはサイズ順にソートして
検索してくれるメソッドがあるんです。
Application.FileSearch というのがそれです。
ところが、これがやたら検索に時間がかかる。
それどころか、Excel2007以降、この機能はサポートされなくなって
しまいました。
それで2007年以降、FileSearch代替メソッドに関する質問が
掲示板をにぎわすことになったのですが、Fso は ファイル名の
ワイルドカードが使えないし、動作が(FileSearchほどではないけど)
のろいということもあり、Dir関数のLoopとか 速度を求めるために
FindFile APIがよく紹介されるんですが、サブディレクトリの検索
のために、先述したように再帰処理を使うので、初心者には敷居が
高い。
ということで、ぼく自身は 最近↑「DIRコマンド」のほうをよく紹介
している訳なんです。

【67112】Re:すべてのフォルダ
お礼  ミーコ  - 10/11/4(木) 20:33 -

引用なし
パスワード
   ▼kanabun さん:

ありがとうございました。
おかげさまでなんとか自分のプログラムに組み込み
完成させることができました。

しかし、私にはとても難しいプログラムです・・・。

【67113】Re:すべてのフォルダ
発言  kanabun  - 10/11/4(木) 21:00 -

引用なし
パスワード
   ▼ミーコ さん:

>おかげさまでなんとか自分のプログラムに組み込み
>完成させることができました。
>
>しかし、私にはとても難しいプログラムです・・・。

MS-DOSの時代にはコマンドラインから
C:\>DIR C:\DATA\*.XLS /B/S
ってやればサブディレクトリを含む*.xlsファイルの一覧が
とれたのに、高機能になったExcelでも WindowsのAPI関数でも
一発でこれをやってくれる命令というか関数がないのは
不思議ですよね?

やりたい処理はBookを開いてからのほうにあるのでしょうから、
その前段階のファイルリストの取得にいつまでも時間を割くのは
もったいないと思いました。
現段階では、
出来合いのApplication.FileSearchメソッドか、上記DIRコマンドで
今は済ませておいて、Bookを開いてからの処理内容の吟味に
関心を集中してください。

では(^^

【67114】Re:すべてのフォルダ
発言  neptune  - 10/11/4(木) 22:46 -

引用なし
パスワード
   ▼ミーコ さん:
>しかし、私にはとても難しいプログラムです・・・。
そう思います。

以下私見です。

下記にほとんどそのまんま、出力先さえ変更すればよいサンプルがあります。

----------Dir関数------------
「再帰的プログラミングとは」
ht tp://kozhouse.homeip.net/progtec/14/
「フォルダ下のファイル名を再帰的に取得する」
ht tp://www3.kcn.ne.jp/~wataru/vb/file.htm

----------FileSystemObject--------------------
「再帰的にサブフォルダまでファイルを列挙する方法」
ht tp://www.tsware.jp/tips/tips_478.htm

他にも「VB ファイル検索 再帰」でググればた〜くさんサンプルはあります。
VB6とか書いていても、検索部分に関して言えば同じです。

個人的にはDir関数をお勧めします。
・FileSystemObjectより断然早い・・・VBのファイル、フォルダ検索用の関数である。
・VBAが存在する限り恐らく無くならないであろう関数である。
・APIもあるけど、更に難しくなるので初心者にはお勧めできない。
 但しドライブ全部を検索するとか何万件以上も検索するのであれば時間を費やす価値はある。
・恐らく初心者、若い人にはDOSコマンドってのはなじみがないはずだし、
 もう知らなくても不自由はしない時代でもある。

簡単なのはFileSystemObjectでキチンとHelpさえ読めばたくさん便利な
メソッドやプロパティがあり、とっつきやすいと思います。
但し、kanabunさんもご指摘のようにワイルドカードを使った検索
は出来ない。元々検索目的ではなくファイル操作目的のオブジェクトであるので。

最も大切なのは、近頃のPCは速いので処理速度云々よりご自分で理解できた方法で
やるのが肝要かと思います。
でなければ、ちょっと改造といってもまた、誰かにやってもらわねばなりませんからね。

できればdir関数かFileSystemObjectでの再帰の手法を理解する事をお勧めします。

但し、プログラミングが今回の処理だけでこれができたらもう良いという場合は
この限りではありません。

解決後失礼しました。

2580 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free