フォルダーを選択してファイルリストを作成する
[VBA系メニューへ]
[質問掲示板]
[バックナンバー目次]
こんにちは、三流プログラマーKen3です。
今回は、
フォルダーを選択してファイルリストを作成する
おや?どこかで見たような、見なかったような、、、
です。
今回作成したファイル名の取得、フォルダー選択のテストプログラム
http://www.ken3.org/p/lzh/off001.lzh
に
office-001.xls, office-001.mdb(フォルダー選択のテストだけ)
保存してます。
ダウンロードして、動きをチェックして見てください。
/*
* 1.今回のキッカケ
*/
仕様、やりたいことをハッキリとさせる
プログラムを組む前には、どんなことやりたい?
こんなこと?
など、作りたい最終結果のイメージを思い浮かべます。
まぁ、ここからの仕様の理解度、プログラムへの落し方が
意外と評価をわけたり、腕の見せ所なんだけどね。
※詳細設計書の書き方やらなきゃね。。。は、ひとまず置いといて、
納品ファイルの一覧表を作って
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
と言われたら、アナタならどうしますか?
ひとつの方法は、エクスプローラーでファイルを表示させて、
それを入力するか、ハードコピーを撮って貼りつけるか。
←参考画面
プロ?ぽい人は、コマンドプロンプトで、
CD \VBA-TEST (目的のフォルダー)
dir *.* > list.txt (DIRはファイル名を表示するコマンド)
で、list.txtを作ってエディターなどで編集して処理します。
Microsoft(R) Windows 98
(C)Copyright Microsoft Corp 1981-1998.
C:\WINDOWS>d:
D:\BackupDISK\Et-mps_2317>cd \vba-test
D:\VBA-TEST>dir *.* > list.txt
D:\VBA-TEST>
←参考画面
list.txt の 中身は、
ドライブ D: のボリュームラベルは HD07G
ボリュームシリアル番号は 2156-1EFF
ディレクトリは D:\VBA-TEST
. <DIR> 02-11-24 14:29 .
.. <DIR> 02-11-24 14:29 ..
042-5-2 <DIR> 01-04-17 10:25 042-5-2
042-3 <DIR> 01-04-13 5:38 042-3
042-4 <DIR> 01-04-14 10:38 042-4
042-5 <DIR> 01-04-17 6:36 042-5
042-2 <DIR> 01-04-10 5:17 042-2
VBA002 <DIR> 02-11-14 6:42 vba002
VBA006 <DIR> 02-11-20 5:46 vba006
VBA013 <DIR> 02-12-02 23:52 vba013
VBA007 <DIR> 02-11-24 14:30 vba007
VBA015 <DIR> 02-12-05 15:54 vba015
VBA018 <DIR> 02-12-08 16:07 vba018
VBA016 <DIR> 02-12-05 21:10 vba016
VBA019 <DIR> 02-12-09 15:25 vba019
A100 TXT 13 02-12-24 1:01 A100.TXT
TEST02~1 XLS 28,160 02-12-12 21:06 Test020-Book.xls
TEST02~2 XLS 40,448 02-12-12 21:50 Test022-Book.xls
DB023 MDB 81,920 02-12-14 1:25 db023.mdb
TEST02~3 XLS 27,648 02-12-26 11:57 Test025-Book.xls
OUT TXT 220 02-12-19 2:42 out.txt
TEST02~4 XLS 30,720 02-12-17 20:22 Test027-Book.xls
・
・
・
TEST05~3 XLS 37,376 03-01-26 19:40 Test052-Book.xls
TEST05~4 XLS 44,032 03-01-28 19:08 Test053-Book.xls
LIST TXT 0 03-01-31 2:30 list.txt
52 個 1,718,398 バイトのファイルがあります.
15 6,293.68 メガバイトの空きがあります.
---
となっているので、あとは好きに編集できます。
毎回、そんなことやってられないので(やっててもいいんだけど)
フォルダーを選択したらファイル名のリストを作成する処理をやりたいと思います。
/*
* 2.日本語で書くのは簡単だけど、、、
*/
フォルダーを選択したらファイル名のリストを作成するツール作ってよ。
やりたいことは〜〜みたいな感じでさ、簡単でいいからさ。
なんて、言われたら?
※簡単でいいからさ、、の一言にだまされないように(笑)
~~~~~~~~~~~~~~~~~~~~~~~~~~
さて、どうしましょうかねぇ。
今回のポイントになるのが、
・ファイル名リストの取得方法
・フォルダーの選択方法
ですね。
何で作ろうかなぁ。はじめの道具選びで運命がほぼ決まるよね。
よし今回はExcelでセルにファイル名を入れてみます。
/*
* 3.ファイルのリストを取るにはDir関数を使う
*/
Excelブックで、Alt+F11を押してVBAの編集画面を出してと、
Sub test_ファイル名を取出す()
'ファイル名を取出して、セルにセットするテストを行う
'A列をクリアする
Range("A1:A9999").Value = "" '1行〜9999行に空文字を代入
' C:\ 内のファイル名を表示します。
Dim strFolder As String 'フォルダー名
Dim strFileName As String 'ファイル名
Dim nYLine As Integer '行カウンタ
strFolder = "c:" '検索するフォルダーを設定します。
strFileName = Dir(strFolder & "\*.*", vbNormal) '最初のファイル名を取る
'ファイルが見つからなくなるまでループしてデータをセットする
nYLine = 1
Do While strFileName <> "" ' ループを開始します。
Cells(nYLine, 1) = strFileName 'セルにファイル名をセットする
nYLine = nYLine + 1 ' カウントアップする
strFileName = Dir ' 次のファイル名を返します。
Loop
End Sub |
なんか難しそうだけど、プログラムなんてのは、
制御文(ここでは、Do Whileのループ)で流れつくって、
標準関数(Dir関数でファイル名取得)
で取得した値を、オブジェクト(Excelのセル)
にセットしただけなんですね。
難しいと感じるポイントがあって、
アルゴリズムと呼ばれてるのが、
制御文などの流れを作っている部分。
標準関数の使い方。
オブジェクトの操作。
大きく言うと、このプログラムでは、3点かなぁ。
アルゴリズムはひらめき系?の部分が多く、
標準関数やオブジェクトの操作は知識、
情報の探し方(調査能力、ヘルプを見るうまさ)
かなぁ。
それだけじゃないだろオイ
~~~~~~~~~~~~~~~~~~~~~~~~
/*
* 4.フォルダーの選択
*/
上記のDIRのテスト関数で、
strFolder = "c:" '検索するフォルダーを設定します。
を好きなのに変えてよ、、、
strFolder = "D:\vba-test" '検索するフォルダーを設定します。
とプログラム変更してから実行してね。
おいおい、プログラムを直しながら実行させる、
そんなツール聞いたことないよね。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
そうですかぁ、エディターぐらい使えるよね(笑)
本気で言ってんの?(怒)
イヤ冗談です(まったく、まじめ君は困ったもんだ。。。)
さてと、フォルダーを選択させるダイアログを探すか。
えっ、ExcelやAccessのVBAだと無いの?
やっと噂のAPIを使うんですか?
そんなことしたくないので、
Shellオブジェクトを使ってみます。
~~~~~~~~~~~~~~~~~
Sub test_フォルダーの選択()
Dim objShell As Object 'Shell
Dim objFolder As Object 'Shell32.Folder
Const strTitle = "フォルダを選択してください。"
'シェルのオブジェクトを作成する
Set objShell = CreateObject("Shell.Application")
'フォルダー参照に設定
Const lngRef = &H1
'ルートフォルダーをデスクトップに設定
'5でMy Documents、6でFavoritesなど
Const fldRoot = &H0
Set objFolder = _
objShell.BrowseForFolder(0, _
strTitle, lngRef, fldRoot)
Set objShell = Nothing
'フォルダー名を取出す
Dim strMSG
If objFolder Is Nothing Then 'キャンセルチェック
strMSG = "キャンセル押しやがって、えっキャンセル押されたらのテスト?"
Else
If objFolder.ParentFolder Is Nothing Then
strMSG = "選択されたのは[ルート(デスクトップ)]です"
Else
strMSG = "選択されたのは[" & objFolder.Items.Item.Path & "]です"
End If
End If
MsgBox strMSG
End Sub |
なんとか、出来たみたいですね。
*デスクトップを選択された時、ログインユーザーの場所を求めてないけどね。
システムやツールを作成する時、
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
標準関数や標準のダイアログで実行できない機能を
外部のオブジェクトを参照して、その機能を借用する(笑)なんてこともあります。
*WindowsAPIを操作する高度な方法もあります。
これも長くなるので、補足発行かなぁ(おいおい、そんなんでいいの?)
/*
* 5.単体でテストしたサブルーチンをつなげる
*/
フォルダーの選択
と
指定したフォルダー内のリストの出力処理
上記2つのテストが完了しました。
さてと、つなげますか。
メインの流れは、
フォルダーを選択させる。
↓
キャンセルだったら、処理を抜ける
↓
選択されたフォルダーを表示関数に渡し、表示する
えっ、そんなものなの?
別に複雑にしたくないので。
プログラム作成になれて無い時は、
日本語の動作を箇条書きで書くといいですよ。
Sub Main()
'フォルダーを選択させる
'キャンセルだったら処理を抜ける
'選択されたフォルダーを表示関数に渡し表示する
End Sub |
みたいに、コメントだけの関数を書いてみる、でいいと思います。
処理のまとめ方にもポイントがあって、
値の受け渡し方法や書き方がプログラムがうまい人とヘタな人の差になるのかなぁ。
※そこをハヤク教えろよ、隠すなよ
まぁまぁ、今回は置いといて次回以降ね。。。
忘れんなよ(怒)
Sub Main()
Dim strFolder '選択されたフォルダーを格納
'フォルダーを選択させる
strFolder = getFOLDER() 'フォルダーの選択関数を呼ぶ
'キャンセルだったら処理を抜ける
If strFolder = "キャンセル" Then
Exit Sub
End If
'選択されたフォルダーを表示関数に渡し表示する
Call setFILELIST(strFolder) 'データのセット
End Sub |
と、変数を使って、2つのユーザー関数を制御するMain関数としました。
'フォルダー選択ダイアログを表示して、リターン値で選択場所を返す
'キャンセルの時は文字列キャンセル、
'デスクトップの時は文字列を返す
Function getFOLDER() As String
Dim objShell As Object 'Shell
Dim objFolder As Object 'Shell32.Folder
Const strTitle = "フォルダを選択してください。"
'シェルのオブジェクトを作成する
Set objShell = CreateObject("Shell.Application")
'フォルダー参照に設定
Const lngRef = &H1
'ルートフォルダーをデスクトップに設定
'5でMy Documents、6でFavoritesなど
Const fldRoot = &H0
Set objFolder = _
objShell.BrowseForFolder(0, _
strTitle, lngRef, fldRoot)
'フォルダー名を取出し、リターン値をセット
If objFolder Is Nothing Then 'キャンセルチェック
getFOLDER = "キャンセル" 'リターン値にキャンセルをセット
Else
If objFolder.ParentFolder Is Nothing Then
getFOLDER = "デスクトップ"
Else
getFOLDER = objFolder.Items.Item.Path 'パスをセットする
End If
End If
Set objFolder = Nothing
Set objShell = Nothing
End Function |
値を返すユーザー関数
Functionにして、
テストで、メッセージボックスの確認していた部分を、
getFOLDER = "キャンセル" 'リターン値にキャンセルをセット
getFOLDER = "デスクトップ"
getFOLDER = objFolder.Items.Item.Path 'パスをセットする
に変えただけでした。
次の表示部は、
'引数(パラメータ)でフォルダー名をもらい、
'データをA列にセットする
Sub setFILELIST(strFolder As String)
'A列をクリアする
Range("A1:A9999").Value = "" '1行〜9999行に空文字を代入
Dim strFileName As String 'ファイル名
Dim nYLine As Integer '行カウンタ
'最初のファイル名を取る
strFileName = Dir(strFolder & "\*.*", vbNormal)
'ファイルが見つからなくなるまでループしてデータをセットする
nYLine = 1
Do While strFileName <> "" ' ループを開始します。
Cells(nYLine, 1) = strFileName 'セルにファイル名をセットする
nYLine = nYLine + 1 ' カウントアップする
strFileName = Dir ' 次のファイル名を返します。
Loop
End Sub |
と、フォルダーの場所をパラメータで受け取り、データをセットしました。
ツール、プログラム作りとかいってたけど、
標準関数のファイル名を返すDir関数
と
Shellオブジェクトを使用したフォルダーの選択、
たんなる関数やオブジェクトの操作を組み合わせだけなんですね。
'フォルダーを選択させる
strFolder = getFOLDER() 'フォルダーの選択関数を呼ぶ
と1つ使えそうな?関数ができあがりましたね。
/*
* 6.終わりの挨拶
*/
今回作成したファイル名の取得、フォルダー選択のテストプログラム
http://www.ken3.org/p/lzh/off001.lzh
に
office-001.xls, office-001.mdb(フォルダー選択のテストだけ)
保存してます。
ダウンロードして、動きをチェックして見てください。
※コピーして、システムに組み込んで使ってみてください。
えっ、ハヤク、デスクトップの位置を知る方法を書けって?
拾い読みして、
1つでも何かの参考となれば幸いです。
Excel/Access大好き、三流プログラマーKen3でした。
※今日はふざけすぎました、解除しないでね。
三流君のHP主な飛び先
VBA系のメルマガで書いた解説を項目ごとにまとめてます
[VBAでAccessを操作(一般)]
[VBAでAccessのレポートを操作]
[VBAでAccessのUserForm/サブフォームを操作]
[VBA Access から Excel 連携]
[VBA でExcel オブジェクト/プロパティ/メソッド/一般]
[VBA でExcel UserForm(ユーザーフォーム)を操作する]
[VBA ExcelからAccessを操作する]
[VBA Outlookの操作]
[VBA IEの操作]
[VBA テキストファイル(*.txt,*.html,*.csv)の操作]
[VBA標準関数関係とその他解説]
ASP系の解説を項目ごとにまとめてみました
[ASP Form等を使用したデータのやり取り]
[ASP その他処理サンプル]
[ASP テキストファイル処理]
[ASP VBScript関数関係の説明]
[ASP ADOでMdbファイルを使う]
[ASP ADOでExcelと接続してみた]