0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

設計書からコード生成 ツールの作成(VBA)

0
Last updated at Posted at 2025-01-21

はじめに

詳細設計書に定義されている内容が膨大かつ単純な実装だったため、一括でコードを生成するためのツールを作成していく

ツールの仕様

excelマクロ(vba)で作成する。
1.以下のような形式を大量に作成したいとする。

        <label for="name">名前:</label><br>
        <input type="text" id="name" name="name" required><br><br>

 
2.変数にしなければならない箇所を決める。

        <label for="A">B:</label><br>
        <input type="C" id="A" name="A" required><br><br>

A,B,Cと3つの変数が必要だとわかる。

※ソースコードはページ最後に記載する。

3.UI作成
以下のようにシートを用意する。
文言や色は適当でいいがセルの場所は一致させるように。
image.png

4.値1または値2に変数に格納したい値を入力。
2データ毎にカウントアップさせたいからループ行数に2を入力。
image.png

5.テンプレ作成
手順2で確認した内容をベースに初回の変数を割り当てる。
作成したテンプレをI1セルに入力。
[セル]で入力。

I1セル用テンプレート
        <label for="[C2]">[D2]:</label><br>
        <input type="[C3]" id="[C2]" name="[C2]" required><br><br>

image.png

6.置換実行
値1or値2が空になるまでループして置換をしてくれる。
image.png

7.ファイル出力
E列に出力された内容をそのままコピーすると不要なダブルクォーテーションが付くため
ファイル出力ボタンより出力するのが楽。
任意のパスをM1セルに入力し実行すると格納される。
image.png

処理概要

  • テンプレート凡例(前後削除も可能)
    [C3]⇒C3セルに置換
    [D4]⇒D4セルに置換
    [C5f1]⇒C5セルの前1文字を省き、置換
    [D6b2]⇒D6セルの後ろ2文字を省き、置換
    [C10F2B1]⇒C10セルの前2文字、後ろ1文字を省き、置換
  • 処理開始時
    出力結果を削除する。
  • 処理の終了
    次のループ時にC、D列両方の値が空の場合。
  • ループ行数
    カウントアップ数値

置換ソースコード


