ExcelマクロVBA技術解説 | プログラミングの基本〜ロジックの組み立て | Excelマクロの問題点と解決策、エクセルVBAの技術的解説



最終更新日:2017-09-18

プログラミングの基本〜ロジックの組み立て


プログラミングの基本というと、プログラミング言語の基本文法についての解説と思われるかもしれませんが、
ここでは、プログラミングする上で最も大切な考え方、ロジックの組み立て方について解説します、
本来は言語は問わないのですが、VBAのサイトですのでVBAを例に解説します。

何かをしようとしたとき、どのような手順になるか…
これが重要です。

「何かをする」何でも良いです、例えばDSでゲームをするとしましょう。
この時の行動手順を書くと、

・DSを取り出す(しまってあるところから持ってくる)
・遊ぶゲームのカードを入れる
・電源を入れる
・ゲームで遊ぶ(ここは細かいことは省略します)
・電源を切る
・ゲームのカードを抜く
・DSをかたずける

細かい事は抜きにして、大抵はこのような感じになります。
これをもっと大まかに簡潔に書くと、

・前準備
・目的の行動
・後片づけ


この3ステップになります。
プログラミングにおいても、DSで遊ぶことと同様に、この手順が必要になります。
これは、あらゆることにおいて共通していることです。
DSで遊ぶとか、プログラミングだけの話ではなく、あらゆる事柄において存在する手順です。
この3ステップをプログラミング用語として書き直すと、

・前処理
・主処理
・後処理


となります。
このように書くと、最近の言語学習者は、古い昔のパッチ処理の話かと思われる人もいるかもしれません。
しかし、けっしてそうではなく、人の行動・考えがそのようにできているのです。
小学校時代から、
準備→目的の行動→後片付け
この、準備と後片付けは、いやというほど教えられてきたはずです。
まさしく、すべての事が、この3ステップに分解できるのです。
そこで、
プログラミングする時のロジックの組み立てにおいて、この3ステップを強く意識すると良いのです。
これは、細分化していっても、その細分化された中に発生します。
主処理を分解すると、
・主処理の中の前処理
・主処理の中の主処理
・主処理の中の後処理

このように分解できるのです。
つまり、
・前処理
・主処理
 ・主処理の中の前処理
 ・主処理の中の主処理
 ・主処理の中の後処理
・後処理

もちろん、分解できない程度の小さなものは別ですが。
逆に、規模が大きくなれば、前処理の中でさえ、3ステップに分解できることもあります。
ただし、処理内容によっては、前処理または後処理のどちらか、または両方が存在しない場合もあることは承知しておいてください。。

ブログラミング言語を問わずに、この3ステップの役割を書くと、

・前処理

入力チェック
出力領域の初期化
主処理で必要となる領域の生成と初期化

・主処理

必要な処理の記述

・後処理

結果の出力
領域の解放


大体こんな感じになります。
言語によって、領域の生成・初期化・解放の部分はかなり違いが出てくることにはなりますが、記述の問題であり考え方としては共通です。

では、具体的にExcelマクロVBAにおいて、どのようになるかを見てみましょう。
ごく簡単な例で、3ステップを見てみましょう。

以下の表において昨年対比を計算するマクロVBAになります。
C列はの%表示は事前に設定してあるとします。



少しだけ丁寧に書いてみました。
多少の書き方の違いはあるにしても、大体はこんな感じになります。

Sub sample()
  Dim i As Long
  Dim ws As Worksheet
  Application.ScreenUpdating = False
  Set ws = ActiveSheet
  
  With ws
    For i = 2 To i.Cells(.Rows.Count, 1).End(xlUp).Row
      .Cells(i, 3) = .Cells(i, 1) / .Cells(i, 2)
    Next
  End With
  
  Application.ScreenUpdating = True
  MsgBox "完了"
End Sub


これなら説明も必要ないとは思いますが、
・前処理
・主処理
・後処理

