エクセルVBA100本ノック。5本目:セルの計算

この記事から得るもの

空白を含むデータがあるテーブルの処理をする際の、範囲設定方法が分かる。


1 今回のお題

画像のようにB2から始まる表があります。
B列×C列を計算した値をD列に入れ、通貨¥のカンマ編集で表示してください。
ただしB列またはC列が空欄の場合は空欄表示にしてください。
例.D2にはB3×C3の計算結果の値を「¥234,099」で表示、D5は空欄
※ブック・シートは任意

f:id:bimori466:20201104162550p:plain

excel-ubara.com

2 今回のお題の意図

単価、点数が両方とも空白の場合を考えること。

3 回答

私の最初の回答

Sub ノック5本目()

i = 2

Do
    i = i + 1
    
    '両方空白なら処理終了
    If Cells(i, 2) = "" And Cells(i, 3) = "" Then: Exit Do
    
    If Cells(i, 2) <> "" And Cells(i, 3) <> "" Then
        Cells(i, 4) = Cells(i, 2) * Cells(i, 3)
        Cells(i, 4).NumberFormatLocal = "\#,##0;\-#,##0"
    End If
Loop

End Sub

このコードのダメな点は、セルB3、C3がともに空白の場合1回目で処理が終了して、その後処理されない。
その後、考えた苦肉の策が以下のコードです。

苦肉の策のコード

Sub ノック5本目()

i = 2

Do
    i = i + 1
    
    '無理くり終わらせるが、処理遅い
    If i = 1048577 Then: Exit Do
    
    If Cells(i, 2) <> "" And Cells(i, 3) <> "" Then
        Cells(i, 4) = Cells(i, 2) * Cells(i, 3)
        Cells(i, 4).NumberFormatLocal = "\#,##0;\-#,##0"
    End If
Loop


End Sub

セルの最大行数を超えたら処理を終了するというコード。しかし、これすんごい遅い(;^ω^)。

4 神髄先生の回答

Dim i As Long
For i = 3 To Range("B2").CurrentRegion.Rows.Count + 1
  If Cells(i, 2) = "" Or Cells(i, 3) = "" Then
    Cells(i, 4) = ""
  Else
    Cells(i, 4) = Cells(i, 2) * Cells(i, 3)
  End If
Next
Columns("D").NumberFormatLocal = "\#,##0"

ポイントは、For i = 3 To Range("B2").CurrentRegion.Rows.Count + 1
Range(”B2”)..CurrentRegion.Rows.Count + 1とすることで、単価、点数が両方とも空白の場合でも処理範囲に入れることができ、かつ最小の処理範囲に抑えることができる。

さすがの模範解答と感じました。