人気ブログランキング | 話題のタグを見る

[VBScript] CSVファイルを上手に処理する:フォルダ内のファイルを1つのCSVにまとめる

どーもボキです。

フォルダに格納されているcsvファイルをひとつのcsvにまとめるサンプル。

単純に連結するだけなら、コマンドプロンプトの「copy *.csv xxx.csv」とすればいいが、
この方法ではタイトル行(今回は1行目のみの前提)が2ファイル目以降も連結されてしまう。

タイトル行が先頭行のみにしたファイル連結も、VBScriptを使えばカンタン!
[VBScript] CSVファイルを上手に処理する:フォルダ内のファイルを1つのCSVにまとめる_a0021757_10534634.png
VBSファイル(もしくは、VBSのショートカット)にフォルダをドロップする、だけ。

フォルダ名.csv にフォルダ内のCSVファイルが連結される。

タイトル行の書き出しは初回ファイルのみとしたファイル連結サンプルソース
' フォルダ内のファイル検索
Sub ProcFolder(DPath)
Dim objFS
Set objFS = CreateObject("Scripting.FileSystemObject")

Dim file ' 出力ファイル
Dim tmp ' 入力ファイル

Dim objFolder
Set objFolder = objFS.GetFolder(DPath) ' 指定フォルダを取得

' フォルダ内のファイル
Dim objFile
For Each objFile In objFolder.Files: Do ' 指定フォルダ内のファイルにてループ
If LCase(objFS.GetExtensionName(objFile.Path)) <> "csv" Then Exit Do ' csv以外なら次へ

If VarType(file) = vbEmpty Then
Set file = objFS.OpenTextFile(DPath & ".csv", 2, True) ' 出力ファイルを書き込み専用(2)で開く

Set tmp = objFS.OpenTextFile(objFile.Path, 1) ' 入力ファイルを読み取り専用(1)で開く
file.WriteLine tmp.ReadLine ' 入力ファイルの1行目を読み出し、それを書き出す
tmp.Close '入力ファイルを閉じる
End If

Set tmp = objFS.OpenTextFile(objFile.Path, 1) ' 入力ファイルを読み取り専用(1)で開く
tmp.ReadLine ' 1行目を読み出すだけ
Do While Not tmp.AtEndOfStream
file.WriteLine tmp.ReadLine ' 入力ファイルの2行目移行を読み出し、それを書き出す
Loop
tmp.Close ' 入力ファイルを閉じる
Loop Until 1: Next
If VarType(file) <> vbEmpty Then file.Close ' 出力ファイルが確保されていたならば、閉じる(フォルダ内にcsvファイルがなかったことを想定)

' フォルダ内のフォルダに対してProcFolderを再起呼び出し
Dim subFolder
For Each SubFolder In objFolder.SubFolders
ProcFolder(SubFolder.Path)
Next
End Sub

ドロップしたフォルダ階層を全てチェックし、フォルダごとのcsvファイルを作っていく。

冒頭にobjFSを確保しているので、ProcFolder関数内のobjFSはなくても良いが、
ProcFolder関数のみでも動作が成立するように、関数ローカルのobjFSは残しままにした。
Dim objWS: Set objWS = CreateObject("WScript.Shell")
Dim objFS: Set objFS = CreateObject("Scripting.FileSystemObject")

' 引数判定
If WScript.Arguments.Count = 0 Then WScript.Quit objWS.Popup("処理するファイル・フォルダをドロップください。", 3, WScript.ScriptName, vbInformation)

' ドロップされたファイル・フォルダを処理
Dim i,s
For i = 0 To WScript.Arguments.Count -1: Do
s = WScript.Arguments(i)
If objFS.FileExists(s) Then
ProcFile(s)
Else
ProcFolder(s)
End If
Loop Until 1: Next

WScript.Quit objWS.PopUp("処理が終了しました。", 3, WScript.ScriptName, vbInformation)
'======================================================================================
' メイン処理
Function ProcFile(FPath)
ProcFile = False
If LCase(objFS.GetExtensionName(FPath)) <> "csv" Then Exit Function

'※ ここに処理実体を記載 ※

ProcFile = True
End Function
' -----------------------------------------------------------------------
' フォルダ内のファイル検索
Sub ProcFolder(DPath)
Dim objFS
Set objFS = CreateObject("Scripting.FileSystemObject")

Dim file ' 出力ファイル
Dim tmp ' 入力ファイル

Dim objFolder
Set objFolder = objFS.GetFolder(DPath) ' 指定フォルダを取得

' フォルダ内のファイル
Dim objFile
For Each objFile In objFolder.Files: Do ' 指定フォルダ内のファイルにてループ
If LCase(objFS.GetExtensionName(objFile.Path)) <> "csv" Then Exit Do ' csv以外なら次へ

If VarType(file) = vbEmpty Then
Set file = objFS.OpenTextFile(DPath & ".csv", 2, True) ' 出力ファイルを書き込み専用(2)で開く

Set tmp = objFS.OpenTextFile(objFile.Path, 1) ' 入力ファイルを読み取り専用(1)で開く
file.WriteLine tmp.ReadLine ' 入力ファイルの1行目を読み出し、それを書き出す
tmp.Close '入力ファイルを閉じる
End If

Set tmp = objFS.OpenTextFile(objFile.Path, 1) ' 入力ファイルを読み取り専用(1)で開く
tmp.ReadLine ' 1行目を読み出すだけ
Do While Not tmp.AtEndOfStream
file.WriteLine tmp.ReadLine ' 入力ファイルの2行目移行を読み出し、それを書き出す
Loop
tmp.Close ' 入力ファイルを閉じる
Loop Until 1: Next
If VarType(file) <> vbEmpty Then file.Close ' 出力ファイルが確保されていたならば、閉じる(フォルダ内にcsvファイルがなかったことを想定)

' フォルダ内のフォルダに対してProcFolderを再起呼び出し
Dim subFolder
For Each SubFolder In objFolder.SubFolders
ProcFolder(SubFolder.Path)
Next
End Sub
' -----------------------------------------------------------------------

by yozda | 2020-05-24 09:06 | プログラミング | Comments(0)