一行のコードで終わらせる ②-2 一行を分解してみる
昨日は、指定フォルダ内にある全ファイルのパスを取得する「一行のコード」(※自作ではありません)を紹介した。
infoment.hatenablog.com
自作ではない悲しさで、不明の部分が多々あった。
そこで今回は、これを可能な限り分解して、理解してみようと思う。
改めて、昨日の「一行」を見てみよう。
Function_FileList = Filter(Split(CreateObject("wscript.shell").exec("cmd /c Dir """ & FolderLocation & """ /b /a-d").stdout.readall, vbCrLf), ".")
人によって手法は様々と思うが、私の場合、複雑なコードを組むときの手順は次のとおりだ。
- 最も基本的な部分を作成する。
- 必要に応じて、段階的に条件分岐や繰り返しを付加する。
従って今回は上記の逆手順で、数式の分解を試みる。
Filter関数
今回初めて知った関数。ある配列を、特定の文字列を持つ要素だけでフィルタリングする。従って、戻り値も配列となる。
www.tipsfound.com
配列
Split(CreateObject("wscript.shell").exec("cmd /c Dir """ & FolderLocation & """ /b /a-d").stdout.readall, vbCrLf)
フィルタ文字
"."
「.」を含むということは、つまり何某かの拡張子を含むファイルパスということになる。なるほど。
ここまでを整理すると、このようになる。
Function Function_FileList(FolderLocation As String) Dim seq As Variant seq = Split(CreateObject("wscript.shell").exec("cmd /c Dir """ & FolderLocation & """ /b /a-d").StdOut.ReadAll, vbCrLf) Dim FilterCharacter As String FilterCharacter = "." Function_FileList = Filter(seq, FilterCharacter) End Function
Split関数
Split関数は、文字列を指定文字で区切り、配列を返す関数だ。
www.tipsfound.com
文字列
CreateObject("wscript.shell").exec("cmd /c Dir """ & FolderLocation & """ /b /a-d").stdout.readall
区切り文字
vbCrLf
vbCrLfは、改行を表すコード。こちらの解説が、とても参考になる。
thom.hateblo.jp
つまり今回は、一行に一つファイルパスを含む複数行の文字列を分割(Split)して、配列を作成していることになる。
ここまでを整理すると、このようになる。
Function Function_FileList(FolderLocation As String) Dim temp As String temp = CreateObject("wscript.shell").exec("cmd /c Dir """ & FolderLocation & """ /b /a-d").StdOut.ReadAll Dim seq As Variant seq = Split(temp, vbCrLf) Dim FilterCharacter As String FilterCharacter = "." Function_FileList = Filter(seq, FilterCharacter) End Function
Windows Scripting Host
ここから先は未だ学びが浅く、かき集めてきたことばかり。コマンドプロンプトから出来ることが、これで実行できるらしい。今後、学習が必要だ。
↓ こちらには、ファイルパスに空白が含まれる場合の対策として、パスを""で囲う必要性が示されている。
Excel VBA を学ぶなら moug モーグ | 即効テクニック | 拡張子関連づけでファイルを開く
それで、↓のような記述になっていたわけだ。
""" & FolderLocation & """
cmd /c
「文字列で指定されたコマンドを実行する」とのこと。つまり、
Dir """ & FolderLocation & """ /b /a-d"
この部分を実行せよということか。
/b
ディレクトリ名とファイル名のみを表示させる。
StdOut
標準出力。Dir関数の結果を出力させている。
標準ストリーム - Wikipedia
ReadAll
TextStreamファイル全体を読み込み、その結果の文字列を返す。
ReadAll メソッド (FileSystemObject)
従って、Dir関数の結果を出力したうえで、読み込んだ文字列ということか。
これらが1行にギュッと詰め込まれていたわけで、これは中々読み込むのが大変だ。引き継いだツールなどにこれが含まれていた場合、恐らく後任者は往生することだろう。
ということで、1行に詰めたのは凄いけど、自己使用以外で展開するのは控えたほうが良さそうです。
参考まで。