プログラム構造

VBAプログラムは、プロシージャ、モジュール、プロジェクトという構造を持ちます。
プロシージャ(手続き)は複数の処理を一つ単位機能としてまとめたもので、他のプログラム言語で言うルーチンや関数と呼ばれるものと同じ性格のものです。
プログラミングでは必要なExcelオブジェクトの属性を決定したり、メソッド(動き)を定義したり、VBA関数を利用してプロシージャを作り、プロシージャとプロシージャを連携させて、目的の処理を実現します。
これを構造面から見ると、いくつかのプロシージャを集めた物がモジュールで、いくつかのモジュールを集めて一つのExcelファイルの中に保存したものがプロジェクトです。

入力データと出力データ

VBAプログラムのひとつの特徴はExcelのブック、シートからデータを読み出し、処理した結果のデータを ブック、シートに保存できるという事です。
ここで、ブックとシートについておさらいすると、Excelを開いて画面に現れる複数のタブを持った表計算用の帳票がブックです。ブックの名前はExcelウインドウの一番上の行の中央に表示されているXXXX.xlsxやXXXX.xlsmなどの名前とファイル属性名の組合せです。
ブックの中の各タブがシートで、それぞれのシート名が各タブに表示されています。
注意しなければいけないのは、プログラムの中では複数のシート、複数のブックを利用する事が出来ますが、一度に扱う事のできるのは一つのブック中の一つのシートです。それがアクティブブックのアクティブシートです。
ブックをディスク上に保管するとファイルになります。ファイル名=ブック名ですが、ファイル名だけではディスクのどの場所にそのファイルが保管されているかがわからないので、ファイル名を扱うときには、同時にそのファイルの置き場所であるパス名も関連して扱います。パス名とファイル名を連結したものがフルパス名です。

プロシージャの構造

VBAのプロシージャは、
  1. プログラム宣言で始まり
  2. プログラムの中で使用する変数、定数の宣言
  3. 必要な値を変数に代入
  4. その変数を使って処理を行い
  5. 処理した結果を印刷したり、新しいExcelファイルとして保存する
といった処理の流れを持ちます。
一般的にはプログラムは保守性を考えて、分かりやすいように、何百行に渡る長いプログラムを書くのではなく、処理をいくつかのサブプログラムに分け、メインプログラムがそれらのサブプログラムを呼び出すように作ることが推奨されます。
しかしVBAプログラムの場合、Excelの持っているいろいろな機能を呼び出して処理を実現するので、それ自体がメインプログラムの位置付けになるので、むやみに処理を分けるとかえって処理の流れが分かりにくくなってしまいます。
また、いくつかのブック、シートを扱うプログラムではプログラムを分けすぎると、今どのブック、シートがアクティブなのか分からなくなり、容易にデータを壊してしまうので、基本的には初めから終わりまで一つのプログラムとして書き下すほうが良いでしょう。

部材、部品によるプログラミング

以上が基本事項です。
プログラミング技術を極めるためにはまだまだ知らなければいけないことがたくさんありますが、今はインターネットのおかげでそれらの情報をいくらでも手に入れることが出来ます。
一方、何事も最良の勉強法は実際にやってみることです。そこで、これ以上の技術説明は以下のサイトを必要に応じて参照していただくとして、次は今までの知識だけでプログラムする方法を考えましょう。

<参考サイト>

Visual Basicの基本テクニック
http://www.panrolling.com/etc/users/taniguchi/99/index.html
Excel VBA入門
http://www.eurus.dti.ne.jp/yoneyama/Excel/vba/
Excel VBA 入門講座へようこそ
http://excelvba.pc-users.net/
Office TANAKA / VBA
http://officetanaka.net/excel/
Excelでお仕事 / VBA基本
http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_010.html
Excel VBA.net
http://www.excel-vba.net/
VBAプログラムの特徴はExcelの機能が使えることでした。
そこで、Excelが提供するオブジェクトやメソッド、関数を目的を実現するための部材や部品と捉え、それらを上手く組み合わせる工夫をすれば、部材や部品の中身を詳しく知らなくてもプログラムを作ることができるでしょう。
これが部材、部品によるプログラミングです。
では得意先売上と原価を営業担当者別に集計する処理を例にこの手法を紹介しましょう。
入力データは下記のExcelシートです。

