2013年04月14日

配列の手順を使ってフォルダ内のファイルの情報を取得する

■配列の手順を使ってフォルダ内のファイルの情報を取得する

お久しぶりです。
ネタ切れと自作プログラム&怠け癖のせいで、しばらく更新していませんでした。

視覚障害者のWindows活用ML
http://www.j7p.net/ml/windows/

に投稿された質問への回答というか、出しゃばりで投稿しようと思っていたプログラムを掲載します。
質問の内容は、フォルダ内のファイル数と、特定のファイル形式、たとえば Word/Excel/txt のファイルがどれくらいあるのかを知りたいというものでした。
質問の方は、別の方法で一応解決したらしいので、結局投稿はしませんでしたが、プロデルの配列の手順についての説明にもなるのではと思ってアップすることにします。

■プログラムの概要

このプログラムでは、フォルダ内の

@サブフォルダの数
Aファイル数
Bファイルの合計サイズ
CWord/Excel/テキスト 形式の それぞれのファイル数

をメッセージボックスで表示し、同時にクリップボードにコピーします。

また、「起動時設定」の手順を加えていますので、実行ファイルのショートカットを「sendto」フォルダにコピーすれば、送るメニューから実行することも可能です。
※ただし、Cドライブや Dドライブなど、ドライブのルートを指定することは出来ません。

このプログラムの難点は、処理速度が遅いことです。フォルダ内のファイル数が増えると、とにかく表示&コピーまで時間がかかります。ちゃんと動いていないんじゃないか? と思ってしまうケースもあります。

◆動作環境情報◆
プロデル 1.1.486
Windows 7 Professional Edition(64)
メモリ:3.10 GB

ここからプログラム
──────────────────────────────
プログラムのタイトルは、「フォルダ情報」

ーー起動時設定(送るメニュー用)
もし、(プログラムの起動時設定)が無でないなら
//送るメニューから起動していれば

配列は、プログラムの起動時設定
//Explorerで選択された項目を配列の形で取得します。

フォルダ名は、「[配列(1)]\」
//選択された項目が1個の場合は、配列の個数も1個なので、
//配列の1番目の要素が目的のフォルダ名になります。
//普通は選択される数は1個ですが、複数の項目が選択されても、
//そのうち1個だけしか処理しません。
//この時、取得されるパスの末尾には \ が付いていないので、
//ここで \ を付けて[フォルダ名]という変数に格納します。

フォルダ判定は、正規表現によってフォルダ名から「\.(.*)」を取り出したもの
//拡張子の有無で、簡易的にフォルダかどうかを判定しています。
//例外的に拡張子の無いファイルも存在しますが、ここでは無視。

もし、フォルダ判定が「{}」でないなら
//パスの中に拡張子が無ければ、[フォルダ判定]は「{}」=空 となり、
//パスをフォルダのパスとして、次の処理に移りますが、
//拡張子が含まれていれば、[フォルダ判定]は「{1}」となるため、
//その場合は、次のメッセージを表示して処理を中止します。

「これはフォルダではありません。」を表示する
終了する
//フォルダでない=ファイルが選択されていたらプログラムを終了します。
//「手順から抜ける」としたいのですが、この場所では
//「抜ける」が使えないため、「終了する」にしています。

もし終わり //フォルダ判定 終わり

でないなら //送るメニューから起動していなければ
フォルダ選択画面を表示する
//送るメニューからの起動ではなく、普通にプログラムが起動された場合は、
//フォルダ選択画面を表示します。

もしフォルダ選択画面のキャンセルなら、終了する
//普通のプログラムだと「抜ける」を使うことが多いのですが、
//上で述べたように、この場所では使えないのと、
//プロセスを残さないために終了させます。

フォルダ名は、フォルダ選択画面のフォルダ名
//フォルダ選択画面で取得されるパスの末尾には \ が付いているので、
//そのまま[フォルダ名]という変数に格納します。

もし終わり
//送るメニューから起動されたかどうかの判定をここで終わります。

フォルダ一覧は、フォルダ名のフォルダの全一覧
//上の手順で格納した[フォルダ名]の中のサブフォルダの全一覧を取得します。
//「全一覧」はサブフォルダも含めた子フォルダの一覧、
//「一覧」は、サブフォルダを含めない直下のサブフォルダの一覧です。
//ここで取得したサブフォルダの一覧(=配列)を、
//[フォルダ一覧]という変数に格納します。

フォルダ数は、フォルダ一覧の個数
//[フォルダ一覧]の配列の数=サブフォルダの個数を、
//[フォルダ数]という変数に格納します。

