機能と数式 | VBA | セミナー | オンラインソフト | お問い合わせ | その他
Top > Excel

VBA実力判定用問題の解答例



「VBAエキスパート スタンダード向けセミナー」を受講するための、VBA実力判定問題の解答例
ちなみに、ベーシックを受講された方なら、この2問くらい楽勝で作成できます。

問題1の解答例
Sub Sample1()
    Dim i As Long, Result As Long
    For i = 2 To 21
        If Format(Cells(i, 1).Value, "aaaa") = "日曜日" Then
            Result = Result + Cells(i, 3).Value
        End If
    Next i
    Range("F2").Value = Result
End Sub

Sub Sample1()

プロシージャ名は何でもかまいません。日本語を使ってもいいです。プロシージャは、標準モジュールに作成します。Sheet1モジュールではいけません。なぜ、標準モジュールに書かなければいけないかは、ベーシックで学習します。

Dim i As Long, Result As Long

変数は必ず宣言します。なぜ変数を宣言しなければいけないのか。変数を宣言しないで使うとどうなるかは、ベーシックで学習します。For Nextで使うカウンタ変数の名前は、特別な事情がない限り「i」を使います。なぜ「i」を使うべきなのかは、ベーシックで学習します。

「Dim i , Result As Long」という宣言では、変数「i」はバリアント型になります。
変数の型がわからないときは、型宣言(As ○○)を省略して、バリアント型変数を使ってもいいです。なぜバリアント型を使うのがいいのか。バリアント型に関する「速度が遅い」などのデメリットが、現在では適切ではないことなどは、ベーシックで学習します。

For i = 2 To 21

本問題では、ワークシート上のデータが"可変かどうか"が不明です。2行目から21行目と"決めうち"してもかまいません。データの最終行が可変だったときのやり方は、ベーシックで学習します。

If Format(Cells(i, 1).Value, "aaaa") = "日曜日" Then

日付(シリアル値)の曜日を判定するには、Format関数を使います。以前は、Weekday関数が使われていましたが、最近の主流はFormat関数です。なぜFormat関数を使うべきなのかは、ベーシックで学習します。

Result = Result + Cells(i, 3).Value

いわゆる「A = A + 1」という考え方です。プログラムを組む上で、もっとも重要な考え方のひとつですが、多くのビギナーが、こうした考え方を理解できず、また、理解していてもプログラミングできません。そのへんも、ベーシックで重点的に学習します。

ここは、Cellsを使います。Rangeではいけません。なぜRangeではいけないのか。そもそも、RangeとCellsは、どう使い分けるべきなのかは、ベーシックで学習します。

Valueプロパティは省略してもかまいません。Rangeオブジェクトでは、プロパティを何も指定しないで省略すると、Valueプロパティを指定したものとみなします。では、Valueプロパティは「省略した方がいいのか」それとも「記述した方がいいのか」については、その根拠とともに、ベーシックで学習します。

このCells(i, 3)は、ワークシートを指定していません。ワークシートを指定しないとどうなるのか、などセルを操作する上でもっとも重要なポイントは、ベーシックで学習します。

ここでは、合計の数値を格納するために変数Resultを使いましたが「Range("F2").Value = Range("F2").Value + Cells(i, 3).Value」と、結果を代入するセルに直接加算してもかまいません。

Range("F2").Value = Result

計算結果をセルに代入しています。本問題では特に指定をしていませんので、セルF2に対する書式設定は、なくてもかまいません。もし書式設定するのなら、

With Range("F2")
  .Value = Result
  .NumberFormat = "#,##0"
End With

あるいは

With Range("F2")
  .Value = Result
  .NumberFormat = Range("C2").NumberFormat
End With

なんて手もあります。いずれにしても、その場合はWithステートメントを使うと可読性とメンテナンス性が高まります。
Withステートメントについては、ベーシックで学習します。
また、結果のセルに3桁の桁区切りを指定するのなら「Range("F2").Value = Format(Result, "#,##0")」とする方法もあります。Excelでは「1,234」のようにカンマを含んだデータをセルに入力すると、そのセルには自動的に通貨の表示形式が設定されます。


エラー対策をするのなら、たとえば、A列のデータが日付形式かどうかを確認したり。

Sub Sample1()
    Dim i As Long, Result As Long
    For i = 2 To 21
        If IsDate(Cells(i, 1).Value) And Format(Cells(i, 1).Value, "aaaa") = "日曜日" Then
            Result = Result + Cells(i, 3).Value
        End If
    Next i
    Range("F2").Value = Result
End Sub

C列のデータが数値形式かどうかの確認なども考えられます。

Sub Sample1()
    Dim i As Long, Result As Long
    For i = 2 To 21
        If Format(Cells(i, 1).Value, "aaaa") = "日曜日" Then
            If IsNumeric(Cells(i, 3).Value) Then
                Result = Result + Cells(i, 3).Value
            End If
        End If
    Next i
    Range("F2").Value = Result
End Sub

ワークシート上をFor Nextでループして、Ifで条件に該当するセルだけを操作する…というのが、Excelマクロの基本形です。もちろん、それだけでは対応できないケースもあるでしょう。そんなときは、スタンダードで学習するFor EachやDo LoopあるいはSelect Caseなどを使ったり、複数のデータを同時に集計するために配列やユーザー定義型を使ったりと、さまざまに発展できます。いずれにしても、For NextとIfを完璧に使いこなすのがVBAの基礎です。



問題2の解答例
Sub Sample2()
    Dim i As Long
    For i = 2 To 21
        If Cells(i, 2).Value = "田中" Then
            Range(Cells(i, 1), Cells(i, 3)).Font.ColorIndex = 3
        End If
    Next i
End Sub

Range(Cells(i, 1), Cells(i, 3)).Interior.ColorIndex = 3

ここが、この問題のポイントです。B列を上から順番に調べて、もしB列の値が"田中"だったら、その行の「A列からC列」の文字色を赤色にします。たとえば、見つかったのが4行目だったら「セル範囲A1:C4」が対象になります。

このように、リスト(表)をレコード(行)単位で操作するときは、Rangeの2番目の書式「Range(左上セル, 右下セル)」を使います。もし、このやり方を知らないときは、次のように3つのセルを操作すればいいでしょう。Rangeの2番目の書式については、ベーシックで学習します。

Sub Sample2()
    Dim i As Long
    For i = 2 To 21
        If Cells(i, 2).Value = "田中" Then
            Cells(i, 1).Font.ColorIndex = 3
            Cells(i, 2).Font.ColorIndex = 3
            Cells(i, 3).Font.ColorIndex = 3
        End If
    Next i
End Sub

もっとも悪い考え方は、次のように、操作の対象となるセル範囲のアドレスを、文字列として結合するやり方です。

Sub Sample2()
    Dim i As Long
    For i = 2 To 21
        If Cells(i, 2).Value = "田中" Then
            Range("A" & i & ":C" & i).Font.ColorIndex = 3
        End If
    Next i
End Sub

これは、やってはいけません。実行すれば同じ結果になりますが、同じ結果になるからといって、どんな書き方をしてもいい訳ではありません。複数のやり方があったとき、ビジネスの現場で作成されるマクロでは、何を注意してコーディングしなければならないのか、などマクロ作成の根源的なポイントは、ベーシックで学習します。



上で解説したようなことは、すべてベーシックのセミナーでじっくり学習します。もし、上で解説したポイントを、すべて理解されているのでしたら、ベーシックを受講せずに、スタンダードだけ受講されても大丈夫です。
勘違いしないでください。ベーシックは 入門 ではなく、基礎 です。



このエントリーをはてなブックマークに追加