変数宣言とデータ型

にメンテナンス済み

VBA でプログラムを書く際、変数はデータを一時的に記憶しておくための「箱」のような役割を果たします。変数を正しく宣言し、適切なデータ型を選ぶことは、バグの少ない、効率的なコードを書くための第一歩です。

この記事では、変数宣言の基本から、各データ型の特徴と使い分け、変数のスコープ(有効範囲)、そして Option Explicit によるバグ防止まで、VBA の変数に関するすべてを詳しく解説します。

変数が必要となるシチュエーション

実務では、以下のような場面で変数が必要になります:

  • 同じ値を繰り返し使用する: シート名やファイルパスなど、何度も参照する値を変数に格納して再利用する
  • 計算結果を保持する: 途中の計算結果を保存して、後の処理で活用する
  • 条件によって異なる値を扱う: If 文の結果に応じて変わる値を一時的に保持する
  • ループのカウンター: For 文で繰り返し回数を管理する
  • コードの可読性向上: マジックナンバーを避け、意味のある名前で値を管理する

変数宣言の基本

Dim ステートメント

VBA で変数を宣言するには Dim ステートメントを使用します。Dim は “Dimension”(次元・領域)の略で、変数のための領域を確保することを意味します。

variable_declaration_basic.bas
Sub VariableDeclarationBasic()
    ' 変数を宣言する
    Dim name As String
    Dim age As Long
    Dim price As Double
    Dim isActive As Boolean

    ' 値を代入する
    name = "山田太郎"
    age = 30
    price = 1980.5
    isActive = True

    ' 値を使う
    Debug.Print name   ' => 山田太郎
    Debug.Print age    ' => 30
    Debug.Print price  ' => 1980.5
    Debug.Print isActive ' => True
End Sub
宣言と代入は分けて書く

VBA では、変数の宣言と初期化を同時に行うことはできませんDim name As String = "山田" のような書き方はエラーになります。宣言と代入は必ず別の行で書いてください。

変数名のルール

