【VBS】26項目を超えるCSVファイルを読み込む処理


いつもお世話になっております。
RfromLです。

今回は項目数が26項目を超えるCSVファイルを読込んで編集して出力する処理についてです。

1.はじめに

バッチスクリプトでCSVファイルを読込んで編集・出力する処理については過去の記事「【バッチスクリプト】CSVファイルを読み込み特定項目のみファイル出力する【バッチスクリプト】CSVファイルを読み込み特定項目のみファイル出力する」で紹介しましたが、バッチスクリプトのfor文で指定できる項目は基本的には26列までとなっています。

以下、forコマンドのヘルプ(コマンド「for /?」の実行結果)より一部抜粋

%i は for 文で明示的に宣言され、%j と %k は tokens= オプションで暗黙的に
    宣言されています。
    tokens= 行を使って 26 個までのトークンを指定できますが、
    文字 'z' または 'Z' よりも高い変数を宣言することはできません。FOR 変数名は

ただし、上記ヘルプの続き

    文字 'z' または 'Z' よりも高い変数を宣言することはできません。FOR 変数名は
    単一の文字で、大文字と小文字を区別し、グローバルなものであり、一度に
    アクティブにできるのは合計 52 個までです。

で「FOR変数名は単一の文字で・・・」と書いてある通りアルファベット以外も指定が可能です。
参考資料「For文のtokensの最大値は31、とそれを超える使い方

アルファベット以外を使用すれば26列を超えることは可能なのですが、可読性の観点から推奨はしません。
自分しか使わないような個人用ツールであれば、まぁいいかなといったところです。

今回は過去の記事で行った「バッチスクリプトでCSVファイルを読み込み特定項目のみファイル出力する処理」と同様のことを項目数が26項目を超えるCSVファイルに対して行うため、VBSで処理を作成します。


2.環境情報

実行環境は以下のバージョンとなっています。

OSWindows11 Home 64ビット
OS ビルドMicrosoft Windows [Version 10.0.26100.3624]

3.機能概要

入力のCSVファイル(27項目)「価格情報ファイル」を読込み、読込んだ内容から一部の項目(11項目)を抜き出して出力のCSVファイル「価格情報ファイル(レイアウト変更)」に書き込みます。

入力CSVファイルから出力CSVファイルに抜き出す項目は下図の通りです。


4.ファイル仕様

実行例として使用するファイルの仕様について記載します。

4-1.入力ファイル

入力ファイルのファイル名は「INFILE.txt」とします。


[ ファイルレイアウト ]

項目No.項目名
1銘柄コード
2銘柄名
3価格
4価格 前日比
5利回り
6NAV
7NAV倍率
8時価総額
9出来高
10決算期
11運用資産
12区分1
13区分2
14区分3
15区分4
16区分5
17区分6
18区分7
19区分8
20区分9
21区分10
22区分11
23区分12
24区分13
25区分14
26区分15
27区分16

[ ファイルフォーマット仕様 ]

データ領域形式可変長
ヘッダー行なし
囲み文字なし
改行コードCRLF
文字コードSJIS
区切り文字,(カンマ)

[ テスト用入力ファイル ]

銘柄コード銘柄名価格価格 前日比利回りNAVNAV倍率時価総額出来高決算期運用資産区分1区分2区分3区分4区分5区分6区分7区分8区分9区分10区分11区分12区分13区分14区分15区分16
9995ムーン投資法人704000+1.15%3.275805251.21119749841196 / 12112345678910111213141516
9996サターンファンド投資法人640000+0.47%3.525878321.0988653433983 / 91234567891011121314151617
9997ジュピター投資法人105800+0.09%4.281081040.98739446222342 / 873456789101112131415161718
9998金星投資法人190500+0.79%3.981910361.0052578093912 / 8745678910111213141516171819
9999太陽投資法人401500+0.50%3.863797711.0640036720296 / 127567891011121314151617181920

4-2.出力ファイル

出力ファイルのファイル名は「OUTFILE.txt」とします。


[ ファイルレイアウト ]

項目No.項目名
1銘柄コード
2銘柄名
3価格
4利回り
5NAV
6NAV倍率
7時価総額
8運用資産
9区分1
10区分8
11区分16

[ ファイルフォーマット仕様 ]

データ領域形式可変長
ヘッダー行なし
囲み文字なし
改行コードCRLF
文字コードSJIS
区切り文字,(カンマ)

5.作成プログラム

5-1.ディレクトリ構成

処理を実行する際のディレクトリ・ファイル構成です。
今回実行するバッチスクリプトは「CsvEdit.bat」です。
「CsvEdit.bat」から「CsvEdit.vbs」に入力ファイルパス、出力ファイルパスを引数として渡して実行します。

5-2.コード内容

今回作成したスクリプトファイルのコード内容は以下の通りです。


[ CsvEdit.bat ]

@echo off
@rem ------------------------------------------------------------
@rem 初期処理
@rem ------------------------------------------------------------
@rem 実行バッチファイルディレクトリ設定
set CMD_PATH=%~dp0

@rem 処理ID設定(バッチファイル名)
set BATCH_ID=%~n0

@rem 処理開始メッセージ表示
echo %BATCH_ID% %date:~0,4%年%date:~5,2%月%date:~8,2%日 %TIME:~0,2%時%TIME:~3,2%分%TIME:~6,2%秒 処理開始

@rem ------------------------------------------------------------
@rem ファイルディレクトリ設定
@rem ------------------------------------------------------------
@rem 入力ファイルディレクトリ
set IDIR=%CMD_PATH%IN

@rem 出力ファイルディレクトリ
set ODIR=%CMD_PATH%OUT