Sub CreateTemplate()
    Dim i As Integer
    Dim outputRow As Integer
    Dim template As String
    Dim cValue As String
    Dim dValue As String
    Dim rowsPerTemplate As Integer
    Dim customCValue As String
    Dim customDValue As String
    Dim customNumber As Integer
    Dim placeholder As String
    Dim startPos As Integer
    Dim endPos As Integer
    Dim fPos As Integer
    Dim bPos As Integer
    
    ' I1セルからテンプレート文字列を取得
    template = Range("I1").Value
    
    ' B1セルからループする行数を取得
    rowsPerTemplate = Range("B1").Value
    
    ' E列のE2以降のセルを削除しておく(E1以外)
    If Not IsEmpty(Range("E2").Value) Then
        Range("E2:E" & Cells(Rows.Count, 5).End(xlUp).Row).ClearContents
    End If

    ' 出力を開始する行(E列の行番号)
    outputRow = 2
    
    ' C列とD列のデータを順番に処理するループ
    i = 2 ' 最初のデータ行(C2D2
    ' C列とD列両方が空でない限りループ
    Do While Not (Cells(i, 1).Value = "" And Cells(i, 4).Value = "")
        ' ループする行数分だけテンプレートを生成
        Dim currentTemplate As String
        currentTemplate = template ' テンプレート文字列をコピー
        
        ' テンプレート内の[C][D]の部分をC列とD列の値で置換
        For j = 0 To rowsPerTemplate - 1
            ' C列とD列の値を取得してテンプレートに挿入
            cValue = Cells(i + j, 3).Value ' C列の値
            dValue = Cells(i + j, 4).Value ' D列の値
            
            ' [C][D]を対応するセルの値に置換
            currentTemplate = Replace(currentTemplate, "[C" & (j + 2) & "]", cValue)
            currentTemplate = Replace(currentTemplate, "[D" & (j + 2) & "]", dValue)
            
            ' [C2bX]の場合は末尾のX文字を削除
            placeholder = "[C" & (j + 2) & "b"
            startPos = InStr(currentTemplate, placeholder)
            If startPos > 0 Then
                ' bプレースホルダーを見つけた場合、末尾の文字数を取得
                endPos = InStr(startPos, currentTemplate, "]")
                If endPos > 0 Then
                    ' b数字(X)を抽出
                    customNumber = CInt(Mid(currentTemplate, startPos + Len(placeholder), endPos - startPos - Len(placeholder)))
                    ' C列の値から末尾X文字を削除
                    customCValue = Left(cValue, Len(cValue) - customNumber)
                    ' bプレースホルダーを置換
                    currentTemplate = Replace(currentTemplate, placeholder & customNumber & "]", customCValue)
                End If
            End If
            
            ' [C2fX]の場合は先頭のX文字を削除
            placeholder = "[C" & (j + 2) & "f"
            startPos = InStr(currentTemplate, placeholder)
            If startPos > 0 Then
                ' fプレースホルダーを見つけた場合、先頭の文字数を取得
                endPos = InStr(startPos, currentTemplate, "]")
                If endPos > 0 Then
                    ' f数字(X)を抽出
                    customNumber = CInt(Mid(currentTemplate, startPos + Len(placeholder), endPos - startPos - Len(placeholder)))
                    ' C列の値から先頭X文字を削除
                    customCValue = Mid(cValue, customNumber + 1)
                    ' fプレースホルダーを置換
                    currentTemplate = Replace(currentTemplate, placeholder & customNumber & "]", customCValue)
                End If
            End If

            ' [D2bX]の場合は末尾のX文字を削除
            placeholder = "[D" & (j + 2) & "b"
            startPos = InStr(currentTemplate, placeholder)
            If startPos > 0 Then
                ' bプレースホルダーを見つけた場合、末尾の文字数を取得
                endPos = InStr(startPos, currentTemplate, "]")
                If endPos > 0 Then
                    ' b数字(X)を抽出
                    customNumber = CInt(Mid(currentTemplate, startPos + Len(placeholder), endPos - startPos - Len(placeholder)))
                    ' D列の値から末尾X文字を削除
                    customDValue = Left(dValue, Len(dValue) - customNumber)
                    ' bプレースホルダーを置換
                    currentTemplate = Replace(currentTemplate, placeholder & customNumber & "]", customDValue)
                End If
            End If

            ' [D2fX]の場合は先頭のX文字を削除
            placeholder = "[D" & (j + 2) & "f"
            startPos = InStr(currentTemplate, placeholder)
            If startPos > 0 Then
                ' fプレースホルダーを見つけた場合、先頭の文字数を取得
                endPos = InStr(startPos, currentTemplate, "]")
                If endPos > 0 Then
                    ' f数字(X)を抽出
                    customNumber = CInt(Mid(currentTemplate, startPos + Len(placeholder), endPos - startPos - Len(placeholder)))
                    ' D列の値から先頭X文字を削除
                    customDValue = Mid(dValue, customNumber + 1)
                    ' fプレースホルダーを置換
                    currentTemplate = Replace(currentTemplate, placeholder & customNumber & "]", customDValue)
                End If
            End If

            ' [C2F2B3]の場合は先頭2文字と末尾3文字を削除
            placeholder = "[C" & (j + 2) & "F"
            startPos = InStr(currentTemplate, placeholder)
            If startPos > 0 Then
                ' Fプレースホルダーを見つけた場合、先頭の文字数を取得
                endPos = InStr(startPos, currentTemplate, "B")
                If endPos > 0 Then
                    ' F数字(X)を抽出
                    fPos = CInt(Mid(currentTemplate, startPos + Len(placeholder), endPos - startPos - Len(placeholder)))
                    
                    ' Bプレースホルダーを見つけた場合、末尾の文字数を取得
                    bPos = InStr(endPos, currentTemplate, "]")
                    If bPos > 0 Then
                        ' B数字(Y)を抽出
                        customNumber = CInt(Mid(currentTemplate, endPos + 1, bPos - endPos - 1))
                        ' C列の値から先頭F文字と末尾B文字を削除
                        customCValue = Mid(cValue, fPos + 1, Len(cValue) - fPos - customNumber)
                        ' FとBプレースホルダーを置換
                        currentTemplate = Replace(currentTemplate, "[C" & (j + 2) & "F" & fPos & "B" & customNumber & "]", customCValue)
                    End If
                End If
            End If

            ' [D2F2B3]の場合は先頭2文字と末尾3文字を削除
            placeholder = "[D" & (j + 2) & "F"
            startPos = InStr(currentTemplate, placeholder)
            If startPos > 0 Then
                ' Fプレースホルダーを見つけた場合、先頭の文字数を取得
                endPos = InStr(startPos, currentTemplate, "B")
                If endPos > 0 Then
                    ' F数字(X)を抽出
                    fPos = CInt(Mid(currentTemplate, startPos + Len(placeholder), endPos - startPos - Len(placeholder)))
                    
                    ' Bプレースホルダーを見つけた場合、末尾の文字数を取得
                    bPos = InStr(endPos, currentTemplate, "]")
                    If bPos > 0 Then
                        ' B数字(Y)を抽出
                        customNumber = CInt(Mid(currentTemplate, endPos + 1, bPos - endPos - 1))
                        ' D列の値から先頭F文字と末尾B文字を削除
                        customDValue = Mid(dValue, fPos + 1, Len(dValue) - fPos - customNumber)
                        ' FBプレースホルダーを置換
                        currentTemplate = Replace(currentTemplate, "[D" & (j + 2) & "F" & fPos & "B" & customNumber & "]", customDValue)
                    End If
                End If
            End If
        Next j
        
        ' 結果をE列に出力
        Cells(outputRow, 5).Value = currentTemplate
        
        
        ' E列に出力したセルの折り返しを無効にする
        Cells(outputRow, 5).WrapText = False
        
        ' 次のテンプレートを出力するために行番号を変更
        outputRow = outputRow + 1
        
        ' 次のテンプレートを作成するために行番号を進める
        i = i + rowsPerTemplate
    Loop
