ウィリアムのいたずらの、まちあるき、たべあるき

ウィリアムのいたずらが、街歩き、食べ物、音楽等の個人的見解を主に書くブログです(たま~にコンピューター関係も)

仕様書からプログラムソースを生成する方法(Excelの仕様書編 その19:メニュー追加 ソース)。

2006-12-19 17:45:11 | ケータイ

 BREWの画面部分のプログラムをExcelの仕様書から自動生成するという、シリーズ仕様書からプログラムソースを生成する方法の続きです。

 今、仕様書にメニュー部分を追加しています。
 以前、ここに、以下の手順で考えると良いとかきました


メニュー項目に限らず、このような、雛形があって、そこから、自動生成する場合については、以下のような手順で考えると、考えやすいと思います。

1.仕様を決める
2.仕様を満たすためには、どういう出力をすればいいか-出力ソースサンプルを作る
3.サンプルをもとに雛形を作る
4.雛形から、出力にもってくるプログラム部分を作成する。


 前回、雛形を作ったので、今回は、「プログラム部分を作成する」です。




■プログラムの仕様について

 ということで、プログラムを書きます。
 メニューを追加する場合、以下のように動くことになります

1.作業用ワークシートを作成する
2.もともとのワークシートを、作業用ワークシートに書き写す
3.作業一覧を作成する
4.作業一覧をもとに、雛形と、2で作った仕様書からプログラムを生成する
5.作業が終わったら、2のワークシートを削除する。

 今回、4はすでにある(標準化されている)ので、1~3と5を作ることになります。
 1~3に関しては、initAppData()、5はfreeAppData()でつくります。
 今回、2の作業をひとつの関数にしました。それが、makeSagyoSheetです。

 これらの関数をVBAで作成します。

 なお、作業用ワークシートの名前ですが、ワークシートの名前の頭に@をつけることにしました。つまり、第一画面シートの作業用シートは@第一画面です。




■ソース
 ということで、Excelの仕様書で、「ドキュメント作成」ボタンが押されてから動くマクロプログラムのうち、今回修正/追加される、initAppData、freeAppData、makeSagyoSheetのソースは、以下のとおりです。

'//*************************************************//
'//                                                 //
'//         個別処理                                //
'//                                                 //
'//*************************************************//
Public Const gamen_teigi_str_gyo As Integer = 5 '画面定義の開始行

'//=========================//
'//     前処理              //
'//=========================//
Sub initAppData()
    Dim gyo As Integer
    Dim pathdir As String
    Dim i As Integer
    Dim j As Integer
    Dim sagyoShname As String       '   作業用シート名
    Dim sagyoSh As Worksheet       '   作業用シート名
    Dim shname() As String
    
    '// 作業一覧シートクリア
    gyo = Sheets("作業一覧").Range("A65536").End(xlUp).Row
    If (gyo >= 5) Then
        Sheets("作業一覧").Range("A5:C" & CStr(gyo)).Clear
    End If
    
    '// 値の初期設定
    pathdir = ActiveWorkbook.Path   '//  読み込み書き出しパス
    gyo = 5                         '// 書き出し開始行
    
    '// 主処理:作業一覧の書き出し
    j = 0
    For i = 1 To Sheets.Count
            '//=========================//
            '// 画面一覧の場合          //
            '//=========================//
        If (Sheets(i).Range("B1") = "画面一覧") Then
                
                '// アプリ用ソース書き出し
            Sheets("作業一覧").Cells(gyo, 1) = pathdir & "¥app_c.txt"
            Sheets("作業一覧").Cells(gyo, 2) = Sheets(i).Name
            Sheets("作業一覧").Cells(gyo, 3) = pathdir & "¥" & Sheets(i).Range("B2") & ".c"
            gyo = gyo + 1
            
                '// アプリ用ヘッダー書き出し
            Sheets("作業一覧").Cells(gyo, 1) = pathdir & "¥app_h.txt"
            Sheets("作業一覧").Cells(gyo, 2) = Sheets(i).Name
            Sheets("作業一覧").Cells(gyo, 3) = pathdir & "¥" & Sheets(i).Range("B2") & ".h"
            gyo = gyo + 1
            
                '// バージョン用書き出し
            Sheets("作業一覧").Cells(gyo, 1) = pathdir & "¥version_h.txt"
            Sheets("作業一覧").Cells(gyo, 2) = Sheets(i).Name
            Sheets("作業一覧").Cells(gyo, 3) = pathdir & "¥version.h"
            gyo = gyo + 1
        End If
            
            '//=========================//
            '// 各画面定義の場合        //
            '//=========================//
        If (Sheets(i).Range("B1") = "画面定義") Then
                
                '// 新規画面用にシート名保存
            ReDim Preserve shname(j + 1)
            shname(j) = Sheets(i).Name
            sagyoShname = "@" & Sheets(i).Name
            j = j + 1
            
                '// 画面用ソース書き出し
            If (Sheets(i).Cells(gamen_teigi_str_gyo, 1) = "") Then
                Sheets("作業一覧").Cells(gyo, 1) = pathdir & "¥gamen_c.txt"
            Else
                Sheets("作業一覧").Cells(gyo, 1) = pathdir & "¥gamen_b_c.txt"
            End If
            Sheets("作業一覧").Cells(gyo, 2) = sagyoShname
            Sheets("作業一覧").Cells(gyo, 3) = pathdir & "¥" & Sheets(i).Range("D2") & ".c"
            gyo = gyo + 1
            
                '// 画面用ヘッダ書き出し
            If (Sheets(i).Cells(gamen_teigi_str_gyo, 1) = "") Then
                Sheets("作業一覧").Cells(gyo, 1) = pathdir & "¥gamen_h.txt"
            Else
                Sheets("作業一覧").Cells(gyo, 1) = pathdir & "¥gamen_b_h.txt"
            End If
            Sheets("作業一覧").Cells(gyo, 2) = sagyoShname
            Sheets("作業一覧").Cells(gyo, 3) = pathdir & "¥" & Sheets(i).Range("D2") & ".h"
            gyo = gyo + 1
        End If
    
    Next
    
    '// 主処理2:作業用画面定義の作成
    For i = 0 To j - 1
        Set sagyoSh = Sheets.Add()
        sagyoShname = "@" & shname(i)
        sagyoSh.Name = sagyoShname
        Call makeSagyoSheet(sagyoShname, shname(i))
        Set sagyoSh = Nothing
    Next
    