@rem ------------------------------------------------------------
@rem ファイルID設定
@rem ------------------------------------------------------------
@rem 入力ファイルID
set  IFILE01=INFILE.txt

@rem 出力ファイルID
set  OFILE01=OUTFILE.txt

@rem ------------------------------------------------------------
@rem VBS : CSVファイル項目抽出処理
@rem ------------------------------------------------------------
cscript //nologo %CMD_PATH%\CsvEdit.vbs %IDIR%\%IFILE01% %ODIR%\%OFILE01%

@rem ------------------------------------------------------------
@rem - 終了処理
@rem ------------------------------------------------------------
:END

@rem 処理終了メッセージ表示
echo %BATCH_ID% %date:~0,4%年%date:~5,2%月%date:~8,2%日 %TIME:~0,2%時%TIME:~3,2%分%TIME:~6,2%秒 処理終了

exit /b 0

[ CsvEdit.vbs ]

Option Explicit
' -------------------------------------------------------------
' 変数の宣言
' -------------------------------------------------------------
Dim objArgs        ' 引数
Dim objFS          ' ファイルシステムオブジェクト
Dim objIText       ' 入力ファイル用
Dim objOText       ' 出力ファイル用

Dim in_Cnt         ' 入力ファイル件数カウンタ
Dim out_Cnt        ' 出力ファイル件数カウンタ

Dim argITextFile   ' 引数①(入力ファイルパス)格納用
Dim argOTextFile   ' 引数②(出力ファイルパス)格納用

Dim strReadLine    ' 入力レコード格納用
Dim strWriteLine   ' 出力レコード格納用

Dim item_member    ' カラム格納用配列

' -------------------------------------------------------------
' 引数取得
' -------------------------------------------------------------
' 入出力ファイル設定(フルパス指定)
Set objArgs = WScript.Arguments
argITextFile = objArgs(0) '第1引数 入力ファイルパス
argOTextFile = objArgs(1) '第2引数 出力ファイルパス

' -------------------------------------------------------------
' 前処理
' -------------------------------------------------------------
' ファイルシステムオブジェクトの生成
Set objFS = CreateObject("Scripting.FileSystemObject")

' 入力ファイルOPEN (1:読み取り専用でファイルオープン)
Set objIText = objFS.OpenTextFile(argITextFile,1)

' 出力ファイル作成 (True:上書き指定でファイル新規作成)
set objOText = objFS.createtextfile(argOTextFile,True)

' -------------------------------------------------------------
' 開始処理
' -------------------------------------------------------------
' 処理開始
WScript.Echo "START"

' -------------------------------------------------------------
' メイン処理
' -------------------------------------------------------------
' 初期値セット
in_Cnt = 0       ' 入力件数
out_Cnt = 0      ' 出力件数(空レコードを除く)

Do While Not objIText.AtEndOfStream

  ' 入力ファイル読込
  strReadLine = objIText.ReadLine

  ' 入力件数カウントアップ
  in_Cnt = in_Cnt + 1

  ' ワーク領域を初期化
  strWriteLine = ""
  item_member = ""

  ' 項目を変数に格納 (区切り文字 カンマ指定)
  item_member = Split(strReadLine,",")

  ' 各項目をレコード書き込み用変数に移送
  strWriteLine = item_member(00) & ","                  '銘柄コード
  strWriteLine = strWriteLine & item_member(01) & ","   '銘柄名
  strWriteLine = strWriteLine & item_member(02) & ","   '価格
  strWriteLine = strWriteLine & item_member(04) & ","   '利回り
  strWriteLine = strWriteLine & item_member(05) & ","   '1口NAV
  strWriteLine = strWriteLine & item_member(06) & ","   'NAV倍率
  strWriteLine = strWriteLine & item_member(07) & ","   '時価総額
  strWriteLine = strWriteLine & item_member(10) & ","   '運用資産
  strWriteLine = strWriteLine & item_member(11) & ","   '区分1
  strWriteLine = strWriteLine & item_member(18) & ","   '区分8
  strWriteLine = strWriteLine & item_member(26)         '区分16

  If Not strWriteLine = "" Then
    ' レコード書き込み
    objOText.writeline(strWriteLine)
    ' 出力件数カウントアップ
    out_Cnt = out_Cnt + 1
  End If

Loop

' -------------------------------------------------------------
' 終了処理
' -------------------------------------------------------------
' 終了メッセージ
WScript.Echo "  INPUT : " & in_Cnt
WScript.Echo "  OUTPUT: " & out_Cnt
WScript.Echo "END"


' オブジェクトクリア&クローズ
objIText.Close
objOText.Close

Set objArgs = Nothing
Set objIText = Nothing
Set objOText = Nothing
Set objFS = Nothing

6.実行結果確認

①入力ファイルが配置されていることを確認

②出力先にファイルが無いことを確認

③バッチスクリプトを実行

④出力先のファイルを開き内容が正しく出力されていることを確認

7.おわりに

今回の記事を作成してから知ったのですが、VBScriptが廃止となるようです。

「VBScript」は2027年頃にデフォルトで無効に ~非推奨化スケジュールが公開/3つのフェイズに分け、段階的にサポートを縮小
米Microsoftは5月22日(日本時間)、「VBScript」の廃止スケジュールを公表した。3つのフェイズに分けて、段階的にサポートが縮小される。

完全に廃止(フェーズ3)となる期日はまだ未定のようですが、これまでVBSで作成したツール類も使えなくなってしまうということです。
だいぶお世話になってきたので少し悲しいものがありますがしょうがない。。😣
今後はPowerShellで代替していくしかないですね。

以上です。
宜しくお願い致します。


タイトルとURLをコピーしました