VBA の変数名には以下のルールがあります:

  • 先頭文字: 英字(アルファベット)で始める必要がある
  • 使用可能文字: 英字、数字、アンダースコア(_
  • 使用不可文字: スペース、ピリオド、!@&$# など
  • 予約語の禁止: SubDimIfString などの VBA 予約語は使えない
  • 文字数: 最大 255 文字
  • 大文字・小文字: 区別されない(myVarMyVar は同じ変数)
variable_naming.bas
' ○ 良い変数名
Dim userName As String
Dim totalAmount As Long
Dim rowIndex As Long
Dim isCompleted As Boolean
Dim filePath As String

' × 使えない変数名
' Dim 1stName As String    ' 数字で始まっている
' Dim user name As String  ' スペースが含まれている
' Dim Sub As String        ' 予約語
変数名の命名規約

VBA では一般的にローワーキャメルケース(先頭小文字、単語の区切りは大文字)が使われます。例: userNametotalCountfilePath。 ループカウンターには ijk を使うのが慣例です。

データ型一覧と選び方

VBA で使用できる主要なデータ型を、用途ごとに整理して紹介します。

数値型

データ型名称範囲メモリ用途
Byteバイト型0 〜 2551 byte小さい正の整数
Integer整数型-32,768 〜 32,7672 byte小さい整数
Long長整数型-2,147,483,648 〜 2,147,483,6474 byte一般的な整数(推奨)
Single単精度浮動小数点数型±1.4E-45 〜 ±3.4E+384 byte小数を含む数値
Double倍精度浮動小数点数型±4.9E-324 〜 ±1.8E+3088 byte高精度な小数(推奨)
Currency通貨型-922,337,203,685,477.5808 〜 922,337,203,685,477.58078 byte金額計算(丸め誤差なし)

その他の型

データ型名称説明メモリ
String文字列型テキストデータを格納10 byte +α
Booleanブール型True または False のみ2 byte
Date日付型日付と時刻を格納8 byte
Objectオブジェクト型オブジェクトへの参照4 byte
Variantバリアント型あらゆるデータ型を格納(既定の型)16 byte +α

Integer と Long の使い分け

VBA を始めたばかりの方は「整数なら Integer でいいのでは?」と思うかもしれません。しかし、実務では Long の使用を推奨します。

integer_vs_long.bas
Sub IntegerVsLong()
    Dim rowCount As Integer
    Dim rowCountLong As Long

    ' Integer では Excel の行数を扱えない!
    ' Excel のシートは最大 1,048,576 行
    ' Integer の上限は 32,767 なのでオーバーフローエラーになる
    ' rowCount = Cells(Rows.Count, 1).End(xlUp).Row  ' エラーの可能性あり

    ' Long なら安全に扱える
    rowCountLong = Cells(Rows.Count, 1).End(xlUp).Row  ' OK
    Debug.Print "最終行: " & rowCountLong
End Sub
Integer のオーバーフローに注意

Integer 型は最大 32,767 までしか格納できません。Excel のシートは最大 1,048,576 行あるため、行番号を扱う変数に Integer を使用するとオーバーフローエラー(実行時エラー 6)が発生する可能性があります。特別な理由がない限り、整数には Long 型を使用してください。

String 型の使い方

文字列型には可変長固定長の2種類があります。

string_types.bas
Sub StringTypes()
    ' 可変長文字列(一般的)
    Dim name As String
    name = "山田太郎"
    Debug.Print name      ' => 山田太郎
    Debug.Print Len(name) ' => 4

    ' 固定長文字列(特殊な用途向け)
    Dim code As String * 5
    code = "ABC"
    Debug.Print code         ' => "ABC  "(5文字に満たない分はスペースで埋められる)
    Debug.Print Len(code)    ' => 5

    ' 文字列の結合
    Dim fullName As String
    Dim firstName As String
    Dim lastName As String
    firstName = "太郎"
    lastName = "山田"
    fullName = lastName & " " & firstName
    Debug.Print fullName  ' => 山田 太郎
End Sub
チェック

文字列の結合には & 演算子を使用します。+ 演算子でも結合できますが、数値型と混在するとエラーの原因になるため、文字列結合には常に & を使用するのが安全です。

Boolean 型

Boolean 型は True(真)または False(偽)の2つの値のみを取ります。条件の結果を保持する際に頻繁に使用します。

boolean_usage.bas
Sub BooleanUsage()
    Dim isFound As Boolean
    Dim isEmpty As Boolean

    ' 条件式の結果を代入
    isFound = (Range("A1").Value = "検索対象")
    isEmpty = (Range("B1").Value = "")

    ' 条件分岐に活用
    If isFound Then
        Debug.Print "見つかりました"
    End If

    ' Boolean 型の初期値は False
    Dim isActive As Boolean
    Debug.Print isActive  ' => False
End Sub

Variant 型 — 使うべきか避けるべきか

Variant 型はあらゆるデータ型の値を格納できる万能型です。データ型を指定せずに宣言した場合、自動的に Variant 型になります。

variant_behavior.bas
Sub VariantBehavior()
    ' 型を指定しないと Variant になる
    Dim value1             ' Variant 型
    Dim value2 As Variant  ' 明示的に Variant を指定(同じ結果)

    value1 = 100           ' 数値を代入
    Debug.Print TypeName(value1)  ' => Integer

    value1 = "テスト"      ' 文字列に変更可能
    Debug.Print TypeName(value1)  ' => String

    value1 = #2025/01/01#  ' 日付にも変更可能
    Debug.Print TypeName(value1)  ' => Date
End Sub
variant_pitfall.bas
Sub VariantPitfall()
    ' 注意: Dim a, b, c As Long は a と b が Variant になる!
    Dim a, b, c As Long
    Debug.Print TypeName(a)  ' => Empty(Variant)
    Debug.Print TypeName(b)  ' => Empty(Variant)
    Debug.Print TypeName(c)  ' => Long

    ' 正しい書き方
    Dim x As Long, y As Long, z As Long
End Sub
よくある間違い:複数変数の宣言

Dim a, b, c As Long と書くと、Long 型になるのは c だけです。abVariant 型になります。 複数の変数を同じ型で宣言する場合は、Dim a As Long, b As Long, c As Long のように各変数にデータ型を指定してください。これは VBA 初心者が最もつまずきやすいポイントの一つです。

Variant は避けるのがベストプラクティス

Variant 型は便利ですが、以下の理由からできるだけ避けましょう:

  • メモリ使用量が多い(16 byte 以上)
  • 型の不一致によるバグが発見しにくい
  • コードの意図が読み取りにくい
  • パフォーマンスが低下する

ただし、ワークシートの値を一括で配列に取得する場合など、Variant が必要な場面もあります。

各データ型の初期値

変数を宣言しただけで値を代入していない場合、データ型ごとに以下の初期値が設定されます。

データ型初期値
Long0
Double0
String""(空文字列)
BooleanFalse
Date0:00:00
ObjectNothing
VariantEmpty
default_values.bas
Sub CheckDefaultValues()
    Dim num As Long
    Dim text As String
    Dim flag As Boolean
    Dim dt As Date

    Debug.Print "Long: " & num     ' => Long: 0
    Debug.Print "String: " & text  ' => String:
    Debug.Print "Boolean: " & flag ' => Boolean: False
    Debug.Print "Date: " & dt      ' => Date: 0:00:00
End Sub

Option Explicit — 変数宣言の強制

Option Explicit とは

Option Explicit は、モジュールの先頭に記述することで、すべての変数の宣言を強制する命令です。未宣言の変数を使用するとコンパイルエラーが発生するようになります。

option_explicit_example.bas
Option Explicit

Sub WithOptionExplicit()
    Dim userName As String
    userName = "山田太郎"

    ' スペルミスがあるとコンパイルエラーになる!
    ' Debug.Print userNmae  ' => コンパイルエラー: 変数が定義されていません
    Debug.Print userName     ' => 山田太郎(正しい)
End Sub

Option Explicit がないとどうなるか

Option Explicit を記述しないと、VBA は未宣言の変数を自動的に Variant 型として作成します。これが思わぬバグの原因になります。

without_option_explicit.bas
' Option Explicit が記述されていない場合

Sub WithoutOptionExplicit()
    Dim totalAmount As Long
    totalAmount = 1000

    ' スペルミスに気づかない!
    ' "totalAmout" という別の Variant 変数が暗黙的に作成される
    Debug.Print totalAmout  ' => ""(空の Variant が表示される)

    ' 計算結果がおかしくなる原因に
    totalAmout = totalAmout + 500  ' totalAmount ではなく totalAmout に加算
    Debug.Print totalAmount  ' => 1000(期待値は 1500)
End Sub
チェック

Option Explicit を使用しないと、変数名のタイプミスがエラーにならず、発見困難なバグの原因になります。VBE の設定で自動挿入を有効にすることを強く推奨します。

Option Explicit の自動挿入設定

VBE(Visual Basic Editor)で、新規モジュール作成時に Option Explicit を自動的に挿入する設定ができます。

  1. VBE を開く(Excel で Alt + F11
  2. メニューの「ツール」→「オプション」を選択
  3. 編集」タブの「変数の宣言を強制する」にチェックを入れる
  4. 「OK」をクリック
チェック

この設定を一度行えば、以降作成するすべてのモジュールに Option Explicit が自動で挿入されます。VBA を始めたら最初に設定しておきましょう。

変数のスコープ(有効範囲)

VBA の変数には、どこからアクセスできるかを決めるスコープ(有効範囲)があります。スコープを正しく理解することで、意図しない変数の上書きやバグを防ぐことができます。

プロシージャレベル変数

SubFunction の内部で Dim を使って宣言した変数は、そのプロシージャ内でのみ使用できます。プロシージャの実行が終了すると、変数の値は破棄されます。

procedure_level.bas
Sub ProcedureA()
    Dim message As String
    message = "プロシージャA のメッセージ"
    Debug.Print message  ' => プロシージャA のメッセージ
End Sub

Sub ProcedureB()
    ' ProcedureA の message にはアクセスできない
    ' Debug.Print message  ' => コンパイルエラー(Option Explicit 有効時)
    Dim message As String
    message = "プロシージャB のメッセージ"
    Debug.Print message  ' => プロシージャB のメッセージ
End Sub

モジュールレベル変数

モジュールの先頭(プロシージャの外側)で Dim または Private を使って宣言した変数は、同じモジュール内のすべてのプロシージャからアクセスできます。

module_level.bas
Option Explicit

' モジュールレベル変数(このモジュール内でのみ有効)
Dim sheetName As String
Private counter As Long

Sub InitializeModule()
    sheetName = "データ一覧"
    counter = 0
End Sub

Sub IncrementCounter()
    counter = counter + 1
    Debug.Print sheetName & " - カウント: " & counter
End Sub

グローバル変数(Public 変数)

モジュールの先頭で Public を使って宣言した変数は、プロジェクト内のすべてのモジュールからアクセスできます。

global_variable.bas
' Module1 の先頭に記述
Public appTitle As String
Public maxRetryCount As Long
use_global_variable.bas
' Module2 から Module1 の Public 変数にアクセス
Sub UseGlobalVariable()
    appTitle = "売上管理ツール"
    maxRetryCount = 3
    Debug.Print appTitle  ' => 売上管理ツール
End Sub

スコープの比較

宣言方法宣言場所有効範囲
Dimプロシージャ内そのプロシージャ内のみ
Dim / Privateモジュールの先頭そのモジュール内のすべてのプロシージャ
Publicモジュールの先頭プロジェクト全体
Staticプロシージャ内そのプロシージャ内(値は保持される)
Static 変数

Static で宣言した変数は、プロシージャの実行が終了しても値が保持されます。プロシージャが呼び出されるたびにカウントアップしたい場合などに便利です。

static_variable.bas
Sub CountCalls()
    Static callCount As Long
    callCount = callCount + 1
    Debug.Print "この関数は " & callCount & " 回呼び出されました"
End Sub

' 1回目の呼び出し => "この関数は 1 回呼び出されました"
' 2回目の呼び出し => "この関数は 2 回呼び出されました"
' 3回目の呼び出し => "この関数は 3 回呼び出されました"
グローバル変数の多用は避ける

Public 変数はどこからでもアクセスできて便利ですが、多用すると以下の問題が発生します:

  • どこで値が変更されたか追跡しにくい
  • プロシージャ間の依存関係が複雑になる
  • テストやデバッグが困難になる

可能な限りプロシージャレベル変数を使用し、値の受け渡しは引数と戻り値で行いましょう。

オブジェクト変数と Set ステートメント

オブジェクト変数の宣言

ワークブック、ワークシート、Range などのオブジェクトを変数に格納する場合は、Set ステートメントを使用して代入します。

object_variables.bas
Sub ObjectVariables()
    ' オブジェクト変数の宣言と代入
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")

    Dim rng As Range
    Set rng = ws.Range("A1:D10")

    Dim wb As Workbook
    Set wb = ThisWorkbook

    ' オブジェクト変数を使用する
    Debug.Print ws.Name      ' => Sheet1
    Debug.Print rng.Address  ' => $A$1:$D$10
    Debug.Print wb.Name      ' => ブック名
End Sub
Set の忘れに注意

オブジェクト変数への代入で Set を忘れると、実行時エラー 91「オブジェクト変数または With ブロック変数が設定されていません」が発生します。

Dim ws As Worksheet
ws = ThisWorkbook.Sheets("Sheet1")      ' × エラー!
Set ws = ThisWorkbook.Sheets("Sheet1")  ' ○ 正しい

オブジェクト変数の解放

オブジェクト変数を使い終わったら Nothing を代入して解放するのがよい習慣です。

release_object.bas
Sub ReleaseObject()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("Sheet1")

    ' シートの操作を行う
    ws.Range("A1").Value = "完了"

    ' オブジェクト参照を解放
    Set ws = Nothing
End Sub
Property Let と Set の違い
VBA でクラスを作成し、 プロパティ(メンバー変数) を取り扱う際に作成する Property メソッドには Get, Set, Let があります。一般的に、VBA 以外の言語では、プロパティ(メンバー変数)に設定するのは Getter

定数の宣言(Const)

プログラム実行中に変更されない値は、変数ではなく**定数(Const)**として宣言します。

const_declaration.bas
Option Explicit

' モジュールレベルの定数
Private Const TAX_RATE As Double = 0.1
Private Const MAX_ROWS As Long = 1000
Public Const APP_NAME As String = "売上管理システム"

Sub CalculateTax()
    Dim price As Long
    price = 1000

    Dim taxIncluded As Double
    taxIncluded = price * (1 + TAX_RATE)
    Debug.Print APP_NAME & ": 税込価格 = " & taxIncluded  ' => 売上管理システム: 税込価格 = 1100
End Sub
チェック

定数名は大文字のスネークケースTAX_RATEMAX_RETRY_COUNT)で書くのが一般的です。これにより変数との区別が一目でつくようになります。

マジックナンバーを避ける
プログラムにおいて、マジックナンバーは原則避けるべきコーディングです。VBA 以外の言語においては、少し学びさえすればマジックナンバーが現れることはほぼ無いかと思いますが、VBA ではなかなか避けられないケースは多いです。扱うデータの性質上

データ型の選び方ガイド

実務で変数を宣言する際の、データ型の選び方をまとめます。

用途別の推奨データ型

用途推奨データ型理由
行番号・列番号LongExcel の最大行数(1,048,576)を超えない
ループカウンターLongInteger のオーバーフローを防止
金額計算Currency丸め誤差が発生しない
小数を含む計算DoubleSingle より精度が高い
フラグ(はい/いいえ)BooleanTrue/False で明確に表現できる
テキスト処理String文字列専用
日付・時刻の処理Date日付計算に便利な関数が使える
シートの値を一括取得Variant配列として取得する際に必要

初心者向け選択フローチャート

迷ったらこのフローで選びましょう:

  1. 数値? → 整数なら Long 、小数なら Double、お金なら Currency
  2. 文字列? → String
  3. はい/いいえ? → Boolean
  4. 日付? → Date
  5. オブジェクト? → 具体的なオブジェクト型WorksheetRange など)
  6. よく分からない → Variant(ただし後で適切な型に変更する)