End Sub

'//=========================//
'//     後処理              //
'//=========================//
Sub freeAppData()
    Dim sagyoShname As String      '   作業用シート名
    Dim sagyoSh As Worksheet       '   作業用シート
    Dim shname() As String
    Dim i As Integer
    Dim j As Integer
    
    '// 主処理1:作業用画面定義の取得
    j = 0
    For i = 1 To Sheets.Count
        If (Left(Sheets(i).Name, 1) = "@") Then
                '// 新規画面用にシート名保存
            ReDim Preserve shname(j + 1)
            shname(j) = Sheets(i).Name
            j = j + 1
        End If
    Next
    
    '// 主処理2:作業用画面定義の削除
    Application.DisplayAlerts = False
    For i = 0 To j - 1
        Sheets(shname(i)).Delete
    Next
    Application.DisplayAlerts = True

End Sub


'//=========================//
'//  作業用シート書き出し   //
'//=========================//
Sub makeSagyoSheet(shname As String, motoname As String)
    Dim sakiSheet As Worksheet
    Dim motoSheet As Worksheet
    Dim lastGyo As Integer
    Dim i As Integer
    Dim j As Integer
    Dim sts As Integer
    Dim strMenuGyo As Integer
    
    
    '// 元、先シートと最後の行を求める
    Set sakiSheet = Sheets(shname)
    Set motoSheet = Sheets(motoname)
    lastGyo = motoSheet.Range("A65536").End(xlUp).Row
    
    sts = 0         '   データまで
    For i = 1 To lastGyo
        Select Case sts
        Case 0:         '   データまで
            If (motoSheet.Cells(i, 1) = "メニュー一覧") Then   '   メニュー開始
                sts = 1     '   メニュー
                strMenuGyo = i
                For j = 1 To 4
                    sakiSheet.Cells(i - strMenuGyo + 3, j + 14) = motoSheet.Cells(i, j)
                Next
            Else
                For j = 1 To 14
                    sakiSheet.Cells(i, j) = motoSheet.Cells(i, j)
                Next
            End If
        Case 1:         '   メニューまで
            For j = 1 To 4
                sakiSheet.Cells(i - strMenuGyo + 3, j + 14) = motoSheet.Cells(i, j)
            Next
        End Select
    Next

    '//あとしまつ
    Set sakiSheet = Nothing
    Set motoSheet = Nothing
    
End Sub

(上記< > ¥ は本当は半角です)




以上です。
次回のこのシリーズは、イベントの追加の話になります。


この記事についてブログを書く
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする
« 富士通が一般公開しているシ... | トップ | 富士通、東証が09年の稼動を... »
最新の画像もっと見る

ケータイ」カテゴリの最新記事