End Sub

ファイル出力ソースコード

Sub ExportEColumnData()
    Dim ws As Worksheet
    Dim filePath As String
    Dim lastRow As Long
    Dim i As Long
    Dim fileNum As Integer
    Dim outputLine As String

    Set ws = ThisWorkbook.Sheets(1) ' 対象シート(必要に応じて変更)
    filePath = Trim(ws.Range("M1").Value)
    
    ' ファイルパスが入力されていない場合
    If filePath = "" Then
        MsgBox "出力ファイルパスが設定されていません。", vbExclamation
        Exit Sub
    End If

    ' E列の最終行を取得(空白で止まる)
    lastRow = ws.Cells(ws.Rows.Count, "E").End(xlUp).Row
    If lastRow < 2 Then
        MsgBox "出力対象のデータがありません。", vbExclamation
        Exit Sub
    End If

    ' ファイル出力処理
    On Error GoTo ErrHandler
    fileNum = FreeFile
    Open filePath For Output As #fileNum

    For i = 2 To lastRow
        If ws.Cells(i, "E").Value <> "" Then
            Print #fileNum, ws.Cells(i, "E").Value
        End If
    Next i

    Close #fileNum
    MsgBox "ファイル出力成功", vbInformation
    Exit Sub

ErrHandler:
      MsgBox "ファイル出力時にエラーが発生しました: " & Err.Description, vbCritical
      On Error Resume Next
      Close #fileNum
End Sub
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?