(11) プログラミングとは(VBA編)

 プログラミングというと、難しそうとか、自分には関係ないと思われるかも知れません。しかし、プログラミングは、AI等による変化に対応するのに役立つそうです。コンピュータが論理的に処理する仕組みを理解することで、主体的に課題解決や価値創造する論理的思考力を養えると言われています。

 私は、SEをしていた時にプログラミングを学んでシステム開発もしました。現在でも、身近に役立つプログラムを作っていますが、プログラミングは論理的な思考に役立つと感じています。

 今回は、プログラミングってどんなものかを、エクセルがあれば利用できるVBA(Visual Basic for Applications)を使って、VBAプログラムの基本的なパターンや、実用的なプログラムの例についてもお話ししたいと思います。

※プログラム等の文字が細かくて見にくい場合は、文字を拡大するかパソコン等からご覧ください。

プログラミングとは

はじめに

〇プログラミングとは、プログラミング言語(VBA等)を使ってプログラムを作成することです。

プログラムとは、コンピュータに何をどのように実行するかを指示する命令のリストで「コード」と呼びます。

〇EXCEL VBAは、エクセルに付いているものなので、今回は、VBAを使ってセル操作を自動化することを中心にお話ししたいと思います。

Excel VBAを使う準備

まず、VBAを使うための準備をします。

「開発」をエクセルのメニューに追加(最初に1回実施)

・エクセルのメニューから「ファイル」-「オプション」を選び、「リボンのユーザ設定」からメインタブに「開発」を追加します。

・「開発」のチェックボックスに☑を付けます。

標準モジュールを追加(ブック毎に実施)

・エクセルの「開発」メニューから「コードの表示」をクリックすます。

・画面左側に階層構造が出てくるので、そこで右クリックして表示されるメニューから、「挿入」-「標準モジュール」を選択します。

・標準モジュールが追加されたら、右クリックして、「コードの表示」を行います。

VBAプログラムの基本的なパターン

※文字が細かい場合は、拡大するかパソコン等からご覧ください。

<共通事項>

・プログラムは、基本的にコードを上から下へ、順に命令を実行されます。プログラムは「Sub プログラム名()」で始まり「End Sub」で終わる。関数は「Function 関数名(引数)」で始まり「End Function」で終わる。

どんなプログラムでも、処理の流れは、順に実行(以下の①)、繰り返し(②)、条件分岐(③)の3パターンです。

Worksheets("シート名").Cells(行,列)でセルを指定できます。

VBAでは「=」は右辺を左辺に代入する意味です。(ただしIF文中は等しいの意味)

・VBAでは変数名は自由に決められるので、分かり易い名前にします。

①5つの命令文を順番に処理してセルに「〇」を入力しています。

Do-Loopの範囲の命令を変数の値を変えて繰り返し、①と同じ処理を効率的に行っています。

Ifでセルの値を判定して、「〇」なら「 」、以外なら「〇」を入力するという処理をしています。

④では、Do-Loopを2重にして、行と列の変数の値を変えながら、表形式のセルの値を置き換えています。条件分岐も行っています。

⑤VBA用の関数Lenで文字列の長さを求め、ワークシート関数Sumで合計を計算し、Msgbox関数で結果をポップアップ表示しています。関数を使うと効率的にプログラムを作成できます。

⑥身長と体重を引数として与え、BMIを求める関数を自分で作成しています。関数では関数名「bmi」に結果をセットします。ワークシート関数と同様、「=bmi(〇,〇)」で使います。

⑦プログラム(「マクロ」とも呼ぶ)をボタンから実行しています。

ここで示したようにEXCELのブックとVBAに入力して使っていただけますので、是非、お試しください。以下、①~⑥のコードの例ですので、コピー等してお使いください。

※本ページのはじめの方の「Excel VBAを使う準備」で、「コードを入力する画面」の出し方を説明していますので、以下のコードを標準モジュールに貼り付けてください。

ーーー コピー用:説明したコードと同じ ーーー

Sub sample1()

   Worksheets("sheet2").Cells(5, 2) = "〇"
   Worksheets("sheet2").Cells(5, 3) = "〇"
   Worksheets("sheet2").Cells(5, 4) = "〇"
   Worksheets("sheet2").Cells(5, 5) = "〇"
   Worksheets("sheet2").Cells(5, 6) = "〇"

