lisz-works

技術系だけど関係ないこと多い系ブログ

VBA ファイル出力クラスを作ってみた

【スポンサーリンク】

Excel ロゴ

Excel VBAで、ファイル出力をする為のクラスを作成しました。

ファイルの扱いの管理(主にファイル番号)が面倒なので、これで楽にできます!

2018.01.15:Openのファイルオープンタイプが誤っていたので修正しました。

ファイル出力用クラス

今回はファイル出力用のクラスを作成してみました。

Option Explicit

' 定数:ファイルオープンタイプ(内部で使用する用)
Const COPEN_TYPE_NONE = 1000
Const COPEN_TYPE_INPUT = 1001
Const COPEN_TYPE_OUTPUT = 1002
Const COPEN_TYPE_APPEND = 1003
' 定数:ファイルオープンタイプ(外部で使用する用)
Public OPEN_TYPE_NONE As Integer
Public OPEN_TYPE_INPUT As Integer
Public OPEN_TYPE_OUTPUT As Integer
Public OPEN_TYPE_APPEND As Integer

' クラスメンバ
Public fileName As String           ' ファイル名
Public openType As Integer          ' ファイルオープンタイプ
Public isInitialized As Boolean     ' 初期化完了フラグ
Public fileNo As Integer            ' ファイル番号

' コンストラクタ
Private Sub Class_Initialize()
    OPEN_TYPE_NONE = COPEN_TYPE_NONE
    OPEN_TYPE_INPUT = COPEN_TYPE_INPUT
    OPEN_TYPE_OUTPUT = COPEN_TYPE_OUTPUT
    OPEN_TYPE_APPEND = COPEN_TYPE_APPEND
End Sub


' 初期化処理
Public Sub Initialize(fname As String, openType As Integer, fileNo As Integer)
    fileName = fname
    isInitialized = True
    Me.fileNo = fileNo
    
    Select Case openType
    Case COPEN_TYPE_INPUT
        Open fileName For Input As #Me.fileNo
        Me.openType = COPEN_TYPE_INPUT
    Case COPEN_TYPE_OUTPUT
        Open fileName For Output As #Me.fileNo
        Me.openType = COPEN_TYPE_OUTPUT
    Case COPEN_TYPE_APPEND
        Open fileName For Append As #Me.fileNo
        Me.openType = COPEN_TYPE_APPEND
    Case Else
        isInitialized = False
        Me.openType = COPEN_TYPE_NONE
    End Select
End Sub

' 書き込み処理
Public Sub writeFile(text As String)
    If Me.openType <> COPEN_TYPE_OUTPUT And Me.openType <> COPEN_TYPE_APPEND Then
        Exit Sub
    End If
    Print #Me.fileNo, text
End Sub

' 読み込み処理
Public Sub readFile(text As String)
    If Me.openType <> COPEN_TYPE_INPUT Then
        Exit Sub
    End If
    
    ' T.B.D.
End Sub


' デストラクタ
' NothingのSet時に発生する
Private Sub Class_Terminate()
    If isInitialized Then
        Close #Me.fileNo
    End If
End Sub

読込にも対応しようとした為、読込関数もあります……
現状コールしてもなにもなりません(笑)

クラスの使い方

1.生成と初期化

まずクラスのインスタンスを生成します。

Set file = New FileManager

次に初期化します。
これは必ず行ってください。

Call file.Initialize("出力ファイル.txt", file.OPEN_TYPE_OUTPUT, 1)

本当はコンストラクタで一緒に初期化したかったのですが、引数を渡す方法がわからなかったのでやむを得ずこの形を……

引数は

  1. 出力ファイル名
  2. ファイルオープンタイプ
  3. ファイル番号

ファイルオープンタイプは、クラスに定義されている

  1. OPEN_TYPE_INPUT:入力
  2. OPEN_TYPE_OUTPUT:出力(新規)
  3. OPEN_TYPE_APPEND:出力(追記)

です。
用途に合わせてセットします。

ファイル番号は、任意の数字です。

複数ファイルの出力をする場合は、ファイルごとに違う値をセットしないといけません。

2.出力

出力は「writeFile()」で行います。

Call file.writeFile("出力する文字列")

これだけです。

初期化時にファイルオープンタイプを、OPEN_TYPE_OUTPUTかOPEN_TYPE_APPEND以外に設定していると、書込を行ってくれないのでご注意を。

3.終了する

明示的にに終了させる場合はこのようにします。

Set file = Nothing

これでデストラクタ(Class_Terminate)が実行されます。

初期化済みの場合、ファイルのクローズ処理を勝手にやってくれます!

恐らく単純にプログラムがそのまま終了するのであれば、そのまま終了させちゃっても大丈夫だとは思いますが……

なぜクラスにしたのか?

そもそもの思いとしては、管理が面倒だったから。

  1. ファイルオープン・クローズの忘れを防止
  2. ファイル番号の管理

主にこの2つを自動でやってほしいというのが狙いでした。

なので本当は

  • オープン→コンストラクタ
  • クローズ→デストラクタ

としたかったのですが、コンストラクタをInitializeで代用……

しかし、デストラクタを設けることで、クローズは確実に行ってくれます。

更に、ファイル番号をクラスメンバで持ってもらうことで、毎度セットする必要がない。

ファイル出力が、関数に文字列渡すだけでOKというのが楽ポイントです。
関数だと、自力でファイル番号ガチャガチャいじらないといけないと思うので。

参考ページ

これらのページを参考にさせて頂きました。

ありがとうございました!!

excelvba.pc-users.net

qiita.com

tonari-it.com

thom.hateblo.jp

beatdjam.hatenablog.com

あとがき

というわけでファイル管理クラスについてでした。

今回、個人的に出力しか需要がなかったので入力を実装していませんが、どっかのタイミングで作りたいですね……

心残りはコンストラクタで引数が渡せない件と、ファイルオープン用の定数がConstだと外部から見えなかったことですね……

なんか変なところで制約がある感じが、VBAの面倒なところな気がします。
(コスト的に結局VBAで組んじゃいましたが)