VBAからテキストファイルを開くときのファイル番号は変数でもよい

Openステートメントのファイル番号には変数も使える

テキストファイルOpen時のファイル番号に変数を使う

たとえば、

Open fileFullName For Input As #1

の「1」の部分を変数で指定できるのか、やってみた。

まず、

f:id:akashi_keirin:20180125194514j:plain

Open fileFullName For Input As # & n

と書いてみると、

f:id:akashi_keirin:20180125194525j:plain

コンパイルエラーwww

Open fileFullName For Input As #n

と書けばエラーは出なかった。

実験

Openステートメントで開くときに指定したファイル番号が既に使われていると、

55:ファイルは既に開かれています

というエラーが出るので、

Do~Loopでエラーが出なくなるまでファイル番号をインクリメントすればいいんじゃね?

と考えたわけですよ。

コーディング

akashi-keirin.hatenablog.com

このときのリスト1getTextFromFileメソッドを改良する。

リスト1 標準モジュール
Public Function getTextFromFile( _
                  ByVal fileFullName As String, _
                  ByVal linesCount As Integer) As String()
  If Dir(fileFullName) = "" Then Exit Function
  On Error Resume Next    '……(1)'
    Dim n As Integer
    n = 0
    Do
      Err.Clear
      n = n + 1
      Open fileFullName For Input As #n
    Loop Until Err.Number = 0
  On Error GoTo 0
  Dim tmpArray() As String
  ReDim tmpArray(linesCount)
  Dim i As Integer
  For i = 0 To linesCount - 1
    If EOF(n) Then Exit For    '……(2)'
    Line Input #n, tmpArray(i)    '……(3)'
  Next
  getTextFromFile = tmpArray
  Close #n    '……(4)'
End Function

大きく変えたのは、(1)からの9行

On Error Resume Next
  Dim n As Integer
  n = 0
  Do
    Err.Clear
    n = n + 1
    Open fileFullName For Input As #n
  Loop Until Err.Number = 0
On Error GoTo 0

Openステートメント実行時にエラーが出なくなるまで変数 n をインクリメントする、という力技www

それに合わせて、(2)、(3)、(4)では

If EOF(n) Then Exit For    '……(2)'
Line Input #n, tmpArray(i)    '……(3)'
Close #n    '……(4)'

もともと「1」と指定していたファイル番号を全部「n」に置き換えた。

実行

次のテスト用コードで実行。

スト2 標準モジュール
Public Sub test()
  Dim targetDir As String
  targetDir = ThisDocument.Path & "\"       '"
  Open targetDir & "ち~んw.txt" For Input As #1    '……(1)
  Call main    '……(2)'
  Close #1
End Sub

まず、(1)の

Open targetDir & "ち~んw.txt" For Input As #1

で「ち~んw.txt」をファイル番号#1を割り当てて開き、

(2)の

Call main

akashi-keirin.hatenablog.com

このとき作成したリスト1mainモジュールを呼び出す。mainからはリスト1のgetTextFromFileメソッドを呼び出すことになる。

実行結果

1ループ目、

f:id:akashi_keirin:20180125194533j:plain

予定通り、エラーが出ている。

で、2ループ目で無事に実行できた。

おわりに

たぶん、もっといいやり方があるんだろうねえ。

もっといいやり方

akashi-keirin.hatenablog.com