End Sub
Sub sample2()

  retu = 2

  Do
    Worksheets("sheet2").Cells(11, retu) = "〇"
    retu = retu + 1
  Loop Until retu > 6
   
End Sub
Sub sample3()

  If Worksheets("sheet2").Cells(17, 2) = "〇" Then
     Worksheets("sheet2").Cells(17, 2) = " "
  Else
     Worksheets("sheet2").Cells(17, 2) = "〇"
  End If
   
End Sub
Sub sample4()

  gyo = 23
  retu = 2

  Do
  
    Do
    
      If Worksheets("sheet2").Cells(gyo, retu) = "〇" Then
         Worksheets("sheet2").Cells(gyo, retu) = " "
      Else
         Worksheets("sheet2").Cells(gyo, retu) = "〇"
      End If
         
      retu = retu + 1
    
    Loop Until retu > 6
    
    retu = 2
    gyo = gyo + 1
        
  Loop Until gyo > 27
   
End Sub
Sub sample5()

  nagasa = Len(Worksheets("sheet2").Cells(36, 2))
  MsgBox (nagasa)

  Total = Application.WorksheetFunction.Sum(Range(Cells(40, 2), Cells(40, 6)))
  MsgBox ("合計: " & Total)


End Sub
Function bmi(height, weight)

  result = weight / ((height / 100) ^ 2)
  bmi = Application.WorksheetFunction.Round(result, 1)

End Function

実用的なプログラムの例

 それでは、これまでの基本パターンの応用として実用的なプログラムを見てみましょう。VBAを使い出して間もないころ、ローンのシミュレーションをしたのを思い出したので、今回は、それを題材にしてみました。みなさんもやってみてください。

プログラムを利用する画面

 まず、EXCELで次のような利用画面を作ってください。

借入額、支払年数、年利(固定金利)、元利均等/元金均等を入力し、「試算実行」をクリックすると、自動的に、各年の支払額と元金支払額、利息支払額の内訳が表示されます。

※1~6行目までだけを入力してください。結果は7行目から自動的に表示されます。

・各年の表示の最後には、総支払額も表示されます。

・先ほどお話ししたVBAプログラムの基本的なパターンを組み合わせて作成しています。

・今回は、金融関係のシミュレーションなので、エクセルの関数(Pmt、IPmt、PPmt)も使用しています。

プログラム(コード)の例

 次に、VBAのコードを入力します。先ほどと同様、標準モジュールに入力してください。

・プログラムは、手作業ならどんな風に行うかを考えて、命令を順に書いていきます。

・命令は、先ほどの基本パターンから、似たものを貼り付け、それを修正します。

・通常のプログラムの流れは、①変数の初期設定等、②メインとなる処理(今回は各年の支払金額を求めながら、総支払額も計算する処理)、③終了処理(今回は総支払額の表示等)

・メイン処理の中では、同じ処理は、繰り返し処理を使って、変数の値を変えながら効率的に回します。また、条件によって処理が異なる場合は、条件分岐を行います。

・プログラムには、コメント(緑色部分)を入れていますので、読み解いてみてください。

難しく感じるかも知れませんが、よく見ると基本パターンを組み合わせているだけです。

ここで示したようにEXCELのブックとVBAに入力すれば使っていただけますので、是非、お試しください。以下、コードの例ですので、コピー等してお使いください。

ーーー コピー用:説明したコードと同じ ーーー