実践的な活用例

例1:データの集計処理

practical_aggregation.bas
Option Explicit

Sub AggregateData()
    Dim ws As Worksheet
    Set ws = ThisWorkbook.Sheets("売上データ")

    Dim lastRow As Long
    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row

    Dim totalSales As Currency
    Dim itemCount As Long
    Dim averageSales As Double
    totalSales = 0
    itemCount = 0

    Dim i As Long
    For i = 2 To lastRow  ' 2行目から(1行目はヘッダー)
        Dim amount As Currency
        amount = ws.Cells(i, 3).Value  ' 3列目が金額と仮定

        totalSales = totalSales + amount
        itemCount = itemCount + 1
    Next i

    ' 平均を計算
    If itemCount > 0 Then
        averageSales = totalSales / itemCount
    End If

    Debug.Print "合計: " & FormatCurrency(totalSales)
    Debug.Print "件数: " & itemCount
    Debug.Print "平均: " & FormatCurrency(averageSales)

    Set ws = Nothing
End Sub

例2:ファイルパスの組み立て

practical_filepath.bas
Option Explicit

Sub BuildFilePath()
    Const BASE_FOLDER As String = "C:\Reports\"
    Const FILE_PREFIX As String = "monthly_report_"
    Const FILE_EXTENSION As String = ".xlsx"

    Dim currentYear As Long
    Dim currentMonth As Long
    currentYear = Year(Date)
    currentMonth = Month(Date)

    ' ファイル名を組み立てる
    Dim fileName As String
    fileName = FILE_PREFIX & currentYear & "_" & Format(currentMonth, "00") & FILE_EXTENSION

    Dim fullPath As String
    fullPath = BASE_FOLDER & fileName

    Debug.Print fullPath  ' => C:\Reports\monthly_report_2026_02.xlsx
