2つのCSVファイルのキー列を比較して、一致したらその行の別の列に更新等の処理をするケースは、多いと思う。
けども、ネットにあまり情報が無かったので、載せておこうと思う。
方法1:ループを二つ使った処理
まず、シンプルにループを使って、付き合わせ処理を作ってみた。よく情報処理の試験で出てくるようなやつ。
![](https://waji-mart.com/homeandabroad/wp-content/uploads/2023/11/0c40c34f79f7c8fcb8ab358faa441ccd.png)
だが、作って実際に動作させると、外側のループのキーと内側ループのキーを一件一件見ていくので、遅くて使い物にならない。
そもそもPADのフローは遅いので、このやり方だと、自分の業務に使えない。
方法2:ループと検索を組み合わせた処理。
次に、外側ループはそのままで、内側で検索を使うことにした。
![](https://waji-mart.com/homeandabroad/wp-content/uploads/2023/11/952c7ad25a3ba46dcce7944afac1020d.png)
ただ、検索結果が返る変数のDataTableMatchesの使い方がわからなくて。
見つかったキーをテーブルで返してくるのと、その中の数字が数値ではなく文字であることが、なかなか気が付かなくて。
しばらく難儀したけど、できた。
![](https://waji-mart.com/homeandabroad/wp-content/uploads/2023/11/f128300eaa3265cf3872a44960ff40f4.png)
結果、すごく早くなった。
2つのファイルそれぞれ30件あるテキストファイルを処理するのにかかった時間は以下。
方法1:360秒
方法2:30秒
12倍。
ExcelVBAだと一瞬で結果が出るのだが、PADだとやはり遅いので、やり方を工夫しないといけないシーンがちらほら出てくる。
もし方法1をどうしても使わなければいけなくなったら、お互いのファイルのキー列をソートして、見つかったら次の処理での調査範囲を狭めるなど作るのに手間がかかる。ヤダなあ。。
参考:方法1のコード
LOOP LoopIndex1 FROM 1 TO CSVTable1.RowsCount - 1 STEP 1
LOOP LoopIndex2 FROM 1 TO CSVTable2.RowsCount - 1 STEP 1
IF CSVTable1[LoopIndex1][0] = CSVTable2[LoopIndex2][0] THEN
IF CSVTable1[LoopIndex1][1] <> CSVTable2[LoopIndex2][1] THEN
Display.ShowMessageDialog.ShowMessageWithTimeout Message: CSVTable2[LoopIndex2][1] Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: True Timeout: 3 ButtonPressed=> ButtonPressed
EXIT LOOP
END
END
END
SET LoopIndex2 TO 1
END
参考:方法2のコード
LOOP LoopIndex1 FROM 1 TO CSVTable1.RowsCount - 1 STEP 1
Variables.FindOrReplaceInDataTable.FindItemInDataTableEverywhere DataTable: CSVTable2 AllMatches: True ValueToFind: CSVTable1[LoopIndex1][0] MatchCase: False MatchEntireCellContents: False DataTableMatches=> DataTableMatches
Text.ToNumber Text: DataTableMatches[0][0] Number=> CSV2Row
IF CSVTable1[LoopIndex1][1] <> CSVTable2[CSV2Row][1] THEN
Display.ShowMessageDialog.ShowMessageWithTimeout Message: $'''%CSVTable2[CSV2Row][0]%
%CSVTable2[CSV2Row][1]%
''' Icon: Display.Icon.None Buttons: Display.Buttons.OK DefaultButton: Display.DefaultButton.Button1 IsTopMost: True Timeout: 3 ButtonPressed=> ButtonPressed
END
END
コードは、PADに貼り付けて使えます。