mito’s blog

IT技術メインの雑記。思い立ったが吉日。

VBAでパラメータ.yamlを作る

この記事は、エーピーコミュニケーションズ Advent Calendar 2021 の7日目のエントリです。

はじめに

Excelは便利だしVBAでもいいじゃない。

やったこと

Excelパラメータシートの一部を、Yamlファイルとして出力します。


このExcelパラメータが、

f:id:mst-it:20211205184025j:plain


匠(VBA)の手により、

f:id:mst-it:20211205184046j:plain
f:id:mst-it:20211205184056j:plain


Yamlに生まれ変わりました!

f:id:mst-it:20211205184113j:plain



VBA

以下がコードです。
Excelパラメータの図と同じ形式のデータを用意する必要があります。

'変数の宣言を強制する
Option Explicit

'グローバル変数(関数をまたいで使用する)
'データの検索範囲
'データ行の始め(Constで宣言した変数は定数となり、書き換えできない)
Const ROW_START As String = 4
'データ行の終わり
Const ROW_END As String = 10
'データ列の始め
Const COLUMN_START As String = "A"
'データ列の終わり
Const COLUMN_END As String = "H"

'YAMLの行数
Const YAML_MAX_COLUMUN As Long = 6

'YAMLを生成するパラメータの行番号
Dim YAML_NUMBER As Long
'YAMLのファイル内容(項目と値の2つをセットとし、YAML_MAX_COLUMUN 行数分を用意する)
Dim YAML_CONTENTS(2, YAML_MAX_COLUMUN) As String


'ボタンクリックで呼び出す関数
Sub create_yaml()

    Dim res_number As Boolean

    'YAMLに起こす番号を選択
    res_number = input_number()

    If res_number = False Then
        MsgBox "ないわー、それはないわー"
        Exit Sub
    End If

    'YAMLの内容を初期化
    Call format_yaml

    'YAMLの内容をセット
    Call set_yaml

    'YAMLを上書き作成
    Call output_yaml

End Sub


'YAMLに起こす番号を選択する関数
'    マクロに設定する関数ではないため、Privateをつけている
'    関数の処理結果(Boolean)を返したいため、subではなくFunctionにしている
Private Function input_number() As Boolean

    'この関数内でエラーが起きても処理を続ける。親関数でエラーハンドリングをしたいため。
    On Error Resume Next

    '数字に型変換して格納する
    YAML_NUMBER = CLng(InputBox("番号を数字で入力してください", "番号", ""))

    '番号が存在するかチェック
    input_number = vlookup_parameters(1)

    '番号が何も入力されていない
    If YAML_NUMBER = 0 Then
       input_number = False
    End If

    '入力内容が正しくない場合、Falseをセットする
    If Err.Number <> 0 Then
        input_number = False
    End If

End Function


'YAMLの内容を初期化する関数
'パラメータを増減するなら、この関数を修正する
Private Sub format_yaml()

    'YAMLファイルとなる配列を初期化する
    YAML_CONTENTS(0, 0) = "---"
    YAML_CONTENTS(0, 1) = "daikoumoku: "
    YAML_CONTENTS(0, 2) = "router: "
    YAML_CONTENTS(0, 3) = "settings:"
    YAML_CONTENTS(0, 4) = "  interface: "
    YAML_CONTENTS(0, 5) = "  description: "

    YAML_CONTENTS(1, 0) = ""
    YAML_CONTENTS(1, 1) = ""
    YAML_CONTENTS(1, 2) = ""
    YAML_CONTENTS(1, 3) = ""
    YAML_CONTENTS(1, 4) = ""
    YAML_CONTENTS(1, 5) = ""

End Sub


'パラメータをYamlにする配列へセットする関数
'パラメータを増減するなら、この関数を修正する
Private Sub set_yaml()

    'vlookupで大項目の列を指定し、値をとってくる
    YAML_CONTENTS(1, 1) = vlookup_parameters(2)

    'vlookupで機器名の列を指定し、値をとってくる
    YAML_CONTENTS(1, 2) = vlookup_parameters(3)

    '機器の設定
    'interface
    YAML_CONTENTS(1, 4) = vlookup_parameters(4)
    'description
    YAML_CONTENTS(1, 5) = vlookup_parameters(5)

    '値の整形
    Dim i As Long
    For i = 0 To (YAML_MAX_COLUMUN - 1)
        '全ての半角SPを削除(値に半角SPが入っていたら、意図したコマンドにならないため)
        YAML_CONTENTS(1, i) = Replace(YAML_CONTENTS(1, i), " ", "")

        '全角文字が入っていたら"で囲む
        If Len(YAML_CONTENTS(1, i)) <> LenB(StrConv(YAML_CONTENTS(1, i), vbFromUnicode)) Then
            '""""は1,4つめが文字くくり、2つめはエスケープ文字、3つめが実際の文字
            YAML_CONTENTS(1, i) = """" & YAML_CONTENTS(1, i) & """"
        End If
    Next

End Sub

'Excelから指定のパラメータを返す関数
Private Function vlookup_parameters(i As Long) As String

    'Vlookup関数を呼び出している。引数はセルに記載するときのVlookupと同じ
    vlookup_parameters = Application.WorksheetFunction.VLookup(YAML_NUMBER, Range(Cells(ROW_START, COLUMN_START), Cells(ROW_END, COLUMN_END)), i, False)

End Function


'YAMLファイルを作成する関数
Private Sub output_yaml()

    'ファイル名に大項目_YYMMDDhhmm.ymlを設定する
    Dim yaml_name As String
    Dim yaml_date As Date

    yaml_date = Now
    yaml_name = vlookup_parameters(2) & "_" & Year(yaml_date) & Month(yaml_date) & Day(yaml_date) & Hour(yaml_date) & Minute(yaml_date) & ".yml"

    'ファイルパスの設定(本エクセルと同じフォルダを指定する)
    Dim file_path As String
    file_path = ActiveWorkbook.Path & "/" & yaml_name

    'ここからファイル書き込み
    Dim n As Long
    n = FreeFile
    Open file_path For Output As #n

    Dim i As Long
    For i = 0 To (YAML_MAX_COLUMUN - 1)
        Print #n, YAML_CONTENTS(0, i); YAML_CONTENTS(1, i)
    Next

    Close #n
    'ここまでファイル書き込み

    '処理が終わったかわかるようにメッセージを出す
    MsgBox "YAMLファイルを作成しました", vbInformation

    'ファイルを開く
    Dim WSH
    Set WSH = CreateObject("Wscript.Shell")
    WSH.Run file_path, vbNormalFocus
    Set WSH = Nothing

End Sub



備考

Option Base 1は使ったことないんだけど、おそらくわかりやすくなる?他言語との違いはどうだったかなぁ。
あと、Yamlファイル名の変数はNamlがいいかなと思ったけどNamulだった。