こんにちは、Ryoです。
VBAを利用したテキストファイルとの連携してデータの読み取りや書き込みを行うケースは多々あろうかと思います。今回はLine Inputステートメントを使用してテキストファイル1行ずつデータを読み込む方法について書いていきたいと思います。
1.サンプル概要
実行元のファイルと同じ場所に保存された「サンプルリスト.txt」に入力されているデータを1行ずつ読み込んで、Excelシートに書込んでいきます。
「サンプルリスト.txt」のデータはこの通りです。
テキストファイル内のデータに対して1行ずつ読み込み、カンマで分割して配列に格納し、それをエクセルのSheetに書込んでいきます。合わせてテキストデータ上の「”(ダブルクォーテーション)」の削除や数値の表示形式変更、セル列幅の自動調整も実行した結果が以下です。
1行毎の書き込む処理をステップ送りで確認すると以下のようになります。
ちなみにテキストファイルのデータを読み込み、そのままの状態で書き込んだ場合は以下のようになってしまいますので、余分な文字の「”」削除や数値の表示形式を修正しているという形です。
以上がサンプル概要になります。
2.サンプルコード
Sub Sample1() Dim num As Integer Dim temp As String Dim DataArray As Variant Dim i, j As Long 'ファイル番号を取得 num = FreeFile 'テキストファイル「サンプルリスト」を開く Open ThisWorkbook.Path & _ "\サンプルリスト.txt" For Input As #num 'EOF関数でファイルの末尾まで処理を繰り返す Do Until EOF(num) '1行分のデータを読み込む Line Input #num, temp 'カンマで分割して配列に格納する DataArray = Split(temp, ",") i = i + 1 '配列のデータ数だけ処理を繰り返す For j = 0 To UBound(DataArray) '文字列に「"」が含まれていたら削除 '※「"」を指定したい場合は「""""」と記述する If InStr(DataArray(j), """") <> 0 Then DataArray(j) = _ Replace(DataArray(j), """", "") End If 'Range.Itemプロパティを利用してデータ書込み With Range("A1").Item(i, j + 1) .Value = DataArray(j) '書込んだデータが数値の場合は表示形式変更 '※ 通し番号「No」の部分を除外する場合は、 ' If IsNumeric(.Value) = True And j <> 0 Then If IsNumeric(.Value) = True Then .NumberFormatLocal = "#,###" End If End With Next Loop 'ファイルを閉じる Close #num 'A~F列の列幅を自動調整する ActiveSheet.Columns("A:F").AutoFit End Sub
読み込む「サンプルリスト.txt」は、カンマで区切られているテキストファイルになります。このテキストファイルにFreeFile関数で取得したファイル番号を使用し、Openステートメントでテキストファイルのデータを開きます。
num = FreeFile
Open ThisWorkbook.Path & _
“\サンプルリスト.txt” For Input As #num
FreeFile関数は「現在未使用のファイル番号を返す関数」になります。「ファイル番号」は既に使用されている番号を指定するとエラーとなってしまうのでFreeFile関数を利用して取得した値を使用する形が一般的です。
テキストファイルのデータは最後(末尾)まで処理を行うのでEOF関数を利用します。このEOF関数は「指定したファイル番号のデータ末尾まで処理が進むとTrueを返す」ものなので、Do Until EOF(Num)とすることで最後の1行まで繰り返しの処理を行うことができます。
次のLine Inputステートメントで変数tempに「1行分のデータ」を読み込んでいます。
構文:Line Input #filenumber, varname
Line Inputステートメントはシーケンシャル入力モードで開いたテキストファイルを1行ずつ読み込み、引数varnameに指定した変数(サンプルではtemp)に代入します。
読み込んだデータについてはSplit関数で「カンマごとに分けた配列」に取り込んでいます。
Line Input #num, temp
DataArray = Split(temp, “,”)
後は変数DataArray(配列)の値をループ処理でセルに入力していきますが、そのままではサンプル概要の項でも触れた通り扱い難いデータになってしまうので「”」の削除や数値の表示形式設定を行っています。
文字列に含まれる「”」の削除についてはInStr関数で有無判定を行い、含まれている場合はReplace関数で空白(””)に置換することで削除しています。「”」は「””””」と4つダブルクォーテーションを並べることで指定できますので知っておくと便利です。
If InStr(DataArray(j), “”””) <> 0 Then
DataArray(j) = _
Replace(DataArray(j), “”””, “”)
End If
True判定された場合はRangeオブジェクトのNumberFormatLocalプロパティで表示形式を設定しています。ループ処理が完了後、ファイルを閉じてセル対象範囲の列幅を自動調整し終了となります。
この一連の処理概要としては以下のような形になりますので、ご参考までに。
3.まとめ
膨大なテキストデータを取り込むような処理であればまとめてデータを読み込み、一括してエクセルシートに書込むような形の方がシンプル且つアクセス頻度が少ないので処理も速いのですが、比較的データ量も少なく行毎のデータを取得/チェックしながら書き込んでいくような処理ではLine Inputステートメントが有効なことも多いので私はよく使っています。
Excelのブックを扱うのに比べるとやや煩雑になりますが、テキストファイルのデータを扱えると何かと有用なので知っておいて損はないと思います。
以上、テキストファイルから1行ずつ読み込みを行う方法についてでした!今回の記事が何かの参考になれば幸いです。
Ryo