ファイルの末尾の文字を調べるには
ファイルの末尾がどういう文字か調べるには、Linuxの場合であればコマンドで「tail -c 1 a.txt | xxd -p」と実行して”0a”と出力されれば改行コードLFである、などと判定できますが、VBAでは残念ながらそういう方法は採れません。
ただ、考え方としては似たような方法は可能です。具体的にはFileSystemObjectクラスを使ってファイルを開き、そのファイルの終端の直前までジャンプ(シーク)し、それ以降の文字を取得する、という方法です。
この方法であればファイルサイズにほとんど影響されることなく、ファイルの末尾の文字を取得することが可能です。
以下ではその方法でのファイルの末尾の文字を調べる方法を紹介します。
事前設定
以下のサンプルコードでは参照設定でFileSystemObjectクラスを利用できるようにしています。
FileSystemObjectクラスを利用するには、事前にVBA画面→ツールメニュー→参照設定、を選択し、参照設定ダイアログで「Microsoft Scripting Runtime」にチェックを付けます。
詳細は「VBAでのFileSystemObjectとTextStreamの使い方」の事前設定をご参照ください。
コード
以下のコードは、指定されたファイルパスの末尾の文字を取得します。終端が改行コードの場合も考慮して、文字コードで取得するようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
'// 引数はファイルパス文字列 '// 戻り値はファイルパス終端文字の文字コード値 Function GetCharEndOfFile(a_sPath As String) As Integer Dim fso As New FileSystemObject '// FileSystemObject Dim ts As TextStream '// TextStream Dim oFile As File '// File Dim iSize As Long '// ファイルサイズ Dim iCode As Integer '// 文字コード '// ファイルが存在しない場合 If (fso.FileExists(a_sPath) = False) Then '// 末尾文字なしとして-1を返す GetCharEndOfFile = -1 '// 以降を処理せず抜ける Exit Function End If '// 指定ファイルのFileオブジェクトを取得 Set oFile = fso.GetFile(a_sPath) '// 指定ファイルのサイズを取得 iSize = oFile.Size '// 空ファイルの場合 If (iSize = 0) Then '// 末尾文字なしとして-1を返す GetCharEndOfFile = -1 '// 以降を処理せず抜ける Exit Function End If '// ファイルを開く Set ts = fso.OpenTextFile(a_sPath, ForReading, True) '// ファイルの終端直前に移動 Call ts.Skip(iSize - 1) '// 最後の1文字を文字コードで取得 iCode = Asc(ts.Read(1)) '// ファイルを閉じる ts.Close GetCharEndOfFile = iCode End Function |
使い方
上の関数の使い方の例です。ファイルパスを指定して引数に渡し、戻り値として文字コード変数で結果を受けています。
取得した文字コードをイミディエイトウィンドウにそのまま出力しています。例えば終端文字が改行LFであれば10が出力されます。
1 2 3 4 5 6 7 8 9 10 |
Sub GetCharEndOfFileTest() Dim sPath As String '// ファイルパス Dim iCode As Integer '// 文字コード sPath = "V:\aaaa\a.txt" iCode = GetCharEndOfFile(sPath) Debug.Print iCode End Sub |
実行結果
10(終端が改行コードCRLFであれば、LFの10が出力される)
問題点
上のコードはFileSystemObjectを利用しており、テキストファイルがShift-JISであることを前提としています。また、終端に全角文字がないことも前提です。
参照するファイルの文字コードがUTF-8だったり、終端が全角文字の場合はエラーになります。
ただ、業務で扱うデータをファイル化したものは処理しやすいようにShift-JISであることの方が多いことと、住所や氏名などの全角文字が終端にある場合もあまりないと思われるため、そうであれば上のコードのままで問題ないと思います。
バイナリファイルを扱うのであればFileSystemObjectの仕組みではなく、Openステートメントを利用してファイルを開き、終端に達した際に直前の文字がなんだったか、という判定を行う方法を採るなど、別の方法が必要になります。
バイナリファイルの扱い方については「VBAでバイナリファイルを読み込む(一括、1バイト、指定バイト)」をご参照ください。