サイトアイコン わんすけに聞いてみる

vbscriptでクラスを考えてみる。②

前回の記事では、漠然と縦に書いていたスクリプトをSub/Functionで纏めてみたり、それでもコードが複雑になりそうだからクラスで纏めてみるっていうアプローチでクラスについて説明しました。 クラス「Class」について使い方を調べると、こんなソースがよく出てきます。
Dim Asan, Bsan
' 1つ目のインスタンス
Set Asan = New Person
Asan.Name = "わたし"
Asan.Age = 30
' 2つ目のインスタンス
Set Bsan = New Person
Bsan.Name = "あなた"
Bsan.Age = 20
' それぞれのインスタンスで別のName、Ageを管理できてるかな?
Msgbox Asan.Name & "(" & Asan.Age & ")"
Msgbox Bsan.Name & "(" & Bsan.Age & ")"

' ここがクラスの定義 ただPublic属性を二つ持つだけ。
Class Person
  Public Name
  Public Age
End Class
で、こんなことを言います。 これを実行すると、「わたし(30)」、「あなた(20)」とメッセージボックスが表示されます。クラスから生成されるインスタンスは別のオブジェクトとして扱われる為、異なる値を管理することができます。 みたいな。 これだけだと「ふーん、で?全部個別に変数使うのと何が違うの?」って思う訳です。前回のファイル操作するクラスの例に立ち返って考えてみましょう。
前回の振り返り
Dim clsTxt
' 二つのテキストを読み込む処理
Set clsTxt = New clsText
log1 = clsTxt.ReadText("yyyymmdd.log")
log2 = clsTxt.ReadText("err_msg.log")
Set clsTxt = Nothing

' ここからクラスの定義
Class clsText
  ' fsoはクラスのインスタンスの中で共有的に使える。
  Private fso
  Private Sub Class_Initialize
    ' New された時に実行される処理
    Set fso = CreateObject("Scripting.FileSystemObject")
  End Sub

  Private Sub Class_Terminate
    ' Nothing とかでインスタンスが破棄された時に実行される処理
    Set fso = Nothing
  End Sub

  ' Publicで宣言されたコードはインスタンスの外から呼び出しができる。
  Public Function ReadText(path)
    Dim f
    If fso.FileExists(path) Then
      Set f = fso.OpenTextFile(path, 1)
      ReadText = f.ReadAll
      f.Close
    Else
      ReadText = ""
    End If
  End Function
  ' 他にもいろいろfso使う処理を入れていく・・・。
End Class
これはこれで、fsoを何度も使いまわしたり、オブジェクトのライフサイクルを考えると便利だよねーっていうのが前回の話。 このクラスに、インスタンスでは個別のデータを保管できるという特性を合わせるとどうなるのか?すこし試してみましょう。
Dim log1
' テキストを読み込んでリネームする処理
Set log1 = New clsTextFile
log1.Path = "yyyymmdd.log"  ' インスタンスに固有データを設定
Msgbox log1.ReadText()      ' 設定したPathのデータを読み込むので引数がいらなくなった。
If log1.FileNameChange("yyyymmdd-1.log") Then  ' ファイル名を変えてみる
  Msgbox "「" & log1.Path & "」にリネームしました。" ' 新しいファイル名にPathが更新されてる
End If
Set log1 = Nothing

' ここからクラスの定義
Class clsTextFile
  ' ファイルパスをインスタンスに持たせてみる。
  Public Path
  Private fso
  Private Sub Class_Initialize
    ' New された時に実行される処理
    Set fso = CreateObject("Scripting.FileSystemObject")
  End Sub
  Private Sub Class_Terminate
    ' Nothing とかでインスタンスが破棄された時に実行される処理
    Set fso = Nothing
  End Sub
  
  ' インスタンスとしてPath持ってるから渡す必要なくなった。
  Public Function ReadText()
    Dim f
    If fso.FileExists(Path) Then
      Set f = fso.OpenTextFile(Path, 1)
      ReadText = f.ReadAll()
      f.Close
    Else
      ReadText = ""
    End If
  End Function
  
  ' リネームしてみる 成功したら Trueが返ってくる
  Public Function FileNameChange(NewFileName)
    Dim Rslt
    If fso.FileExists(Path) Then
      With fso.GetFile(Path)
        .Name = NewFileName  ' ファイル名を変える。
        Path = .Path         ' インスタンスのPathをリネーム後のファイルに更新する。
      End With
      Rslt = True
    Else
      Rslt = False
    End If
  End Function
  ' 他にもいろいろfso使う処理を入れていく・・・。
End Class
前回の例では、fsoを効果的に使う道具っぽい感じで機能していたクラスですが、こうしてみるとlog1自体がログファイルっぽく見えてきませんか?
Dim log1
Set log1 = New clsTextFile
log1.Path = "yyyymmdd.log"  ' インスタンスに固有データを設定
Msgbox log1.ReadText()      ' 設定したPathのデータを読み込むので引数がいらなくなった。
If log1.FileNameChange("yyyymmdd-1.log") Then  ' ファイル名を変えてみる
  Msgbox "「" & log1.Path & "」にリネームしました。" ' 新しいファイル名にPathが更新されてる
End If
Set log1 = Nothing
log1に生成したインスタンスを入れてPathを設定したら、log1に対してReadTextやFileNameChangeといった命令を渡すことでテキストファイルを直接操作できるようになっています。 なんとなく、インスタンス自体に「オブジェクト」感がでてきたのではないでしょうか? 長いシナリオで対象のファイルに様々な処理を行う場合には、おすすめな記述方法です。 が、そこまで長くない処理ではまだかえって煩わしさの方が強いかもしれません。。。 今度、これぞクラスで定義してるから使い回しいいぞってクラス作って紹介することにします。   次回はすこし、別のテーマに触れてみようかな。
モバイルバージョンを終了