ファイル一覧は、(フルパスで「[フォルダ名]」のファイルの全一覧)
ファイル数は、ファイル一覧の個数
//フォルダ内のファイルの全一覧を取得して、その個数を求めます。
//サブフォルダの個数を取得する時と同じ手順です。
//ファイルの全一覧の個数を、[ファイル数]という変数に格納します。
//個数を求めるだけなら フルパスで と指定する必要はないのですが、
//次の手順で必要になるため フルパスで と指定しています。

サイズ配列は、{}
//取得したファイルのサイズを格納するために、あらかじめ配列を作成しておきます。

ファイル一覧を要素にそれぞれ繰り返す
要素のサイズを、サイズ配列に加える
//ここでファイルのサイズを取得するために フルパス が必要になります。
//配列の要素=ファイルのフルパスから、そのサイズを求めます。
//取得したサイズを、あらかじめ作成しておいた[サイズ配列]に
//追加して(加えて)いきます。

繰り返し終わり

値Aは、サイズ配列の合計
//サイズ配列の要素=各ファイルのサイズの合計を求めます。

値Bは、値Aのサイズ形式
//ファイルのサイズはバイトで取得されているため、
//それを MB GB などの単位に変換します。
//リファレンスの「ファイル」を参照。

txt配列は、{}
//フォルダ内のテキストファイルを抽出して格納するための配列を
//あらかじめ作成しておきます。

ファイル一覧を要素にそれぞれ繰り返す
txtは、正規表現によって要素から「\.txt」を取り出したもの
//配列(ファイル一覧)の要素から、拡張子 .txt を取り出します。
//取り出した結果は、[txt]という配列の形の変数に格納されます。
//大文字の TXT(点字データのdetailファイルなど)も拾えます。

もし、txtが「{}」でないなら
//上で取り出した結果が、空=「{}」でなければ、
//その要素には拡張子 .txt が含まれるテキストファイルと判断します。

txtを、txt配列に加える
テキストファイルと判断した要素を、先ほど作成した txt配列 に加えていきます。

もし終わり
繰り返し終わり

//以下の手順も、テキストファイルの抽出と同じ手順になるため、説明は省略します。

ワード配列は、{}
ファイル一覧を要素にそれぞれ繰り返す
ワードは、正規表現によって要素から「\.doc(.*)」を取り出したもの
//\.doc(.*) とすることによって、Word2007以降の拡張子 .docx も
//拾えるようにしています(Excelも同じ)。
//マクロ入りやテンプレートなどの拡張子のWordファイルは拾えませんが、
//普通はあまり使われないため、許容範囲と勝手に判断しちゃってます。

もし、ワードが「{}」でないなら
ワードを、ワード配列に加える
もし終わり
繰り返し終わり

エクセル配列は、{}
ファイル一覧を要素にそれぞれ繰り返す
エクセルは、正規表現によって要素から「\.xls(.*)」を取り出したもの
もし、エクセルが「{}」でないなら
エクセルを、エクセル配列に加える
もし終わり
繰り返し終わり

パス配列は、フォルダ名を「\」で区切ったもの
//フォルダ名のフルパスから、指定されたフォルダ名だけを取り出すため、
//まず、フォルダのフルパスを \ で区切った配列の形にして、
//[パス配列]という変数に格納します。

直フォルダ名は、パス配列([パス配列の個数-1])
//例として C:\Windows\System32\ というパスを \ で区切ると、
//配列(1)=「C:」
//配列(2)=「Windows」
//配列(3)=「System32」
//配列(4)=「 」(空の要素)
//となります。
//System32 を求めるためには、配列の個数から 1 を引いた数の要素を
//取得すればいいということになります。
//上の命令文を、わかりやすく分けて書けば次のようになります。
//値は、パス配列の個数-1
//直フォルダ名は、パス配列([値])

//ここまでに得られたデータを整理して、メッセージボックスに表示し、
//同時にクリップボードにコピーする手順が、以下の手順です。

結果は、「[改行]フォルダ名   :[直フォルダ名] ([フォルダ名])[改行]サブフォルダ数 :[フォルダ数][改行]ファイル数   :[ファイル数][改行]合計サイズ   :[値B][改行]テキストファイル:[txt配列の個数][改行]Word文書    :[ワード配列の個数][改行]Excel文書    :[エクセル配列の個数][改行][改行]」

結果を表示する
結果を、クリップボードへコピーする
終了する
//終了する を入れないと、プロセスが残ってしまうケースがあるため、
//この一行を記述してあります。
──────────────────────────────
posted by yanikun at 15:47| Comment(0) | TrackBack(0) | produire