End Sub

注意点とトラブルシューティング

よくあるエラーと対処法

エラー原因対処法
「型が一致しません」(エラー 13)変数の型と代入する値の型が合わないデータ型を確認し、型変換関数(CLngCStr 等)を使う
「オーバーフロー」(エラー 6)値がデータ型の範囲を超えたLongDouble など、より大きい型を使用
「変数が定義されていません」Option Explicit 有効時に未宣言の変数を使用変数を Dim で宣言する
「オブジェクト変数が設定されていません」(エラー 91)Set を使わずにオブジェクト変数に代入Set ステートメントを使用する

型変換関数

異なるデータ型間で値を変換する場合は、型変換関数を使用します。

type_conversion.bas
Sub TypeConversion()
    Dim text As String
    text = "12345"

    ' 文字列 → 数値
    Dim num As Long
    num = CLng(text)  ' => 12345

    ' 数値 → 文字列
    Dim numStr As String
    numStr = CStr(num)  ' => "12345"

    ' その他の型変換関数
    ' CInt()  - Integer に変換
    ' CDbl()  - Double に変換
    ' CCur()  - Currency に変換
    ' CBool() - Boolean に変換
    ' CDate() - Date に変換
End Sub

練習問題

次のコードの出力結果として正しいものはどれですか?
Dim a, b As Long
a = 10
b = 20
Debug.Print TypeName(a) & " / " & TypeName(b)
正解は「Integer / Long」です。Dim a, b As Long と書いた場合、Long 型になるのは b だけです。a は型指定がないため Variant 型になり、整数 10 を代入すると Integer として保持されます。すべての変数を Long にするには Dim a As Long, b As Long と書く必要があります。
Option Explicit が記述されたモジュールで、以下のコードを実行するとどうなりますか?
Sub Test()
    Dim counter As Long
    cunter = 10
    Debug.Print counter
