t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

VBA 2段階Splitで文字列からオブジェクトコレクションを作る

今回のワザは、VBAでパズルを解こうとしたときに思いついた副産物である。

先日Twitterにてコーヘーさんより以下のつぶやきが。

その、プログラムで解くパズルというのがこちらのツイート。

油分け算と同じく、パックトラック法で解けると踏んでいたが、なかなか思うように動かずいまだ完成していない。。

さて、今回はそのプログラムを試行錯誤している中で使ったテクニックである。

まず駒を表すクラスを作成した。
クラス名はそのまま、駒として、以下のコードを張り付ける。

Public X As Integer
Public Y As Integer
Public 名前 As String

Function Self() AsSet Self = Me
End Function

他に進むメソッドなども実装してあるが、今回のネタと関係ないので省略。

そして、駒オブジェクトを生成するサンプルコード。

Sub ObjectCollectionSample()
    Dim 駒コレクション As Collection
    Set 駒コレクション = New Collection
    For Each k In Split("赤,2,4|緑,4,2|青,5,4", "|")
        With New.名前 = Split(k, ",")(0)
            .X = Split(k, ",")(1)
            .Y = Split(k, ",")(2)
            駒コレクション.Add .Self, .名前
        End With
    Next
    
    Dim コマ AsFor Each コマ In 駒コレクション
        Debug.Print コマ.名前; コマ.X; コマ.Y
    Next
End Sub

※元のパズルでは青が2つであるが、プログラム上で青1・青2とするのはややこしいので片方を緑としておいた。

ポイントは、Split関数に渡す最初の文字列をカンマとパイプの2種類の記号で区切っていること。
最初のSplitではパイプで切り分けるので、k(0)="赤,2,4"、k(1)="緑,4,2"、k(2)="青,5,4" となる。
Fo文の内部のSplitではさらにkをカンマで区切ったものをインデックス指定してオブジェクトのプロパティに設定している。

このように複数種類の記号をデリミタとして使えば、フィールド×レコードの2次元情報を単純な文字列として表現できる。

コードが複雑になるのでチーム開発には向かないかもしれないが、決まった初期値を設定するのに冗長なコードを書くはつらいので個人的なマクロではこういうテクニックも有りかと思う。

以下はマクロにマクロを書かせるパターン。

Sub マクロにマクロを書かせる()
    For Each k In Split("赤,2,4|緑,4,2|青,5,4", "|")
        n = n + 1
        Debug.Print "Dim 駒"; CStr(n); " As String : 駒"; CStr(n); "Name = """ & Split(k, ",")(0) & """"
        Debug.Print "Dim 駒"; CStr(n); "X As Integer : 駒"; CStr(n); "X = " & Split(k, ",")(1)
        Debug.Print "Dim 駒"; CStr(n); "Y As Integer : 駒"; CStr(n); "Y = " & Split(k, ",")(2)
    Next
End Sub

実行すると、冗長だけどシンプルなコードを得られる。

Dim1 As String : 駒1Name = "赤"
Dim 駒1X As Integer : 駒1X = 2
Dim 駒1Y As Integer : 駒1Y = 4
Dim2 As String : 駒2Name = "緑"
Dim 駒2X As Integer : 駒2X = 4
Dim 駒2Y As Integer : 駒2Y = 2
Dim3 As String : 駒3Name = "青"
Dim 駒3X As Integer : 駒3X = 5
Dim 駒3Y As Integer : 駒3Y = 4

以上

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。