こんにちは。
本日はちょっとしたサンプル。
テキストファイルに書き込みを行い、
ある一定のサイズになったら新しく新規のファイルを作成し、
これまでのファイルのインデックスをアップさせていく
クラスモジュールのサンプルです。
概要
Log20201030.txtのようなファイルを作ります。
指定したサイズを越えるまで、更新します。
サイズを越えるとき、ファイルのインデックスをアップさせて
Log20201030_1.txtを作成。
そして、Log20201030.txtをクリアします。
このインデックスが大きければ大きいほど古いファイルとなります。
インデックスが付いていないファイルが常に最新となります。
クラスモジュールの名前はLoggerとしておきます。
クラスモジュール(Logger)
Option Explicit ' 最大ファイルサイズ(byte) Const MaxFileSize As Long = 2000 ' ファイル関連 Private Const fileName As String = "Log" Private Const Extension As String = ".txt" Private Const SepaText As String = "_" Private Const TmpText As String = "tmp" Private FileDate As String Private Path As String Private FileFullName As String Private FSO As Object ' [1]クラス初期化処理 Private Sub Class_Initialize() Set FSO = CreateObject("Scripting.FileSystemObject") Path = ThisWorkbook.Path End Sub ' [2]クラス解放処理 Private Sub Class_Terminate() Set FSO = Nothing End Sub ' [3]ログ出力[Info] Public Sub Info(ByVal msg As String) Call MainProcess("[Info] " & Now & " : " & msg) End Sub ' [3]ログ出力[Warn] Public Sub Warn(ByVal msg As String) Call MainProcess("[Warn] " & Now & " : " & msg) End Sub ' [3]ログ出力[Error] Public Sub Error(ByVal msg As String) Call MainProcess("[Error] " & Now & " : " & msg) End Sub ' [4]メイン処理 Private Sub MainProcess(ByVal msg As String) FileDate = Format(Now, "yyyymmdd") FileFullName = Path & "\" & fileName & FileDate & Extension ' ファイルの存在チェック If Not FSO.FileExists(FileFullName) Then FSO.CreateTextFile (FileFullName) End If ' サイズチェック If IsOverMaxFileSize(msg) = True Then Call AdjustFileName End If ' 出力処理 Call WriteFileAppend(FileFullName, msg) End Sub ' [5] サイズチェック処理 Private Function IsOverMaxFileSize(ByVal msg As String) As Boolean Dim result As Boolean: result = False Dim tmpFile As String: tmpFile = Path & "\" & fileName & FileDate & SepaText & TmpText & Extension FileCopy FileFullName, tmpFile Call WriteFileAppend(tmpFile, msg) Dim size As Long: size = FileLen(tmpFile) If size > MaxFileSize Then result = True End If Kill tmpFile IsOverMaxFileSize = result End Function ' [6] 書き込み処理 Private Sub WriteFileAppend(ByVal fileName As String, ByVal msg As String) Open fileName For Append As #1 Print #1, msg Close #1 End Sub ' [7] ファイル名調整処理 Private Sub AdjustFileName() Dim fileArr() As String ReDim fileArr(0) Dim buf As String buf = Dir(Path & "\" & fileName & FileDate & "*") Do While buf <> "" fileArr(UBound(fileArr)) = buf ReDim Preserve fileArr(UBound(fileArr) + 1) buf = Dir() Loop If UBound(fileArr) > 0 Then ReDim Preserve fileArr(UBound(fileArr) - 1) End If Dim item As Variant For Each item In fileArr Dim oriFile As String: oriFile = Path & "\" & fileName & FileDate If InStr(item, SepaText) = 0 Then FileCopy FileFullName, oriFile & SepaText & "1" & Extension Else Dim tmp() As String: tmp = Split(item, Extension) Dim tmp2() As String: tmp2 = Split(tmp(0), SepaText) Dim num As Integer: num = tmp2(1) FileCopy Path & "\" & item, oriFile & SepaText & num + 1 & Extension End If Next item Open FileFullName For Output As #1 Close #1 End Sub
処理の詳細
[1]クラス初期化処理関数(Class_Initialize)
この関数は、クラスのインスタンスが生成された際に呼び出されます。
なので、処理で必要な情報をここで作成しておきます。
- FileSystemObjectのインスタンス作成
- パスを取得して、ベースとなるファイル名を取得
[2]クラス解放処理関数(Class_Terminate)
この関数は、クラスのインスタンスが破棄された際に呼び出されます。
今回は、FSOの解放を行っています。
[3]ログ出力処理関数(Info,Warn,Error)
この関数が実際に呼び出されます。
Info,Warn,Errorのそれぞれの出力用関数を作成しました。
[4]メイン処理関数(MainProcess)
ログを出力するにあったて必要な処理のメイン部分です。
引数に、出力する文字列を受け取ります。
- ファイルの存在チェック
- インデックスなしのファイルのサイズをチェック
- データの出力を行う
今回、ファイル名に日付を入れたかったので
Nowを使用して日付を取得しています。
1.にて、FileExistsでファイルが存在するかどうかチェックします。
存在しない場合は、CreateTextFileでファイルの作成を行います。
どちらも、FileSystemObjectのメソッドです。
2.にて、サイズチェック処理関数を呼び出します。
サイズが越えていた場合は、ファイル名更新処理関数を呼び出し、
ファイル名の更新を行っています。
3.にて、データの出力を行います。
[5] サイズチェック処理関数(IsOverMaxFileSize)
サイズチェックを行っているのはIsOverMaxFileSize関数です。
引数に、出力する文字列を受け取ります。
流れとしては、
- 最新のファイルのコピーをとる(tmpFile)
- tmpFileに一旦書き込みを行う
- tmpFileが指定したサイズを越えているか判定(FileLenを使用)
- 判定後、tmpFileは削除(Killを使用)
- 結果を呼び元に返す
これで、追加したあとのサイズを判定できます。
[6] 書き込み処理関数(WriteFileAppend)
ファイルへの書き込みはWriteFileAppend関数にて行っています。
引数に、出力する文字列を受け取ります。
Open,Closeは以下の内容になっています。
' fileName を追加書き込みモードで番号1としてオープンする Open fileName For Append #1 ' ファイル番号1にmsgを書き込む Print #1, msg ' ファイル番号1を閉じる Close #1
[7]ファイル名調整処理関数(AdjustFileName)
IsOverMaxFileSizeでサイズ越えてるよってなった場合
AdjustFileName関数にてファイルのインデックスを調整します。
一旦、指定場所(今回はマクロがおいてある場所)にある対象の日付を含む
テキストファイル名を取得します。
ここでの処理については以下の記事を参照して下さい。
現在の最新となるインデックスなしのファイルはインデックス1をつけてコピーし、
すでにインデックスが振られているファイルは
現在のインデックスに1プラスしたインデックスのファイルにコピーします。
最後に、最新となるインデックスなしのファイルを空にします。
先程使用したOpen,Closeを使います。
ここでは、空にしたいだけなので、上書きモード(Output)で開いています。
' FileFullName を上書きモードで番号1としてオープンする Open FileFullName For Output As #1 ' ファイル番号1を閉じる Close #1
使用方法
使用方法はこんな感じです。
Option Explicit Sub Main() ' インスタンス生成 Dim log As LogUtils Set log = New LogUtils log.Info ("情報を出力します。") log.Warn ("ワーニングを出力します。") log.Error ("エラーを出力します。") Set log = Nothing End Sub
テキストファイルに以下の内容が出力されました。
[Info] 2020/10/27 13:56:23 : 情報を出力します。 [Warn] 2020/10/27 13:56:23 : ワーニングを出力します。 [Error] 2020/10/27 13:56:23 : エラーを出力します。
以上です。