この記事は、エーピーコミュニケーションズ Advent Calendar 2021 の7日目のエントリです。
はじめに
やったこと
Excelパラメータシートの一部を、Yamlファイルとして出力します。
このExcelパラメータが、
匠(VBA)の手により、
Yamlに生まれ変わりました!
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だった。