この3ステップが明確に表れています。

Sub sample()

前処理
  Dim i As Long
  Dim ws As Worksheet
  Application.ScreenUpdating = False
  Set ws = ActiveSheet

主処理
  With ws
    For i = 2 To i.Cells(.Rows.Count, 1).End(xlUp).Row
      .Cells(i, 3) = .Cells(i, 1) / .Cells(i, 2)
    Next
  End With

後処理
  Application.ScreenUpdating = True
  MsgBox "完了"

End Sub


少し複雑な処理にしてみるとしましょう。
昨年対比が100%未満の場合、昨年対比を赤字にしてみましょう。

Sub sample2()
  Dim i As Long
  Dim ws As Worksheet
  Application.ScreenUpdating = False
  Set ws = ActiveSheet
  
  With ws
    For i = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row
      .Cells(i, 3).Font.ColorIndex = xxlAutomatic
      .Cells(i, 3) = .Cells(i, 1) / .Cells(i, 2)
      If .Cells(i, 3) < 1 Then
        .Cells(i, 3).Font.Color = vbRed
      End If
    Next
  End With
  
  Application.ScreenUpdating = True
  MsgBox "完了"
End Sub


これを3ステップに分解してみると、

Sub sample2()

前処理
  Dim i As Long
  Dim ws As Worksheet
  Application.ScreenUpdating = False
  Set ws = ActiveSheet

主処理
  With ws
    For i = 2 To i.Cells(.Rows.Count, 1).End(xlUp).Row

 主処理の中の前処理
      .Cells(i, 3).Font.ColorIndex = xlAutomatic

 主処理の中の主処理
      .Cells(i, 3) = .Cells(i, 1) / .Cells(i, 2)
      If .Cells(i, 3) < 1 Then
        .Cells(i, 3).Font.Color = vbRed
      End If

 主処理の中の後処理
・・・今回はありません

後処理
  Application.ScreenUpdating = True
  MsgBox "完了"

End Sub


処理内容がシンプルなので、各ステップが短いですが、3ステップの構造を確認してください。
ここで、3ステップを意識せずに書くと、
主処理の中が、

      .Cells(i, 3) = .Cells(i, 1) / .Cells(i, 2)
      If .Cells(i, 3) < 1 Then
        .Cells(i, 3).Font.Color = vbRed
      Else
        .Cells(i, 3).Font.ColorIndex = xlAutomatic
      End If

このようになることがあります。
もちろん、この程度の処理であれば、これでも問題はありません。
しかし、今後の拡張性を考慮した場合、保守性を考えれば前者の方がよりよいと言えます。
つまり、
初期化→主処理
このステップを明確にしておくのです。

ではさらに、プロシージャーの分割についても少しお話ししておきます。
各処理の中が複雑になる場合、プロシージャーの分割に進みます。
ただし、一応説明を加えておきますが、プロシージャーの分割は必ずしも複雑だから分割するということばかりではなく、
可読性・保守性・汎用性・可用性 これらのの向上が重要なことは申し上げておきます。
では、先のプロシージャーを分割すると、

Sub sample3()
  Dim i As Long
  Dim ws As Worksheet
  Application.ScreenUpdating = False
  Set ws = ActiveSheet
  
  With ws
    For i = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row
      Call sample3_main(ws, i)
    Next
  End With
  
  Application.ScreenUpdating = True
  MsgBox "完了"
End Sub

Sub sample3_main(ByVal ws As Worksheet, ByVal i As Long)
  With ws
    .Cells(i, 3).Font.ColorIndex = xlAutomatic
    .Cells(i, 3) = .Cells(i, 1) / .Cells(i, 2)
    If .Cells(i, 3) < 1 Then
      .Cells(i, 3).Font.Color = vbRed
    End If
  End With
End Sub

または、

 Sub sample4()
  Dim ws As Worksheet
  Application.ScreenUpdating = False
  Set ws = ActiveSheet
  
  Call sample4_main(ws)

  Application.ScreenUpdating = True
  MsgBox "完了"