プログラミングは次のように進めます

  1. 必要な変数を決めて、大まかな処理の流れをコメント文と制御文で記述します。
    Option Explicit
    
    Sub 売上集計()
    
    Dim RowMax As Long
    Dim I As Long
    Dim 得意先コード As String
    Dim 担当者コード As Integer
    Dim 読出行 As Long
    Dim 書出行 As Long
    Dim 金額 As Double
    
    '最大行検出
    
    For I = 2 To RowMax
        得意先コード = Cells(I, 4).Value
        担当者コード = Cells(I, 2).Value
        If 得意先コード <> Cells(I + 1, 4).Value Then
    '得意先コードが違う --> 集計結果書出し
    
    '書出行番号カウントアップ
            書出行 = 書出行 + 1
    '金額リセット
    
        ElseIf 担当者コード <> Cells(I + 1, 2).Value Then
    '担当者コードが違う --> 集計結果書出し
    
    '書出行番号カウントアップ
    
    '金額リセット
            
        Else
    '得意先も担当者も同じ --> 金額カウントアップ
            
        End If
        
    '読出行番号カウントアップ
    
    Next I
    
    End Sub
  2. 処理の流れに沿って処理を細分化し、式やExcelの部材、部品で置き換えます。また、この時点で繰り返し行われる処理を別のプロシージャとして切り出す検討も行います。
    Option Explicit
    
    Sub 売上集計()
    
    Dim RowMax As Long
    Dim 得意先コード As String
    Dim 担当者コード As Integer
    Dim 読出行 As Long
    Dim 書出行 As Long
    Dim 金額 As Double
    
    '最大行検出
    RowMax = Cells(Rows.Count, 1).End(xlUp).Row
    
    書出行 = 2
    
    For 読出行 = 2 To RowMax
        得意先コード = Cells(読出行, 4).Value
        担当者コード = Cells(読出行, 2).Value
        If 得意先コード <> Cells(読出行 + 1, 4).Value Then
    '得意先コードが違う --> 集計結果書出し
            Call 集計結果書出し(書出行, 金額)
    '書出行番号カウントアップ
            書出行 = 書出行 + 1
    '金額リセット
            金額 = 0
    
        ElseIf 担当者コード <> Cells(読出行 + 1, 2).Value Then
    '担当者コードが違う --> 集計結果書出し
            Call 集計結果書出し(書出行, 金額)
    '書出行番号カウントアップ
            書出行 = 書出行 + 1
    '金額リセット
            金額 = 0
            
        Else
    '得意先も担当者も同じ --> 金額カウントアップ
            金額 = 金額 + Cells(読出行, 8).Value
            
        End If
        
    '読出行番号カウントアップ
    Next 読出行
    
    End Sub
    
    Sub 集計結果書出し(I, 金額)
    
    
    End Sub
  3. プログラムを実行テストしながら変数のリセットやシートデータを事前にソーティングするなど、当初は気づかなかったBug対策を行います。
    Option Explicit
    Public 読出行 As Long
    Public 書出行 As Long
    Public 金額 As Double
    Sub 売上集計()
    
    Dim RowMax As Long
    Dim 得意先コード As String
    Dim 担当者コード As Integer
    
    '最大行検出
    RowMax = Cells(Rows.Count, 1).End(xlUp).Row
    
    'グループ、担当者コード、得意先コード順にソーティング
        ActiveWorkbook.Worksheets(出力タブ).Sort.SortFields.Clear
        ActiveWorkbook.Worksheets(出力タブ).Sort.SortFields.Add Key:=Range("A2:A" & RowMax) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        ActiveWorkbook.Worksheets(出力タブ).Sort.SortFields.Add Key:=Range("B2:B" & RowMax) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        ActiveWorkbook.Worksheets(出力タブ).Sort.SortFields.Add Key:=Range("D2:D" & RowMax) _
            , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
        With ActiveWorkbook.Worksheets(出力タブ).Sort
            .SetRange Range("A1:J" & RowMax)
            .Header = xlYes
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
    
    書出行 = 2
    金額 = 0
    
    For 読出行 = 2 To RowMax
        得意先コード = Cells(読出行, 4).Value
        担当者コード = Cells(読出行, 2).Value
        If 得意先コード <> Cells(読出行 + 1, 4).Value Then
    '得意先コードが違う --> 集計結果書出し
            Call 集計結果書出し
    
        ElseIf 担当者コード <> Cells(読出行 + 1, 2).Value Then
    '担当者コードが違う --> 集計結果書出し
            Call 集計結果書出し
            
        Else
    '得意先も担当者も同じ --> 金額カウントアップ
            金額 = 金額 + Cells(読出行, 8).Value
            
        End If
        
    '読出行番号カウントアップ
    Next 読出行
    
    
    '不要行削除
    Rows(CInt(書出行) & ":" & RowMax).Select
    Selection.Delete Shift:=xlUp
    
    End Sub
    
    Sub 集計結果書出し()
    
    Dim I As Integer
    
    金額 = 金額 + Cells(読出行, 8).Value
    
    For I = 1 To 10
        Cells(書出行, I).Value = Cells(読出行, I).Value
    Next I
    Cells(書出行, 8).Value = 金額
    
    '書出行番号カウントアップ
    書出行 = 書出行 + 1
    '金額リセット
    金額 = 0
    
    End Sub
    
  4. テストが終了すれば、プログラムは完成です。
次ページより部材、部品リストを紹介しますので、プログラム開発の手引きとして活用してください。
1 2 3

 

このサイトは個人生活を健やかに、愉しく、 企業活動を闊達にして、 持続可能な社会作りを目指します
Copyright © しなやか暮し研究所 2012 All Rights Reserved.