End Sub
正解は「コンパイルエラーが発生する」です。Option Explicit が有効な場合、cunter(スペルミス)は宣言されていない変数として検出され、「コンパイルエラー: 変数が定義されていません」が発生します。これが Option Explicit を使用する最大のメリットです。
Excel VBA で行番号を格納する変数のデータ型として、最も適切なものはどれですか?
正解は「Long」です。Excel のシートは最大 1,048,576 行あり、Integer(最大 32,767)では不足します。Double は小数を扱うための型であり、行番号には不適切です。Variant でも動作しますが、明示的な型指定が推奨されます。Long(最大 約21億)なら十分に対応できます。

まとめ

  • 変数は Dim 変数名 As データ型 で宣言し、代入は別の行で行う
  • 整数には Integer ではなく Long を使用するのがベストプラクティス
  • Dim a, b As Long では aVariant 型になる。各変数に型を指定する
  • Option Explicit を必ず有効にして、未宣言変数によるバグを防止する
  • VBE のオプションで「変数の宣言を強制する」を有効にしておく
  • 変数のスコープは必要最小限にする(プロシージャレベル > モジュールレベル > グローバル)
  • オブジェクト変数の代入には Set が必要
  • 変更されない値は定数(Const)として宣言する
Debug.Printとデバッグ手法
VBAのデバッグ技術をマスターして、効率的にバグを発見・修正しましょう。Debug.Print、イミディエイトウィンドウ、ブレークポイント、ステップ実行、ウォッチウィンドウなど、実践的なデバッグ手法を詳しく解説します。
配列の操作
配列を使用することで、複数のデータを一つの変数に格納することができます。VBAにおける配列の定義と操作方法について解説します。
Collectionオブジェクト
VBAのCollectionオブジェクトは、複数のデータを柔軟に管理できる便利なデータ構造です。この記事では、Collectionの基本的な使い方から、Dictionaryとの使い分け、実践的な活用方法まで詳しく解説します。
Sub と Function の違い
VBAのSubプロシージャとFunctionプロシージャの違いを初心者向けに徹底解説。戻り値の有無、引数の渡し方(ByRef・ByVal)、スコープ(Public・Private)、呼び出し方法まで、実践的なコード例とともに紹介します。
ループ処理 (For / Do)
VBAのループ処理(For Next、For Each、Do While、Do Until)の書き方を初心者向けに徹底解説。繰り返し処理の基本構文から、Exit文によるループ脱出、ネスト、パフォーマンス最適化まで、実践的なコード例とともに紹
#VBA #変数 #データ型 #Option Explicit #初心者向け