VBAの便利な使い方

続いては、VBAの使い方の一例をご紹介します。ここではプログラミングにおける専門用語が出てきますが、ゆっくりと理解すれば問題ありません。一つずつ丁寧に説明しますので、あせらずじっくりと読み進めてくださいね。

<VBAの変数・配列とは>

VBAを使いこなすにあたって、知っておきたいのが「変数」と「配列」です。

変数とは、プログラミング言語において値を入れておく「ボックス」を指します。このボックスには1つの値しか入らず、2つ目の値が入ると1つ目の値は消えてしまいます。処理によって中身が変わることから「変数」と呼ばれています。1つの変数には1つの値しか入らないと覚えておきましょう。

続いて登場するのが「配列」です。配列は1つの変数に対して、複数の値を入れることができます。変数=一軒家、配列=マンションと例えると、わかりやすいでしょう。変数(一軒家)にはAさんしか住めないけれど、配列(マンション)には複数のボックス(部屋)があり、Aさん、Bさん、Cさん、Dさんが住めるとイメージしてみてください。

配列は先頭が0から始まるというルールを持っていますので、併せて覚えておくと良いでしょう。

続いては、いくつか具体例を出しながら、便利なVBAの使い方をご紹介します。

<一つのセルに入力された日付を年・月・日に分割する>

スクリーンショット 2019-08-16 16.12.01.png
一つのセルに入力された情報を複数のセルに分割する方法は、覚えておくとさまざまな場面で活用できます。以下は、一つのセルに入力された日付を年・月・日の3つのセルに分割する際のサンプルコードです。こちらを応用して業務に活用してみてくださいね。

エクセルのフォーマット例

サンプルコード

Sub 行の分割()
Dim 行 As Long
Dim i As Long
行 = Cells(Rows.Count, 1).End(xlUp).Row
Range("A1:C1").EntireColumn.Insert
Range("A1").Value = "年"
Range("B1").Value = "月"
Range("C1").Value = "日"
Range("D1").AutoFill Destination:=Range("A1:D1"), Type:=xlFillFormats
For i = 2 To 行
Range("A" & i).Value = Year(Range("D" & i).Value)
Range("B" & i).Value = Month(Range("D" & i).Value)
Range("C" & i).Value = Day(Range("D" & i).Value)
Next i
Application.DisplayAlerts = False
Range("D1").EntireColumn.Delete
Application.DisplayAlerts = True
End Sub

<単位の付いた数値の合計を算出する>

通常、エクセルのSUM関数では「個」や「円」など単位のついた値の合計を算出することはできません。しかし、文字列を数値に変換するVal関数を使用してVBAのプログラムを書くことで、この問題を解消して合計値を算出できます。

エクセルフォーマット例
スクリーンショット 2019-08-16 16.12.20.png
 
サンプルコード
Sub 単位付きの数値を合計()
Dim 行 As Long
Dim i As Long
Dim 合計1 As Long
Dim 合計2 As Long
行 = Cells(Rows.Count, 1).End(xlUp).Row - 1
For i = 2 To 行
Cells(i, 4) = Val(Cells(i, 2)) * Val(Cells(i, 3))
合計1 = 合計1 + Val(Cells(i, 3))
合計2 = 合計2 + Val(Cells(i, 4))
Next i
Cells(行 + 1, 3) = 合計1
Cells(行 + 1, 4) = 合計2
Range("C" & 行 + 1).NumberFormatLocal = "##,###" & "個"
Range("D2", "D" & i + 1).NumberFormatLocal = "##,###" & "円"
End Sub

<MsgBox関数の設定方法>

VBAの便利な使い方の一つに、メッセージボックスを表示させる「MsgBox関数」があります。このMsgBox関数を使うと、メッセージボックスで「はい」「いいえ」などのメッセージを表示し、その後の処理を分岐させることも可能です。

【MsgBox関数の構文】

MsgBox関数は、以下のような構文になっています。

Msgbox([prompt], [buttons], [title], [helpfile, context])
prompt……ダイアログボックスに表示するメッセージを指定する
buttons……ダイアログボックスに表示するボタンの種類を指定する(省略可)
title……ダイアログボックスの上部に表示するタイトルを指定する(省略可)
helpfile, context……ヘルプファイルを設定する際に指定する(省略可だが、helpfileを指定した場合は、必ずcontextも指定する必要がある)

promptに設定できる文字数は1バイト文字で約1,024文字までとなっており、文字列で指定します。

Buttonsには、以下のようなボタンやアイコンを指定できます。一部、抜粋してご紹介します。
スクリーンショット 2019-08-16 16.12.40.png

たとえば、エラーメッセージと共に警告アイコンを表示させたい場合は、以下のようにコードを表記します。
[primary]Sub Sample()
MsgBox "この操作は実行できません。", Buttons:= vbCritical
End Sub[/primary]

「はい」「いいえ」など、ユーザーが選択したボタンによって処理を変えたい場合は、MsgBoxの戻り値を使用しましょう。戻り値は以下の表を参照してください。
スクリーンショット 2019-08-16 16.13.02.png

たとえば、「処理を実行しますか?」とのメッセージとともに「はい」「いいえ」ボタンを表示させ、ユーザーが選択したボタンによって処理を変える(異なるメッセージを表示させる)場合は、以下のようにコードを表記します。
Sub Sample()
Dim rslt As VbMsgBoxResult
rslt = MsgBox("処理を実行しますか?", Buttons:=vbYesNo)
If rslt = vbYes Then
MsgBox "処理を実行しました。"
Else
MsgBox "処理を中止しました。"
End If
End Sub

※「はい」を押すと「処理を実行しました。」と表示、「いいえ」を押すと「処理を中止しました。」と表示されます。

<初心者は注意!最終行のデータ取得方法>

VBAを始めたばかりの初心者が引っかかりやすいのが、エクセルの最終行のデータを取得する際のコードの書き方です。この点について配慮しないコードを書いてしまうと、数値の取りこぼしが起こる可能性があります。

たとえば、数値が書かれたエクセルデータの途中に空欄の箇所があった場合、空欄以降のセルのデータを取得しない等の問題が起こる、などです。このようなエラーを起こしづらい2つのサンプルコードをご紹介します。

【ワークシートの最大行・最大列を取得するサンプルコード①】

MaxRow = Cells(Rows.Count, 1).End(xlUp).Row
MaxCol = Cells(1, Columns.Count).End(xlToLeft).Column

こちらはスタンダードな方法で、ワークシートの最下列から上方向に向かって、値のあるセルを検索してデータを取得するコードです。最下列からセルを検索することで、途中に空欄のセルがあってもすべてのデータを取得することが可能になります。

Rowはワークシートの行(横)を表し、Columnは列(縦)をあらわすオブジェクトです。ややこしいですが、2つとも覚えておきましょう。

【ワークシートの最大行・最大列を取得するサンプルコード②】

[primary]With ActiveSheet.UsedRange
MaxRow = .Find("", , xlFormulas, , xlByRows, xlPrevious).Row
MaxCol = .Find("
", , xlFormulas, , xlByColumns, xlPrevious).Column
End With[/primary]

ワークシートの最下列から書式付きのセルを除外し、値のあるセルの最終行、最終列を検索してデータを取得するコードです。VBAプログラムには相性の問題もあり、必ずしもご紹介したサンプルコードが当てはまるとは限りません。エラーが出てしまう場合は、さまざまなコードを試して検証してみましょう。