Sub loan_simulation()
    '今回のコードは初心者向けに「変数宣言なし」で書いています。最初にDimで変数の型を指定した方が、正確に計算できます。
    '支払金額等は参考値であり利用は自己責任でお願いします。実際に借入を行う場合は、金融機関に正確な支払額等を確認してください。

    'ローンのシミュレーション条件をフォームから入力
    kariire = Worksheets("sheet3").Cells(4, 1)     ' 借入額
    nensu = Worksheets("sheet3").Cells(4, 2)       ' 年数
    nenri = Worksheets("sheet3").Cells(4, 3)       ' 年利
    housiki = Worksheets("sheet3").Cells(4, 4)     ' 元利均等または元金均等

    '変数の初期値の設定
    geturi = nenri / 12   '月当たりの金利
    tukisu = nensu * 12   '総支払月数
    zangaku = kariire     'ローン残額 初期値=借入額

    y = 7                 '7行目から結果表示
    nen_siharai_kei = 0   '年間支払額の合計
    total_siharai_kei = 0 'トータルの支払額
    tuki_cnt = 1          '処理月数のカウンター

    '総支払月数分繰り返し
    Do

        If housiki = "元利均等" Then       '元利均等の場合 EXCELのワークシート関数を利用
            tuki_siharai = -WorksheetFunction.Pmt(geturi, tukisu, kariire)    '毎月返済額 Pmt(月金利,総月数,借入額)
            risoku = -WorksheetFunction.IPmt(geturi, tuki_cnt, tukisu, kariire) '利息部分 IPmt(月金利,支払月,総月数,借入額)
            gankin = -WorksheetFunction.PPmt(geturi, tuki_cnt, tukisu, kariire) '元金部分 PPmt(月金利,支払月,総月数,借入額)
            '※注 Excelの金融関数(PMTなど)は「支払うお金=マイナス」で返すものです。
                  '今回は符号を反転してプラスで表示しています。

        ElseIf housiki = "元金均等" Then   '元金均等の場合 関数がないため式で計算
            gankin = kariire / tukisu      '元金部分=借入額/月数
            risoku = zangaku * geturi      '利息部分=残額×金利
            tuki_siharai = gankin + risoku '毎月返済額=元金部分+利息部分
        
        End If

        '年間の支払額、年間元金分、利息分の合計
        nen_siharai_kei = nen_siharai_kei + tuki_siharai
        nen_gankin_kei = nen_gankin_kei + gankin
        nen_risoku_kei = nen_risoku_kei + risoku
                       
        'トータルの支払額の合計
        total_siharai_kei = total_siharai_kei + tuki_siharai
                
        '年末(12で割り切れる月の場合)
        If tuki_cnt Mod 12 = 0 Then
            Cells(y, 1).Value = y - 6 & "年目"                    '何年目かの表示
            Cells(y, 2).Value = Format(nen_siharai_kei, "#,##0")  '年間支払額(金額表示は3桁ずつカンマ区切り)
            Cells(y, 3).Value = Format(nen_gankin_kei, "#,##0")   '年間元金部分
            Cells(y, 4).Value = Format(nen_risoku_kei, "#,##0")   '年間利息部分
                        
            y = y + 1
            
            '年間支払額、年間元金分、利息分のクリア
            nen_siharai_kei = 0
            nen_gankin_kei = 0
            nen_risoku_kei = 0
        
        End If

        '残額の計算
        zangaku = zangaku - gankin
        '支払月数のカウント
        tuki_cnt = tuki_cnt + 1

    '支払月数が総月数になるまで繰り返し
    Loop Until tuki_cnt > tukisu

    '総支払額、総支払金額を最後に表示
    Cells(y + 1, 1).Value = "総支払額"
    Cells(y + 1, 2).Value = Format(total_siharai_kei, "#,##0")

End Sub

補足説明

 最後に、プログラミングに関して、少し補足説明をさせていただきます。

作業の途中で、適宜、ファイルの保存を行ってください。「ファイル」メニューから「上書き保存」等で行えます。

デバッグの機能使うと、実際にプログラムを少しずつ実行し、流れや変数の値を確認できます。

・エクセルのメニューから「デバッグ」を選択します。

・「ステップイン」は1行ずつ、「カーソル行の前まで実行」は複数行をまとめて、それぞれ実行できます。

・黄色印で実行中の場所を示しています。

・変数にマウスを合わせると、変数の値も表示されます。

プログラムが上手く動かない時は、デバッグを使うと原因を突き止めることができます。

〇上のプログラムには「’(クォーテーション)」の後に、コメントで説明を加えています。この部分は無くてもプログラムは動きますが、それぞれの命令で何をしているのかを、作成者以外の方がプログラムを見た時に、分かり易くしています。

〇VBAで、命令の書き方等が分からない時は、Googleや生成AI等で調べられます。例 「EXCEL VBA メッセージ 出し方」(メッセージボックスの使い方を調べる場合)

〇本記事に掲載しているサンプルコードの動作、結果については保証はできませんので、自分でしっかりとテスト、検証してご利用ください。