End Sub

Sub sample4_main(ByVal ws As Worksheet)
  Dim i As Long
  With ws
    For i = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row
      .Cells(i, 3).Font.ColorIndex = xlAutomatic
      .Cells(i, 3) = .Cells(i, 1) / .Cells(i, 2)
      If .Cells(i, 3) < 1 Then
        .Cells(i, 3).Font.Color = vbRed
      End If
    Next
  End With
End Sub


このサンプルでは、どちらでが良いというほどの差異はありませんが、
一般的には、後者のsample4が書かれることの方が多いように感じます。
しかし、私は、どちらかというと前者のsample3を書くことの方が多い気がします。
理由としては、
主処理がさらに複雑になり、複数のプロシージャーに分割する必要が出てきたとき、
sample3の方が分割しやすく、全体の可読性が良いと思うからです。

    For i = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row
      Call sample3_main1(ws, i)
      Call sample3_main2(ws, i)
      Call sample3_main3(ws, i)
    Next

このように、機能追加しやすいのではないかと思います。
もちろん、全体としての処理内容に依存しますので、一概には言えませんが、そういう場合が多いということです。

最後に、再度記載しておきます。

常に意識すべきことは、処理を3ステップで考える
・前処理
・主処理
・後処理

そして、プロシージャーを分割するときは
・可読性
・保守性
・汎用性
・可用性


これらを常に意識してプログラムしていくことで、より良いプログラムが書けるようになりますし、コーディングの速度も上がっていくものです。




同じテーマ「ExcelマクロVBA技術解説」の記事

シートに数式を設定する時のセル参照の指定方法
標準モジュールとシートモジュールの違い
クリップボードを使わないセルのCopy
Rangeの使い方:最終行まで選択を例に
オブジェクト式について
Dir関数の制限について
画像サイズ(横x縦)の取得について

新着記事 ・・・新着記事一覧を見る

データクレンジングと名寄せ|ExcelマクロVBA技術解説(10月20日)
SUMIFの間違いによるパフォーマンスの低下について|エクセル関数超技(6月17日)
条件式のいろいろな書き方:TrueとFalseの判定とは|ExcelマクロVBA技術解説(6月15日)
空白セルを正しく判定する方法2|ExcelマクロVBA技術解説(5月6日)
フルパスをディレクトリ、ファイル名、拡張子に分ける|ExcelマクロVBA技術解説(4月15日)
テキストボックスの各種イベント|Excelユーザーフォーム入門(4月9日)
フォルダ(サブフォルダも全て)削除する、Optionでファイルのみ削除|ExcelマクロVBAサンプル集(4月4日)
最後の空白(や指定文字)以降の文字を取り出す|エクセル関数超技(3月26日)
先頭の数値、最後の数値を取り出す|エクセル関数超技(3月26日)
Excelファイルを開かずにシート名をチェック|ExcelマクロVBAサンプル集(3月23日)

アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|ExcelマクロVBA入門
2.RangeとCellsの使い方|ExcelマクロVBA入門
3.Range以外の指定方法(Cells,Rows,Columns)|ExcelマクロVBA入門
4.変数とデータ型(Dim)|ExcelマクロVBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|ExcelマクロVBA入門
6.定数と型宣言文字(Const)|ExcelマクロVBA入門
7.徹底解説(VLOOKUP,MATCH,INDEX,OFFSET)|エクセル関数超技
8.マクロって何?VBAって何?|ExcelマクロVBA入門
9.CSVの読み込み方法|ExcelマクロVBAサンプル集
10.ひらがな⇔カタカナの変換|エクセル基本操作



  • >
  • >
  • >
  • プログラミングの基本〜ロジックの組み立て

  • このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    なお、掲載のVBAコードは自己責任で使ってください。万一データ破損等の損害が発生しても責任は負いません。

    ↑ PAGE TOP