名前の二重定義の回避

定義済みの識別子を作成しようとしたり、使用しようとすると、名前付けの競合が発生します。名前付けの競合によって、"名前が適切ではありません。" または "同じスコープ内で宣言が重複しています。" などのエラー メッセージが表示されることがあります。ただし、名前付けの競合は検出されない場合もあります。特に、すべての変数を明示的に宣言せずに変数を使用すると、コード内で名前付けの競合が発生し、間違った結果が生じる可能性があります。

名前付けの競合の多くは、データ、オブジェクト、およびプロシージャの識別子の適用範囲 (スコープ) の特性を理解することで解決できます。Visual Basic には、プロシージャ  レベル、プライベート モジュール レベル、およびパブリック モジュール レベルという 3 つのスコープ レベルがあります。

名前付けの競合は、次のような識別子に関連して発生することがあります。

•	複数のスコープ レベルで表示される識別子。

•	同じレベルで 2 つの異なる意味を持つ識別子。

たとえば、別々のモジュール内の各プロシージャは、同じ名前を使うことができます。したがって、プロシージャ MySub をモジュール Mod1 およびモジュール Mod2 内で定義することができます。プロシージャが定義されているモジュール内でのみ呼び出される場合は、競合は発生しません。ただし、プロシージャ MySub がこれら以外のモジュールから呼び出される場合に、2 つの MySub プロシージャを区別する修飾子を指定しなければ、エラーが発生することがあります。

一般に、名前付けの競合は、各識別子の前にモジュール名を付加し、さらに必要に応じてプロジェクト名を追加して構成される修飾子を付けることにより解決できます。たとえば、次のように指定します。

YourProject.YourModule.YourSub MyProject.MyModule.MyVar

上のコードは、Sub プロシージャ YourSub を呼び出し、引数として MyVar を渡します。同じ識別子を区別できる修飾子を任意に組み合わせて使用することができます。

識別子を参照すると、対応する識別子のうち、"最も近く" で宣言されている識別子がそれぞれ自動的に検索されます。たとえば、変数 MyID がプロジェクト内の 2 つのモジュール (Mod1 と Mod2) でキーワード Public を指定して宣言されている場合、モジュール Mod2 内では修飾しなくても Mod2 内で宣言された変数 MyID を指定できます。Mod2 内で宣言された MyID を Mod1 内で指定する場合には、Mod2.MyID のように修飾する必要があります。これは Mod2 が異なる直接参照先プロジェクト内にある場合でも同じです。ただし、Mod2 が間接的に参照するプロジェクト (直接参照するプロジェクトから参照するプロジェクト) 内にある場合は、Mod2 内の変数 MyID への参照は、常にプロジェクト名で修飾する必要があります。他の直接参照先モジュールから MyID を参照すると、次の対象を検索し、最初に見つかった宣言を MyID とみなします。

•	[ツール] メニューの [参照設定] ダイアログ ボックスに表示される順に、直接参照先プロジェクトが検索されます。

•	各プロジェクトのモジュールが検索されます。ただし、プロジェクト内のモジュールには固有の順序がないので注意してください。

ホスト アプリケーションのオブジェクト (Microsoft Excel の R1C1 など) を異なるスコープ レベルで再利用することはできません。

ヒント   名前付けの競合によって発生する典型的なエラーには、あいまいな名前によるエラー、宣言を複製するときのエラー、識別子が宣言されていないためのエラー、プロシージャが見つからないためのエラーなどがあります。各モジュールの先頭で、Option Explicit ステートメントを指定して、各変数を使用する前にその変数の明示的な宣言を強制することにより、名前付けの競合と識別子に関連するエラーを防ぐことができます。


同じ名前のプロシージャの呼び出し

アクティブ モジュール内のプロシージャを呼び出す場合と同様に、アクティブ モジュールと同じプロジェクトのモジュール内にあるプロシージャを呼び出すことができます。ただし、複数のモジュールに同じ名前のプロシージャが記述されている場合、次の例のように呼び出しステートメントでモジュール名を指定しなければなりません。

Sub Main()

Module1.MyProcedure

End Sub

2 つの異なるプロジェクト内で、2 つの異なるプロシージャに同じ名前を付けると、そのプロシージャを呼び出す場合に、プロジェクト名を指定しなければなりません。たとえば、次のプロシージャは、MyProject.vbp プロジェクト内の MyModule モジュールの Main プロシージャを呼び出します。

Sub Main()

[MyProject.vbp].[MyModule].Main

End Sub

メモ   アプリケーションにより、プロジェクトの名称は異なります。たとえば、Microsoft Access では、プロジェクトはデータベース (.MDB) と呼びますが、Microsoft Excel では、ワークシート (.XLS) と呼んでいます。

プロシージャを呼び出すヒント

•	モジュールやプロジェクトの名前を変更する場合、そのモジュールまたはプロジェクトを呼び出すステートメントで指定されている名前もすべて変更します。名前が変更されていないと、Visual Basic は呼び出すプロシージャを検索できません。[編集] メニューの [置換] を使って、モジュールの文字列を検索および置換できます。

•	参照元のプロジェクト間で名前付けの競合を防ぐには、プロシージャに重複しない名前を付け、プロジェクトやモジュールを指定せずにプロシージャを呼び出せるようにします。


 Property プロシージャの呼び出し

Property プロパティ プロシージャを呼び出す場合の構文は次のとおりです。

Property プロシージャ	構文
Property Let プロシージャ	[object.]propname(arguments)] = argument
Property Get プロシージャ	varname = [object.]propname(arguments)]
Property Set プロシージャ	Set [object.]propname[.(arguments)] = varname
Property Let プロシージャまたは Property Set プロシージャを呼び出すときは、等号 (=) の右側に必ず引数を 1 つ指定します。

複数の引数を持つ Property Let プロシージャまたは Property Set プロシージャを宣言すると、式の右辺に指定された値が Property Let プロシージャまたは Property Set プロシージャの宣言で定義した最後の引数に渡されます。たとえば、次の図は、Property プロシージャを呼び出すときに指定する引数と Property Let プロシージャの宣言で定義した引数の関係を示しています。

複数の引数を持つ Property プロシージャを使用するのは、通常、プロパティの配列を作成する場合だけです。


Sub プロシージャと Function プロシージャの呼び出し

Sub プロシージャを別のプロシージャから呼び出すには、プロシージャ名を入力し、必要な引数の値を指定します。Call ステートメントは必要ありませんが、Call ステートメントを記述する場合は、引数をかっこで囲まなければなりません。

Sub プロシージャを使って、複数のプロシージャをまとめて記述することにより、コードを理解しやすく、簡単にデバッグできるようにすることが可能です。次のコード例では、Sub プロシージャ Main は Sub プロシージャ MultiBeep を呼び出し、引数として値 56 を引き渡します。MultiBeep が実行されると、制御は Main に戻り、Main は、Sub プロシージャ Message を呼び出します。Message は、メッセージ ボックスを表示します。ユーザーが [OK] をクリックすると、制御は Main に戻り、Main は終了します。

Sub Main()

MultiBeep 56

Message

End Sub

Sub MultiBeep(numbeeps)

For counter = 1 To numbeeps

Beep

Next counter

End Sub

Sub Message()

MsgBox "休憩の時間です。"

End Sub

複数の引数を持つ Sub プロシージャの呼び出し

次のコード例は、複数の引数を持つ Sub プロシージャを呼び出す方法として、2 つの方法を示しています。2 度目に HouseCalc を呼び出すときは、Call ステートメントを使用するので、引数をかっこで囲む必要があります。

Sub Main()

HouseCalc 99800, 43100

Call HouseCalc(380950, 49500)

End Sub

Sub HouseCalc(price As Single, wage As Single)

If 2.5 * wage <= 0.8 * price Then

MsgBox "この家は購入不可能です。"

Else

MsgBox "この家は購入可能です。"

End If

End Sub

Function プロシージャ呼び出し時のかっこの使い方

関数の戻り値を使用するには、次のコード例のように、式の中で関数を変数に代入して、引数をかっこで囲みます。

Answer3 = MsgBox("現在の給与に満足していますか ?", 4, "質問 3")

また、関数の戻り値が不要の場合は、Sub プロシージャを呼び出すときと同じ方法で関数を呼び出すことができます。次のコード例のように、かっこを省略して引数リストを指定し、関数を変数に代入しないように記述します。

MsgBox "作業が完了しました。", 0, "作業ボックス"

注意   このコード例で、引数をかっこで囲むと、構文エラーになります。

名前付き引数の引き渡し

Sub プロシージャおよび Function プロシージャのステートメントは、名前付き引数を使って、呼び出すプロシージャに値を引き渡すことができます。名前付き引数を使う場合、構文で決まっている記述順序に関係なく、任意の順序で指定できます。名前付き引数に値を代入するには、引数名、コロンと等号 (:=)、引数に代入する値の順で記述します。

次の例は、名前付き引数を使って MsgBox 関数を呼び出します。戻り値は無視します。

MsgBox Title:="作業ボックス", Prompt:="作業が完了しました。"

次の例は、名前付き引数を使って MsgBox 関数を呼び出します。戻り値は、変数 answer3 に代入されます。

answer3 = MsgBox(Title:="質問 3", _

Prompt:="現在の給与に満足していますか ?", Buttons:=4)


オブジェクト変数の作成

変数は、値以外にオブジェクトへの参照を格納することができます。オブジェクト変数を使うと、オブジェクトを参照するときと同じように操作することができます。たとえば、オブジェクトのプロパティの値を取得または設定したり、そのオブジェクトのメソッドを使用することができます。

オブジェクト変数を作成するには、

1.	オブジェクト変数を宣言します。

2.	オブジェクト変数にオブジェクトへの参照を代入します。

オブジェクト変数の宣言

オブジェクト変数は、Dim ステートメント、または他の宣言ステートメント (Public ステートメント、Private ステートメント、または Static ステートメント) を使って宣言します。オブジェクト変数は、バリアント型 (Variant)、オブジェクト型 (Object)、または固有オブジェクト型でなければなりません。有効な宣言の例を次に示します。

Dim MyObject	' MyObject をバリアント型で宣言します。

Dim MyObject As Object	' MyObject をオブジェクト型で宣言します。

Dim MyObject As Font	' MyObject を固有オブジェクト型 (Font) で宣言します。

メモ   オブジェクト変数を宣言せずに使用すると、そのオブジェクトのデータ型は、既定のバリアント型 (Variant) になります。

オブジェクト型 (Object) のオブジェクト変数は、プロシージャを実行するまでオブジェクト型 (Object) が特定できない場合に使用します。オブジェクト型 (Object) の変数は、任意のオブジェクトへの参照を格納できます。

参照するオブジェクトの種類がわかっている場合は、そのオブジェクトの種類を指定してオブジェクト変数を宣言します。たとえば、Sample オブジェクトを利用するアプリケーションで、そのオブジェクトを参照するオブジェクト変数を宣言する場合は、次のどちらのステートメントでも記述できます。

Dim MyObject As Object	' 総称オブジェクト型で宣言します。

Dim MyObject As Sample	' 固有オブジェクト型 (Sample) で宣言します。

特定のオブジェクトを指定して、固有オブジェクト型として宣言すると、データ型のチェックが自動的に行われると共に、コードの実行速度やコードの読みやすさも向上します。

参照オブジェクトのオブジェクト変数への代入

オブジェクト変数にオブジェクトへの参照を代入するには、Set ステートメントを使用します。オブジェクト変数に代入できるのは、オブジェクト式または Nothing のいずれかです。オブジェクト変数への代入例を示します。

Set MyObject = YourObject	' 参照オブジェクトを代入します。

Set MyObject = Nothing	' 変数とオブジェクトの関係を無効にします。

Set ステートメントで、キーワード New を使用すると、オブジェクト変数の宣言と、オブジェクトへの参照の代入を同時に記述できます。たとえば、次のように指定します。

Set MyObject = New Object	' オブジェクトを作成して代入します。

オブジェクト変数に Nothing を代入すると、そのオブジェクト変数と変数が参照していたオブジェクトとの関係が無効になります。変数とオブジェクトの関係を無効にすることにより、変数の内容を変更して、参照していたオブジェクトに誤って変更を加えてしまうことを防ぐことができます。また、オブジェクトを閉じた後は、そのオブジェクトを参照しているオブジェクト変数に必ず Nothing に代入するようにすると、オブジェクト変数が有効なオブジェクトを参照しているかどうかを簡単に調べることができます。次にその例を示します。

If Not MyObject Is Nothing Then

' オブジェクト変数が有効なオブジェクトを参照している場合。

. . .

End If

このテストでは、オブジェクト変数が参照しているオブジェクトを含むアプリケーションを、ユーザーが閉じたのかどうかを確実に判断することはできません。

オブジェクトの現在のインスタンスへの参照

コードの実行中にオブジェクトの現在のインスタンスを参照するには、キーワード Me を使います。現在のオブジェクトに関連付けられたすべてのプロシージャが、キーワード Me を指定して参照されるオブジェクトへのアクセス権を持ちます。オブジェクトの現在のインスタンスに関する情報を別のモジュールのプロシージャに渡す場合に、キーワード Me を使用すると特に便利です。たとえば、モジュールに次のプロシージャがあるものとします。

Sub ChangeObjectColor(MyObjectName As Object)

MyObjectName.BackColor = RGB(Rnd * 256, Rnd * 256, Rnd * 256)

End Sub

次のステートメントを使ってプロシージャを呼び出し、オブジェクトの現在のインスタンスを引数として渡すことができます。

ChangeObjectColor Me


再帰プロシージャの作成

プロシージャが使用できる変数用のメモリ領域のサイズは限られています。プロシージャが自分自身を呼び出すと、そのたびに消費される変数用の領域も多くなります。自分自身を呼び出すプロシージャは、再帰プロシージャと呼ばれます。再帰プロシージャは、繰り返し自分自身を呼び出し、最終的にエラーを発生させます。次に例を示します。

Function RunOut(Maximum)

RunOut = RunOut(Maximum)

End Function

2 つのプロシージャが互いを無限に呼び出し合う場合、また、再帰呼び出しを制限する条件を指定しても、その条件が満たされない場合、このようなエラーを検出することが難しくなります。たとえば、次の例は、階乗を計算する再帰プロシージャです。

Function Factorial (N)

If N <= 1 Then	' 再帰呼び出しの終了条件。

Factorial = 1	' (N = 0) が真なので、それぞれの呼び出しを終了します。

Else	' N > 0 の場合は、再度 Factorial を呼び出します。

Factorial = Factorial(N - 1) * N

End If

End Function

再帰プロシージャを使用する場合は、メモリが不足するまで自分自身を呼び出していないかどうかを確認する必要があります。エラーが発生した場合は、プロシージャが自分自身を無限に呼び出していないかどうかを確認してください。その後、次に示す方法でメモリの使用量を抑えてください。

•	不必要な変数を取り除きます。

•	バリアント型 (Variant) 以外のデータ型を使います。

•	プロシージャの論理構造を見直します。多くの場合、再帰プロシージャを使う代わりにループをネスト (入れ子) させて解決できます。


配列の宣言

配列は、Dim ステートメント、Static ステートメント、Private ステートメント、または Public ステートメントを使って他の変数と同じように宣言します。スカラ変数 (配列でない変数) と配列変数の違いは、配列変数の場合、通常はサイズ (要素数) を指定する必要があるという点です。サイズが指定されている配列は、固定長配列と呼ばれます。プログラムを実行中にサイズを変更できる配列は、動的配列と呼ばれます。

配列のインデックス番号の最小値を 0 にするか、1 にするかは、Option Base ステートメントの設定で決まります。Option Base 1 を設定しない限り、すべての配列の最小値は 0 になります。

固定長配列の宣言

次のコード行では、11 行、11 列の固定長配列を持つ整数型 (Integer) の配列として宣言します。

Dim MyArray(10, 10) As Integer

最初の引数は行を表し、2 番目の引数は列を表します。

他の変数を宣言する場合と同様に、配列にデータ型を指定しないと、宣言した配列の要素のデータ型は、既定のバリアント型 (Variant) となります。数値をバリアント型 (Variant) で宣言した場合、配列の各要素は、16 バイトのメモリを使用します。文字列をバリアント型 (Variant) で宣言した場合、各要素は、22 バイトのメモリを使用します。できる限り簡潔なコードを記述するために、配列をバリアント型 (Variant) 以外のデータ型として、明示的に宣言してください。次のコード行は、いくつかの配列のサイズを比較します。

' この整数型の配列は、22 バイトを使用します (11 要素 * 2 バイト)。

ReDim MyIntegerArray(10) As Integer

' この倍精度浮動小数点数型の配列は、88 バイトを使用します (11 要素 * 8 バイト)。

ReDim MyDoubleArray(10) As Double

' このバリアント型の配列は、最低 176 バイトを使用します (11 要素 * 16 バイト)。

ReDim MyVariantArray(10)

' この整数型の配列は、100 * 100 * 2 バイト (20,000 バイト) を使用します。

ReDim MyIntegerArray (99, 99) As Integer

' この倍精度浮動小数点数型の配列は、100 * 100 * 8 バイト (80,000 バイト) を使用します。

ReDim MyDoubleArray (99, 99) As Double

' このバリアント型の配列は、最低 160,000 バイト (100 * 100 * 16 バイト) を使用します。

ReDim MyVariantArray(99, 99)

配列の最大サイズは、オペレーティング システムや利用可能なメモリ量により異なります。システムで利用可能な RAM の容量を超える配列を使用すると、データをディスクから読み取ったり、ディスクに書き込んだりする処理が発生するため、処理速度が遅くなります。

動的配列の宣言

動的配列を宣言すると、コードの実行時に配列のサイズを変更できます。配列を宣言するには、次の例のように、Static ステートメント、Dim ステートメント、Private ステートメント、または Public ステートメントを使用します。また、かっこの中のインデックス番号は、省略します。

Dim sngArray() As Single

メモ   ReDim ステートメントは、変数がモジュール レベルまたはプロシージャ レベルで存在しない場合、宣言ステートメントとして動作します。より広い適用範囲をもつ同じ名前の別の変数が作成された場合でも、ReDim ステートメントは後者の変数を参照するため、Option Explicit が有効であっても、必ずしもコンパイル エラーは発生しません。このような競合を防ぐには、ReDim ステートメントを宣言ステートメントとしてではなく、あくまでも配列の大きさを再設定するものとして使用する必要があります。

配列の適用範囲内のプロシージャで、ReDim ステートメントを使って、次元数の変更、要素数の定義、各次元の上限と下限を指定します。また、必要に応じて動的配列を変更することもできます。ただし、ReDim ステートメントを実行するたびに、配列の現在の値が失われます。ReDim Preserve ステートメントを使用すると、配列の現在値を保持した状態で配列を拡張できます。たとえば、次のステートメントは元の要素に設定されている値を失わずに、配列 varArray を拡張して 10 要素を追加します。

ReDim Preserve varArray(UBound(varArray) + 10)

メモ   動的配列でキーワード Preserve を使用する場合、最後の次元の上限値のみ変更できます。次元数は変更できません。


定数の宣言

定数を宣言すると、値に意味のある名前を割り当てることができます。定数を宣言して値を設定するには、Const ステートメントを使います。定数の宣言後、定数を修正したり、新しい値を代入することはできません。

プロシージャ内または宣言セクションのモジュールの先頭で定数を宣言します。モジュール レベル定数は、既定ではプライベート定数となります。パブリック モジュール レベルの定数を宣言するには、Const ステートメントの前にキーワード Public を指定します。Const ステートメントの前にキーワード Private を指定して、プライベート定数を明示的に宣言すると、コードの内容がわかりやすくなります。詳細については、Visual Basic ヘルプの「適用範囲と参照可能範囲の概要」を参照してください。

次の例は、パブリック定数 conAge を整数型 (Integer) として宣言し、定数に値 34 を代入します。

Public Const conAge As Integer = 34

定数は、次のいずれかのデータ型、ブール型 (Boolean)、バイト型 (Byte)、整数型 (Integer)、長整数型 (Long)、通貨型 (Currency)、単精度浮動小数点数型 (Single)、倍精度浮動小数点数型 (Double)、日付型 (Date)、文字列型 (String)、またはバリアント型 (Variant) として宣言できます。定数の値はあらかじめ決まっているので、Const ステートメントにデータ型を指定できます。詳細については、Visual Basic ヘルプの「データ型の概要」を参照してください。

1 行のステートメントで複数の定数を宣言できます。データ型を指定するには、定数ごとにデータ型を指定する必要があります。次のステートメントでは、定数 conAge を整数型 (Integer)、定数 conWage を通貨型 (Currency) として宣言します。

Const conAge As Integer = 34, conWage As Currency = 35000


変数の宣言

変数を宣言する場合は、通常、Dim ステートメントを使います。宣言ステートメントをプロシージャ内に配置し、プロシージャ レベル変数を宣言できます。または、宣言セクションのモジュールの先頭に宣言ステートメントを配置し、モジュール レベル変数を宣言することもできます。

次の例は、変数 strName を作成し、文字列型 (String) を指定します。

Dim strName As String

プロシージャ内にこのステートメントがある場合、変数 strName はそのプロシージャ内でのみ使用できます。このステートメントが、モジュールの宣言セクション内にある場合、変数 strName はモジュール内のすべてのプロシージャで使用できますが、プロジェクトの他のモジュールのプロシージャでは使用できません。この変数をプロジェクトのすべてのプロシージャで使用できるようにするには、次の例にのように Public ステートメントを指定します。

Public strName As String

変数の名前付けに関する詳細については、Visual Basic ヘルプの「Visual Basic の名前付け規則」を参照してください。

変数は、次のいずれかのデータ型、ブール型 (Boolean)、バイト型 (Byte)、整数型 (Integer)、長整数型 (Long)、通貨型 (Currency)、単精度浮動小数点数型 (Single)、倍精度浮動小数点数型 (Double)、日付型 (Date)、文字列型 (String) (可変長文字列の場合。固定長文字列の場合は、String * length。)、またはオブジェクト型 (Object) として宣言できます。データ型を指定しないと、バリアント型 (Variant) のデータ型が既定として割り当てられます。Type ステートメントを使って、ユーザー定義型を作成することもできます。データ型の詳細については、Visual Basic ヘルプの「データ型の概要」を参照してください。

1 行のステートメントに複数の変数を宣言できます。データ型を指定する場合は、各変数ごとにデータ型を指定する必要があります。次のステートメントでは、変数 intX、intY、および intZ は、整数型 (Integer) として宣言されます。

Dim intX As Integer, intY As Integer, intZ As Integer

次のステートメントでは、変数 intX と intY は、バリアント型 (Variant) として宣言され、変数 intZ だけが 整数型 (Integer) として宣言されます。

Dim intX, intY, intZ As Integer

宣言ステートメントで変数のデータ型を省略すると、変数は既定のバリアント型 (Variant) となります。

Public ステートメントの使い方

Public ステートメントを使って、パブリック モジュール レベル変数を宣言できます。

Public strName As String

パブリック変数は、プロジェクト内のすべてのプロシージャから使用できます。パブリック変数を標準モジュールまたはクラス モジュールで宣言すると、そのパブリック変数が宣言されているプロジェクトを参照するすべてのプロジェクトでも、その変数を使用できます。

Private ステートメントの使い方

Private ステートメントを使って、プライベート モジュール レベルの変数を宣言できます。

Private MyName As String

プライベート変数は、同じモジュール内のプロシージャのみ使用できます。

メモ   Dim ステートメントをモジュール レベルで使用すると、Private ステートメントと同じ機能をします。Private ステートメントを使用すると、コードの内容がわかりやすくなります。

Static ステートメントの使い方

Dim ステートメントの代わりに Static ステートメントを使用すると、宣言された変数は、モジュールの実行中、値を保持します。

Option Explicit ステートメントの使い方

変数を代入ステートメントで使用するだけで、変数を暗黙的に宣言できます。暗黙的に宣言された変数は、すべてバリアント型 (Variant) になります。バリアント型 (Variant) の変数は、他のデータ型で宣言した変数よりも多くのメモリを必要とします。変数を明示的に、特定のデータ型で宣言する方が、アプリケーションの効率が良くなります。すべての変数を明示的に宣言すると、名前付けの競合によるエラーや入力ミスによるエラーの発生を減らすことができます。

変数の暗黙的な宣言を防ぐには、モジュールの宣言セクションに Option Explicit ステートメントを指定します。Option Explicit ステートメントを使うと、モジュール内のすべての変数の明示的な宣言が強制されます。モジュールに Option Explicit ステートメントが指定されている場合、未宣言の変数名や、誤って記述された変数名が検出されると、コンパイル時エラーが発生します。

Visual Basic プログラミング環境でオプションを設定すると、すべての新規モジュールに対して、Option Explicit ステートメントを自動的に追加することができます。Visual Basic の環境オプションの変更方法については、アプリケーションのマニュアルを参照してください。このオプションは、既に作成したコードに対しては、変更を行わないので注意してください。

メモ   固定長配列と動的配列は明示的に宣言する必要があります。

オブジェクト変数の宣言の自動化

あるアプリケーションを使って、別のアプリケーションのオブジェクトを制御する場合、他のアプリケーションのタイプ ライブラリへの参照を設定する必要があります。参照を設定すると、他のアプリケーション内のオブジェクトの固有オブジェクト型でオブジェクト変数を宣言できます。たとえば、Microsoft Excel タイプ ライブラリへの参照を設定する場合に Microsoft Word を使用しているときは、Microsoft Word 内で Worksheet 型の変数を宣言して Microsoft Excel Worksheet オブジェクトを示すことができます。

別のアプリケーションを使って Microsoft Access のオブジェクトを制御する場合、通常、その固有オブジェクト型でオブジェクト変数を宣言できます。キーワード New を使って、オブジェクトの新しいインスタンスを自動的に作成することもできます。ただし、Microsoft Access のオブジェクトであることを明示しなければならないこともあります。たとえば、オブジェクト変数を宣言して、Microsoft Visual Basic の Form オブジェクト内で Microsoft Access のフォームを示す場合、Microsoft Access の Form オブジェクトと Visual Basic Form オブジェクトを区別する必要があります。次の例のように、変数を宣言するときにタイプ ライブラリ名を指定します。

Dim frmOrders As New Access.Form

アプリケーションによっては、Microsoft Access に固有のオブジェクト型を認識しないものがあります。このようなアプリケーションから Microsoft Access のタイプ ライブラリへの参照を設定する場合は、Microsoft Access のすべてのオブジェクト変数を Object 型として宣言しなければなりません。また、キーワード New を使って、オブジェクトの新しいインスタンスを作成することもできません。次の例は、Microsoft Access のオブジェクト型を認識しないアプリケーションから Microsoft Access の Application オブジェクトのインスタンスを表す変数の宣言方法を示しています。また、このアプリケーションは Application オブジェクトのインスタンスを作成します。

Dim appAccess As Object

Set appAccess = CreateObject("Access.Application")

アプリケーションがどの構文をサポートしているかどうかを確認するには、アプリケーションのマニュアルを参照してください。


プロパティ設定時のコードの実行

同じ名前を共有する Property Let プロシージャ、Property Set プロシージャ、および Property Get プロシージャを作成することができます。これにより、共に関連して動作するプロシージャ グループを作成できます。Property プロシージャで使用した名前は、Sub プロシージャ、Function プロシージャ、変数またはユーザー定義型の名前として使用することはできません。

Property Let ステートメントを使用すると、プロパティの値を設定するプロシージャを作成できます。たとえば、Property プロシージャを使用してフォームのビットマップを反転するプロパティを作成します。次のコードは、Property Let プロシージャを呼び出すために使用する構文です。

Form1.Inverted = True

フォームのビットマップを反転させる処理は、実際には Property Let プロシージャ内で実行されます。

Private IsInverted As Boolean

Property Let Inverted(X As Boolean)

IsInverted = X

If IsInverted Then

...

(statements)

Else

(statements)

End If

End Property

フォーム レベルの変数 IsInverted は、プロパティの設定値を格納します。この変数をキーワード Private で宣言すると、Property Let プロシージャを使った場合に限り、プロパティの設定値を変更できます。Property プロシージャで使う変数には、プロパティと関連していることがすぐにわかる名前を付けてください。

次のコードは、Inverted プロパティの現在の値を返す Property Get プロパティの例です。

Property Get Inverted() As Boolean

Inverted = IsInverted

End Property

Property プロシージャを使用すると、プロパティの値が設定されたときに、処理を簡単に実行することができます。Property プロシージャを使用すると、次の処理を行うことができます。

•	プロパティに値を設定する前に、プロパティ値を確認できます。

•	プロパティ値が設定された後で、新しい値に基づいた処理を実行します。


コードのループ

条件付きステートメントとループ ステートメント (制御構造) を使用すると、判定と処理を繰り返す Visual Basic コードを作成できます。もう 1 つの便利な制御構造、With ステートメントを使用すると、オブジェクトを再指定せずに一連のステートメントを実行できます。

条件付きステートメントによる判別

条件付きステートメントは、条件が真 (True) または偽 ( False) のいずれかを評価し、その結果に応じて、実行する 1 つまたは複数のステートメントを指定します。通常、条件は、比較演算子を使って 1 つの値または変数と他の値とを比較する式になります。

条件付きステートメントの選択

•	If...Then...Else ステートメント : 条件が真 (True) または偽 (False) の場合、分岐します。

•	Select Case ステートメント : 条件セットから分岐先を選択します。

ループでのコードの反復

ループを使用すると、ステートメント グループを繰り返し実行できます。ループには条件が偽 (False) になるまでステートメントを繰り返し実行するもの、または条件が真 (True) になるまで繰り返すものがあります。また、ステートメントを一定の回数繰り返すループや、コレクションの各オブジェクトごとにステートメントを繰り返すループもあります。

ループの選択

•	Do...Loop ステートメント : 条件が真 (True) の間、または真 (True) になるまでループします。

•	For Each...Next ステートメント : コレクションの各オブジェクトごとに、ステートメント グループを繰り返し実行します。

•	For...Next ステートメント : カウンタを使って、ステートメントを指定した回数実行します。

同じオブジェクトに対する複数のステートメントの実行

Visual Basic では、通常、オブジェクトのメソッドの 1 つを実行したり、プロパティの 1 つを変更する前に、そのオブジェクトを指定する必要があります。With ステートメントを使用すると、オブジェクトを一度指定すれば、一連のステートメントすべてに適用できます。

•	With ステートメント : 同じオブジェクトで一連のステートメントを実行します。


For...Next ループの高速化

整数型 (Integer) は、バリアント型 (Variant) よりも使用するメモリが少ないだけでなく、演算処理も少し速くなります。この違いはわずかですが、大量の処理を行うような場合、この差は大きくなります。次に例を示します。

Dim CountFaster As Integer	' 整数型を使用する例。

For CountFaster = 0 to 32766

Next CountFaster

Dim CountSlower As Variant	' バリアント型を使用する例。

For CountSlower = 0 to 32766

Next CountSlower

最初の例は、2 番目の例に比べて少しだけ速く実行されます。ただし、CountFaster の値が 32,767 を超えるとエラーが発生します。この問題を解決するには、CountFaster のデータ型を、実際によりも値の範囲が広い長整数型 (Long) に変更します。一般にサイズの小さなデータ型ほど、演算処理に必要な時間が少なくて済みます。バリアント型 (Variant) は、他のデータ型と比べて演算処理速度が少し遅くなります。


引数の効率的な引き渡し

すべての引数は、特に指定しない限り、参照渡しでプロシージャに引き渡されます。参照渡しは、引数のデータ型に関係なく、すべての引数が渡されるときの所要時間およびプロシージャ内のメモリ領域 (4 バイト) が同じであるため、効率的です。

プロシージャを宣言するときにキーワード ByVal を指定すると、引数を値渡しで渡すことができます。値で渡される引数は、引数のデータ型に応じて、プロシージャ内で 2 ～ 16 バイトのメモリ領域を使用します。データ型が大きいほど、値渡しに要する時間が少し長くなります。このため、一般に文字列型 (String) とバリアント型 (Variant) では値渡しを使用せず、参照渡しを使用します。

引数を値渡しにすると、元の変数のコピーが渡されます。プロシージャ内で引数の変更を行っても、元の変数には反映されません。次に例を示します。

Function Factorial (ByVal MyVar As Integer)	' 関数を宣言します。

MyVar = MyVar - 1

If MyVar = 0 Then

Factorial = 1

Exit Function

End If

Factorial = Factorial(MyVar) * (MyVar + 1)

End Function

' 変数 S で Factorial を呼び出します。

S = 5

Print Factorial(S)	' 120 (5 の階乗) が表示されます。

Print S	' 5 が表示されます。

関数を宣言するときにキーワード ByVal を指定しなければ、上の 2 つの Print ステートメントでは、それぞれ 1 と 0 が表示されます。これは、MyVar が変数 S を参照し、変数 S は 0 になるまで 1 ずつ減算されるからです。

キーワード ByVal によって引数がコピーされるので、上の Factorial 関数にバリアント型 (Variant) を引き渡すことができます。参照渡しでバリアント型 (Variant) を別のデータ型の引数に渡すことはできません。


関数からの文字列の取得

関数によっては 2 つの形式を持つものがあります。バリアント型 (Variant) を返す形式と、文字列型 (String) を返す形式です。バリアント型 (Variant) を返す形式は、異なるデータ型への変換が自動的に行われるので便利です。この形式を使用すると、Null 値を式で渡すことができます。文字列型 (String) を返す形式は、使用するメモリが少ないため、より効率的です。

次の場合は、文字列型 (String) を返す形式を使用することを検討してください。

•	プログラムが大きく、多くの変数を使用する場合。

•	データをランダム アクセス ファイルに直接書き込む場合。

次の関数は関数名にドル記号 ($) を追加すると、文字列型 (String) の値を返します。これらの関数は、ドル記号を付けずに使用すると、バリアント型 (Variant) の値を返します。使用方法と構文は、文字列型 (String) もバリアント型 (Variant) も同じです。

Chr$	ChrB$	*Command$
CurDir$	Date$	Dir$
Error$	Format$	Hex$
Input$	InputB$	LCase$
Left$	LeftB$	LTrim$
Mid$	MidB$	Oct$
Right$	RightB$	RTrim$
Space$	Str$	String$
Time$	Trim$	UCase$
* すべてのアプリケーションで使用できるわけではありません。


条件付きコンパイルの概要

条件付きコンパイルを使用すると、コード ブロックの特定の部分を選択してコンパイルできます。たとえば、同じプログラミング タスクへの各種の操作速度を比較するステートメントをデバッグしたり、各種言語用にアプリケーションをローカライズすることができます。

条件付きコンパイラ定数は、#Const ディレクティブでコードに宣言し、#If...Then...#Else ディレクティブで条件付きでコンパイルされるコード ブロックを示します。次の例は、変数 conDebug の値を基に、デバッグを行うためのコードまたは実際に動作するコードを実行します。

' 宣言セクションでパブリックなコンパイル定数を宣言します。

#Const conDebug = 1

Sub SelectiveExecution()

#If conDebug = 1 Then

.	' デバッグしながらコードを実行します。

.

.

#Else

.	' 通常のコードを実行します。

.

.

#End If

End Sub


変数の有効期間の概要

変数が値を保持する期間を、変数の有効期間と呼びます。変数の値が有効期間中に変更されることもありますが、変数は何らかの値を保持します。変数が適用範囲外になると、値を失います。

プロシージャの実行が開始されるとき、すべての変数が初期化されます。数値変数は 0、可変長文字列は長さ 0 の文字列 ("")、固定長文字列は ASCII 文字コード 0、または Chr(0) で表される文字で初期化されます。バリアント型 (Variant) 変数は、Empty 値で初期化されます。ユーザー定義型変数の各要素は、別々の変数として個別に初期化されます。

オブジェクト変数を宣言すると、メモリ内の領域は確保されますが、値は Set ステートメントを使ってオブジェクトへの参照が代入されるまで、Nothing が設定されています。

コードの実行中に変数の値が変更されない場合、適用範囲外になるまで初期値が保持されます。

Dim ステートメントで宣言されるプロシージャ レベルの変数は、プロシージャの実行が終了するまで値を保持します。プロシージャが他のプロシージャを呼び出す場合、それらのプロシージャが実行されている間、変数は値を保持します。

プロシージャ レベルの変数をキーワード Static で宣言すると、コードがモジュールで実行されている限り、変数は値を保持します。すべてのコードの実行が終了すると、変数は適用範囲と値を失います。その有効期間は、モジュール レベル変数の有効期間と同じです。

モジュール レベルの変数は、静的変数とは異なります。標準モジュールまたはクラス モジュールでは、コードの実行を停止するまで、モジュール レベルの変数は値を保持します。クラス モジュールでは、クラスのインスタンスが存在する限り、値を保持します。モジュール レベルの変数は、値がリセットされるまでメモリ リソースを消費するので、必要な場合のみ使用することをお勧めします。

Sub ステートメントまたは Function ステートメントの前にキーワード Static を指定すると、そのプロシージャのすべてのプロシージャ レベル変数の値は、呼び出しの間保持されます。


名前付き引数と省略可能な引数の概要

Sub プロシージャまたは Function プロシージャを呼び出すときは、引数をプロシージャの構文で指定されている定義位置に正しい順序で指定するか、構文上の順序とは無関係に、引数の名前を記述して指定します。

たとえば、次の Sub プロシージャは、3 つの引数を受け取ります。

Sub PassArgs(strName As String, intAge As Integer, dteBirth As Date)

Debug.Print strName, intAge, dteBirth

End Sub

次の例のように、各引数をカンマで区切り、構文どおりの正しい位置に指定して、このプロシージャを呼び出すことができます。

PassArgs "Mary", 26, #69-2-21#

また、名前付き引数をそれぞれカンマで区切って、このプロシージャを呼び出すこともできます。

PassArgs intAge:=26, dteBirth:=#69-2-21#, strName:="Mary"

名前付き引数に値を代入するには、引数名、コロンと等号 (:=)、引数に代入する値の順で記述します。

名前付き引数は、省略可能な引数を持つプロシージャを呼び出すときに便利です。名前付き引数を使用すると、省略する引数を示すためにカンマを入れる必要がなくなります。名前付き引数を使用すると、どの引数を渡し、どの引数を省略したかを簡単に知ることができます。

プロシージャの定義では、省略可能な引数の前にキーワード Optional を付けます。プロシージャを定義するときに、省略可能な引数に既定値を指定することもできます。次にコード例を示します。

Sub OptionalArgs(strState As String, Optional strCountry As String = "USA")

. . .

End Sub

省略可能な引数を使ってプロシージャを呼び出す場合、省略可能な引数を指定するかどうかを選択できます。省略可能な引数を指定しない場合、その引数が既定値を持っていれば、その値が適用されます。既定値を持たない省略可能な引数を指定した場合は、指定したとおりの変数となります。

次のプロシージャには、省略可能な引数 varCountry 変数が含まれています。IsMissing 関数は、省略可能な引数がプロシージャに渡されたかどうかを調べます。

Sub OptionalArgs(strState As String, Optional intRegion As Integer, _

Optional strCountry As String = "USA")

If IsMissing(intRegion) And IsMissing(strCountry) Then

Debug.Print strState

ElseIf IsMissing(strCountry) Then

Debug.Print strState, intRegion

ElseIf IsMissing(intRegion) Then

Debug.Print strState, strCountry

Else

Debug.Print strState, intRegion, strCountry

End If

End Sub

次の例のように、名前付き引数を使って、このプロシージャを呼び出すことができます。

OptionalArgs strCountry:="USA", strState:="MD"

OptionalArgs strState:= "MD", intRegion:=5


オブジェクト、プロパティ、メソッド、およびイベントの概要

オブジェクトは、ワークシート、セル、グラフ、フォーム、レポートなど、アプリケーションの要素を表します。Visual Basic コードでは、オブジェクトのメソッドの 1 つを使ったり、プロパティのいずれかの値を変更する前に、対象となるオブジェクトを識別する必要があります。

コレクションは、通常、中に複数の異なる種類のオブジェクトを含むオブジェクトです。ただし、常に異なる種類のオブジェクトを含んでいるとは限りません。たとえば、Microsoft Excel では、Workbooks コレクションは開いているすべての Workbook オブジェクトを含みます。Visual Basic では、Forms コレクションはアプリケーションのすべての Form オブジェクトを含みます。

コレクションの要素は、数値または名前で識別できます。たとえば、次のプロシージャでは、Workbooks(1) は、1 番目の開いている Workbook オブジェクトを識別します。

Sub CloseFirst()

Workbooks(1).Close

End Sub

次のプロシージャは、文字列として指定した名前を使って Form オブジェクトを識別します。

Sub CloseForm()

Forms("MyForm.frm").Close

End Sub

オブジェクトが共通のメソッドを共有している場合、オブジェクトのコレクション全体を処理することもできます。たとえば、次のプロシージャは、開いているフォームをすべて閉じます。

Sub CloseAll()

Forms.Close

End Sub

メソッドを使うと、コントロール内のオブジェクトが行う動作を操作することができます。たとえば、次の例で示す Add メソッドは、コンボ ボックスに新しい項目を追加するための、ComboBox オブジェクトのメソッドです。

次のプロシージャは、Add メソッドを使ってコンボ ボックス (ComboBox) コントロールに新しい項目を追加します。

Sub AddEntry(newEntry as String)

Combo1.Add newEntry

End Sub

プロパティは、サイズ、色、画面の位置などオブジェクトの特徴や、使用可能または表示/非表示などの動作を定義する属性です。オブジェクトの特徴を変更するには、そのプロパティ値を変更します。

プロパティに値を設定するには、対象となるオブジェクトの後ろに、ピリオド、プロパティ名、等号 (=)、新しいプロパティ値の順で記述します。たとえば、次のプロシージャは、Caption プロパティを設定して Visual Basic フォームのキャプションを変更します。

Sub ChangeName(newTitle)

myForm.Caption = newTitle

End Sub

プロパティによっては、設定できないものがあります。各プロパティのヘルプ トピックを参照すると、そのプロパティが値の取得および設定が共に可能であるか、取得のみ可能であるか、または設定のみ可能であるかがわかります。

オブジェクトのプロパティのいずれかの値を取得することで、オブジェクトに関する情報を取得できます。次のプロシージャは、メッセージ ボックスを使って、現在アクティブなフォームの一番上に配置されているタイトルを表示します。

Sub GetFormName()

formName = Screen.ActiveForm.Caption

MsgBox formName

End Sub

マウスのクリックや、キーを押すなど、オブジェクトで認識される動作をイベントと呼びます。これらのイベントに対し、どのような処理を実行するかをコードで記述できます。ユーザーの操作やプログラム コードの結果に対してイベントを発生させたり、システムでイベントを発生させることもできます。

オブジェクトの取得

すべてのアプリケーションは、それに含まれるオブジェクトを返す方法を備えています。ただし、その方法はオブジェクトにより異なるため、アプリケーションで使っているオブジェクトまたはコレクションのヘルプ トピックを参照し、オブジェクトを返す方法を確認してください。


オートメーションの概要

オートメーション (以前のバージョンでは OLE オートメーション) は、コンポーネント オブジェクト モデル (COM) の機能で、開発ツール、マクロ言語、およびオートメーションをサポートする他のアプリケーションに対してオブジェクトを公開するために、アプリケーションが使用する業界標準の技術です。たとえば、表計算アプリケーションでは、ワークシート、グラフ、セル、セル範囲などがそれぞれ異なる型のオブジェクトとして公開されます。ワード プロセッサでは、アプリケーション、文書、段落、文、ブックマーク、選択範囲などのオブジェクトが公開されます。

アプリケーションがオートメーションをサポートしている場合、アプリケーションが公開するオブジェクトを Visual Basic で操作できます。Visual Basic でオブジェクトを操作するには、オブジェクトに対してメソッドを使用したり、オブジェクトのプロパティ値の取得または設定を行います。たとえば、MyObj という名前のオートメーション オブジェクトを作成し、次のようなコードでこのオブジェクトを操作することができます。

MyObj.Insert "Hello, world."	' 文字列を挿入します。

MyObj.Bold = True	' 書式を設定します。

If Mac = True	' Check your platform constant

MyObj.SaveAs  "HD:\WORDPROC\DOCS\TESTOBJ.DOC"	' オブジェクトを保存します (Macintosh の場合)。

Else

MyObj.SaveAs  "C:\WORDPROC\DOCS\TESTOBJ.DOC"	' オブジェクトを保存します (Windows の場合)。

オートメーション オブジェクトを利用する関数は、次のとおりです。

関数	内容
CreateObject	指定した種類の新しいオブジェクトを作成します。
GetObject	ファイルからオブジェクトを取得します。
アプリケーションで使用できるプロパティやメソッドの詳細については、アプリケーションのマニュアルを参照してください。アプリケーションで利用できるオブジェクト、関数、プロパティ、メソッドは、通常、アプリケーションのオブジェクト ライブラリに定義されます。


パラメータ配列の概要

パラメータ配列を使用すると、引数の配列をプロシージャに渡すことができます。プロシージャを定義するときに、配列内の要素数が不明でも問題ありません。

パラメータ配列を示すには、キーワード ParamArray を使います。この配列は、バリアント型 (Variant) の配列として宣言し、プロシージャの定義では、最後の引数として指定する必要があります。

次の例は、パラメータ配列を持つプロシージャの定義方法を示しています。

Sub AnyNumberArgs(strName As String, ParamArray intScores() As Variant)

Dim intI As Integer

Debug.Print strName; "    点"

' UBound 関数を使用して、配列の上限を決定します。

For intI = 0 To UBound(intScores())

Debug.Print "          "; intScores(intI)

Next intI

End Sub

次の例は、このプロシージャの呼び出し方法を示しています。

AnyNumberArgs "Jamie", 10, 26, 32, 15, 22, 24, 16

AnyNumberArgs "Kelly", "高", "低", "平均", "高"


適用範囲と参照可能範囲の概要

別のプロシージャで使用される変数、定数、またはプロシージャの有効な範囲を、適用範囲と呼びます。適用範囲には、3 つのレベル、プロシージャ レベル、プライベート モジュール レベル、およびパブリック モジュール レベルがあります。

変数を宣言する場合、その適用範囲を決定します。異なる適用範囲を持つ変数間で名前付けの競合が発生しないように、すべての変数を明示的に宣言することをお勧めします。

プロシージャ レベルの適用範囲の定義

プロシージャ内で定義された変数や定数は、そのプロシージャの外から、参照できません。変数の宣言を含むプロシージャだけが、その変数を使用できます。次の例では、最初のプロシージャは、文字列を含むメッセージ ボックスを表示します。変数 strMsg は、最初のプロシージャのローカル変数であるため、2 番目のプロシージャは、空白のメッセージ ボックスを表示します。

Sub LocalVariable()

Dim strMsg As String

strMsg = "この変数は、このプロシージャ以外では使用できません。"

MsgBox strMsg

End Sub

Sub OutsideScope()

MsgBox strMsg

End Sub

プライベート モジュール レベルの適用範囲の定義

モジュール レベルの変数や定数は、モジュールの宣言セクションで定義できます。モジュール レベルの変数は、パブリック変数またはプライベート変数として設定できます。パブリック変数は、プロジェクト内のすべてのモジュールのすべてのプロシージャから使用できます。プライベート変数は、そのモジュール内のプロシージャでのみ使用できます。特に指定しない限り、宣言セクションで Dim ステートメントを使って宣言された変数は、プライベートな適用範囲を持ちます。変数の前にキーワード Private を指定すると、コード内での適用範囲を明確にすることができます。

次の例では、文字列変数 strMsg は、モジュール内で定義されたどのプロシージャでも使用できます。2 番目のプロシージャを呼び出すと、ダイアログ ボックスの文字列変数 strMsg の内容が表示されます。

' モジュールの宣言セクションに次のコードを追加します。

Private strMsg sAs String

Sub InitializePrivateVariable()

strMsg = "この変数は、このモジュール以外では使用できません。"

End Sub

Sub UsePrivateVariable()

MsgBox strMsg

End Sub

メモ   標準モジュールまたはクラス モジュールのパブリック プロシージャは、どの参照元プロジェクトでも使用できます。モジュール内のすべてのプロシージャの適用範囲を現在のプロジェクト内に制限するには、モジュールの宣言セクションに Option Private Module ステートメントを追加します。パブリック変数とプロシージャは、現在のプロジェクトの他のプロシージャでも使用できますが、参照元プロジェクトでは使用できません。

パブリック モジュール レベルの適用範囲の定義

モジュール レベルの変数をパブリックとして宣言すると、プロジェクトのすべてのプロシージャで使用できます。次の例では、文字列変数 strMsg はプロジェクトのすべてのモジュールのすべてプロシージャから使用できます。

' モジュールの宣言セクションに含めます。

Public strMsg As String

既定では、イベント プロシージャ以外のすべてプロシージャが、パブリック プロシージャになります。Visual Basic でイベント プロシージャを作成すると、プロシージャの宣言の前にキーワード Private が自動的に挿入されます。イベント プロシージャ以外のプロシージャをパブリック プロシージャにしたくない場合は、そのプロシージャをキーワード Private を使って、明示的に宣言しなければなりません。

参照元プロジェクトから、標準モジュールまたはクラス モジュールで定義したパブリックなプロシージャ、変数、および定数を使用できます。ただし、その前にそれらを定義しているプロジェクトへの参照を設定する必要があります。

標準モジュールまたはクラス モジュール以外のフォーム モジュールやレポート モジュールなどのモジュールは、常駐するプロジェクトに対してプライベートであるため、そこで定義されたパブリックなプロシージャ、変数、および定数は、参照元プロジェクトでは使用できません。


バリアント型 (Variant)の概要

定数、変数、または引数を宣言するときに、データ型を指定しないと、バリアント型 (Variant) が自動的に設定されます。バリアント型 (Variant) として宣言した変数には、文字列、日付、時間、ブール値、または数値を格納することができます。また、それらの値は自動的に変換されます。数値をバリアント型 (Variant) で宣言した場合は、16 バイトのメモリを必要とし、他のデータ型を明示的に指定した変数よりも、アクセス速度がやや遅くなります。メモリの使用量については、大きなプロシージャまたは複雑なモジュールでは、特に避ける必要があります。定数を宣言する場合にバリアント型 (Variant) を使用することは、ほとんどありません。文字列をバリアント型 (Variant) で宣言した場合は、文字列のサイズに 22 バイトを足したメモリを必要とします。

次のステートメントは、バリアント型 (Variant) の変数を作成します。

Dim myVar

Dim yourVar As Variant

theVar = "これはテキストです。"

最後のステートメントは、変数 theVar を明示的に宣言せずに、暗黙的または自動的に変数を宣言します。暗黙的に宣言される変数は、バリアント型 (Variant) として指定されます。

ヒント   変数または引数にあるデータ型を指定し、その後、誤ったデータ型を使用すると、データ型に関するエラーが生じます。データ型に関するエラーの発生を防ぐには、暗黙的な変数 (バリアント型 (Variant)) だけを使用するか、または変数をすべて明示的に宣言し、データ型を指定します。後の方法を使用することをお勧めします。


Visual Basic の構文の概要

Visual Basic ヘルプ トピックのメソッド、ステートメント、または関数の構文は、メソッド、ステートメント、または関数を正しく使用するために必要なすべての要素を示しています。トピックの例では、最も一般的な構文要素の参照方法を示しています。

Activate メソッドの構文

object.Activate

Activate メソッドの構文の斜体文字 "object" は、ユーザーが指定する情報のプレースホルダです。この場合は、オブジェクトを返すコードを指定します。太字の文字は、記述どおりに入力しなければなりません。たとえば、次のプロシージャは、現在作業中の文書で 2 つ目のウィンドウをアクティブにします。

Sub MakeActive()

Windows(2).Activate

End Sub

MsgBox 関数の構文

MsgBox(prompt[, buttons] [, title] [, helpfile, context])

MsgBox 関数の構文の中の各斜体文字は、関数の名前付き引数です。角かっこで囲まれた引数は、省略可能です。Visual Basic のコードを記述するときには、この角かっこを付けないでください。この MsgBox 関数の構文で必ず指定しなければならない引数は、prompt プロンプトの文字列だけです。

関数やメソッドの引数は、位置または名前によってコードに指定します。引数を位置で指定するには、構文で決められた指定順序に従い、次の例のように各引数をカンマで区切って指定します。

MsgBox "答えは正解です。",0,"Answer Box"

引数を名前で指定するには、引数名、コロンと等号 (:=)、引数に代入する値の順で記述します。名前付き引数の場合、次の例のように任意の順序で指定できます。

MsgBox Title:="解答ボックス", Prompt:="答えは正解です。"

関数およびいくつかのメソッドの構文では、引数をかっこで囲んで指定します。こうした関数やメソッドは値を返すので、引数をかっこで囲み、値を変数に代入する必要があります。戻り値を無視したり、引数を渡さない場合は、引数をかっこで囲まないでください。値を返さないメソッドは、引数をかっこで囲む必要はありません。この表記規則は、位置で指定する引数または名前付き引数のどちらを使用する場合にも適用されます。

次の例では、MsgBox 関数は、変数 myVar に格納される選択ボタンの番号を返します。戻り値が使用されるため、引数をかっこで囲む必要があります。別のメッセージ ボックスは、変数の値を表示します。

Sub Question()

myVar = MsgBox(Prompt:="私は自分の仕事を楽しんでいます。", _

Title:="解答ボックス", Buttons:="4")

MsgBox myVar

End Sub

Option ステートメントの構文

Option Compare {Binary | Text | Database}

Option Compare ステートメントの構文では、中かっこ ({}) と垂直線 (|) によって 3 つの項目から必ず 1 つを選択しなければならないことを示します。Visual Basic のコードを記述するときには、この中かっこを付けないでください。たとえば、次のステートメントは、モジュール内の文字列を大文字小文字を区別しない並べ替え順序で比較することを指定します。

Option Compare Text

Dim ステートメントの構文

Dim varname[([subscripts])] [As type] [, varname[([subscripts])] [As type]] . . .

Dim ステートメント構文では、Dim は必ず指定しなければならないキーワードです。要素の中で必ず指定しなければならない要素は、varname (変数名) だけです。たとえば、次のステートメントは 3 つの変数 myVar、nextVar、および thirdVar を作成します。これらの変数は、自動的にバリアント型 (Variant) 変数として宣言されます。

Dim myVar, nextVar, thirdVar

次の例は、変数を文字列型 (String) の変数として宣言します。特定のデータ型を指定すると、メモリを節約できます。また、コード中のエラーも見つけやすくなります。

Dim myAnswer As String

1 つのステートメントで複数の変数を宣言するには、各変数のデータ型を指定します。データ型を指定しない変数は、自動的にバリアント型 (Variant) として宣言されます。

Dim x As Integer, y As Integer, z As Integer

次のステートメントでは、変数 x と変数 y は、バリアント型 (Variant) として宣言されます。変数 z だけが、整数型 (Integer) として指定されています。

Dim x, y, z As Integer

配列変数を宣言する場合は、かっこを付ける必要があります。インデックス番号は省略可能です。次のステートメントは、動的配列 myArray を宣言します。

Dim myArray()


配列の使い方

配列を宣言すると、同じデータ型の 1 組の値を処理できます。通常の変数は、1 つの値を 1 つの区画に格納していますが、配列は、値を格納するために多くの区画を持つ 1 つの変数です。配列が格納しているすべての値を参照する場合は、配列全体を参照できます。また、配列の個々の要素を参照することもできます。

たとえば、一年間の毎日の支出を記録する場合、365 個の変数を宣言する代わりに、365 の要素を持つ 1 つの配列変数を宣言することができます。配列の各要素には、1 つの値を持ちます。次のステートメントは、365 個の要素を持つ配列変数 curExpense を宣言します。特に指定しない限り、配列には 0 から始まるインデックス番号が付けられます。したがって、配列に指定するインデックスの最大値は、365 ではなく 364 となります。

Dim curExpense(364) As Currency

各要素の値を設定するには、要素のインデックス番号を指定します。次の例は、配列の各要素に初期値 20 を代入します。

Sub FillArray()

Dim curExpense(364) As Currency

Dim intI As Integer

For intI = 0 to 364

curExpense(intI) = 20

Next

End Sub

インデックス番号の最小値の変更

モジュールの先頭で Option Base ステートメントを使用すると、最初の要素の既定値を 0 から 1 に変更することができます。次の例では、Option Base ステートメントを使って、配列のインデックス番号の最小値を変更します。この Dim ステートメントは、365 の要素を持つ配列変数 curExpense を宣言します。

Option Base 1

Dim curExpense(365) As Currency

次の例のように To 節を使って配列のインデックス番号の最小値を明示的に設定することもできます。

Dim curExpense(1 To 365) As Currency

Dim strWeekday(7 To 13) As String

バリアント型 (Variant) の値の配列への格納

バリアント型 (Variant) の値の配列を作成するには、次に示す 2 つの方法があります。1 つ目の方法は、次の例のようにバリアント型 (Variant) の配列を宣言する方法です。

Dim varData(3) As Variant

varData(0) = "Claudia Bendel"

varData(1) = "4242 Maple Blvd"

varData(2) = 38

varData(3) = Format("06-09-1952", "General Date")

もう 1 つの方法は、次の例のように Array 関数で返される配列をバリアント型 (Variant) 変数に代入する方法です。

Dim varData As Variant

varData = Array("Ron Bendel", "4242 Maple Blvd", 38, _

Format("06-09-1952", "General Date"))

どちらの方法で配列を作成しても、バリアント型 (Variant) の値の配列の要素を識別します。たとえば、次のステートメントは、前の 2 つの例のどちらにも追加できます。

MsgBox varData(0) & " に関するデータを記録しました。"

多次元配列の使い方

Visual Basic では、最大 60 次元までの配列を宣言することができます。たとえば次のステートメントは、2 次元の 5 ｘ 10 の配列を宣言します。

Dim sngMulti(1 To 5, 1 To 10) As Single

配列を行列とすると、最初の引数は行、2 番目の引数は列を表します。

多次元の配列を処理するには、ネストさせた For...Next ステートメントを使います。次のプロシージャでは、単精度浮動小数点数型 (Single) の値を持つ 2 次元の配列を指定します。

Sub FillArrayMulti()

Dim intI As Integer, intJ As Integer

Dim sngMulti(1 To 5, 1 To 10) As Single

' 配列に値を格納します。

For intI = 1 To 5

For intJ = 1 To 10

sngMulti(intI, intJ) = intI * intJ

Debug.Print sngMulti(intI, intJ)

Next intJ

Next intI

End Sub


定数の使い方

プログラムの中で同じ値を何度も使うことがあります。また、記憶しておくことが困難な数値や、使用目的が分かりにくい値がコード上で必要になることもあります。このような場合、定数を使用すると、コードが読みやすくなり、保守も容易になります。定数とは、数値や文字列の代わりに使用される、意味を持たせた名前のことです。定数は変数と異なり、値を変更したり、新しい値を代入したりすることはできません。

定数には 3 種類あります。

•	組み込み定数 (システム定義の定数) は、アプリケーションやコントロールで定義されている定数です。Microsoft Access、Microsoft Excel、Microsoft Project, および Microsoft Word など、オブジェクト ライブラリを提供する他のアプリケーションでも、各種の定数が定義されており、オブジェクト、メソッド、プロパティで使用できます。オブジェクト ブラウザでは、それぞれのオブジェクト ライブラリによって提供されている定数の一覧を表示できます。

Visual Basic の定数は、Visual Basic (VB) ライブラリ、Visual Basic for Applications (VBA) ライブラリ、および Data Access Object (DAO) ライブラリに一覧表示されます。

メモ   Visual Basic では、Visual Basic または Visual Basic for Applications の以前のバージョンで作成されたアプリケーションで使用した定数を引き続き正しく認識します。オブジェクト ブラウザ中に一覧表示される定数は、アプリケーションで宣言する必要はありません。

•	記号定数またはユーザー定義の定数は、Const ステートメントを使って宣言します。

•	条件コンパイル定数は、#Const ステートメントを使って宣言します。

従来の Visual Basic アプリケーションでは、定数名を大文字の英字とアンダースコアを組み合わせて表していました。次に例を示します。

TILE_HORIZONTAL

複数のオブジェクト ライブラリで異なる値を表す定数に、同じ名前を使ってしまうことを防ぐために、組み込み定数は修飾されています。定数の名前を修飾する方法は 2 つあります。

•	プリフィックスを付けます。

•	ライブラリへの参照を使用します。

プリフィックスを使用した定数の修飾

オブジェクトに表示される組み込み定数は、大文字と小文字を混在させた名前を使用し、定数名の先頭に、その定数を定義するオブジェクト ライブラリを示す 2 文字のプリフィックスを付けています。Visual Basic for Applications のオブジェクト ライブラリで定義されている組み込み定数には "vb"、Microsoft Excel のオブジェクト ライブラリで定義される定数には "xl" というプリフィックスがそれぞれ付いています。カスタム コントロールのプリフィックスは、次のようにタイプ ライブラリによって異なります。

•	vbTileHorizontal

•	xlDialogBorder

ライブラリへの参照を使用した定数の修飾

次の構文を使って定数への参照を修飾します。

[libname.] [modulename.]constname

定数を修飾するための構文は、次の指定項目から構成されます。

指定項目	内容
libname	省略可能です。その定数を定義しているタイプ ライブラリの名前を指定します。多くのカスタム コントロール (Macintosh では利用できません)では、タイプ ライブラリの名前はコントロールのクラス名でもあります。コントロールのクラス名が不明な場合は、マウス ポインタをツールボックスのコントロール上に移動させると、クラス名がツール ヒントとして表示されます。
modulename	省略可能です。その定数を定義するタイプ ライブラリ内のモジュールの名前を指定します。オブジェクト ブラウザを使ってモジュールの名前を検索できます。
constname	タイプ ライブラリ内でその定数に定義された名前を指定します。
たとえば、次のように指定します。

Threed.LeftJustify


データ型の効率的な使い方

データ型の指定を省略した変数には、バリアント型 (Variant) が割り当てられます。バリアント型 (Variant) を使用するとプログラムの作成は簡単になりますが、最も効率的に使用できるデータ型とは言えません。

次のような場合には、特定のデータ型の使用を避ける必要があります。

•	プログラムが大きくて、多くの変数を使う場合。

•	プログラムをできる限り高速で、実行する必要がある場合。

•	データをランダム アクセス ファイルに直接書き込む場合。

バリアント型 (Variant) のほかに、バイト型 (Byte)、ブール型 (Boolean)、整数型 (Integer)、長整数型 (Long)、単精度浮動小数点数型 (Single)、倍精度浮動小数点数型 (Double)、通貨型 (Currency)、小数点型 (Decimal)、日付型 (Date)、オブジェクト型 (Object)、文字列型 (String) のデータ型がサポートされています。次の例のように特定のデータ型の変数を宣言するには、Dim ステートメントを使います。

Dim X As Integer

このステートメントは、変数 X が -32,768 ～ 32,767 の範囲の整数であることを宣言します。変数 X にこの範囲外の数値を設定しようとすると、エラーが発生します。変数 X に小数の値を設定しようとすると、その数値は丸められます。たとえば、次の例のようになります。

X = 32768	' エラーが発生します。

X = 5.9	' x には 6 が設定されます。


Do...Loop ステートメントの使い方

Do...Loop ステートメントを使用すると、ステートメント ブロックを繰り返し実行できます。ステートメントは条件が真 (True) である間、または条件が真 (True) になるまで、繰り返し実行されます。

ステートメントの繰り返し - 条件が真 (True) の間

キーワード While を使って、Do...Loop ステートメントの条件を調べる方法には 2 つあります。ループに入る前に条件を調べる方法と、少なくとも 1 回はループを実行した後で条件を調べる方法があります。

ChkFirstWhile プロシージャの中で変数 myNum の値を 20 から 9 に変えて設定した場合、ループ内部のステートメントは 1 回も実行されません。ChkLastWhile プロシージャの中で、条件が既に偽 (False) の場合、ループ内部のステートメントを 1 回だけ実行します。

Sub ChkFirstWhile()

counter = 0

myNum = 20

Do While myNum > 10

myNum = myNum - 1

counter = counter + 1

Loop

MsgBox "このループは " & counter & " 回繰り返されました。"

End Sub

Sub ChkLastWhile()

counter = 0

myNum = 9

Do

myNum = myNum - 1

counter = counter + 1

Loop While myNum > 10

MsgBox "このループは " & counter & " 回繰り返されました。"

End Sub

ステートメントの繰り返し - 条件が真 (True) になるまで

キーワード Until を使って、Do...Loop ステートメントを調べる方法には 2 つあります。ループに入る前に条件を調べる方法 (ChkFirstUntil プロシージャ) と、少なくとも 1 回はループを実行した後で条件を調べる方法 (ChkLastUntil プロシージャ) があります。条件が偽 (False) である間、ループが続行されます。

Sub ChkFirstUntil()

counter = 0

myNum = 20

Do Until myNum = 10

myNum = myNum - 1

counter = counter + 1

Loop

MsgBox "このループは " & counter & " 回繰り返されました。"

End Sub

Sub ChkLastUntil()

counter = 0

myNum = 1

Do

myNum = myNum + 1

counter = counter + 1

Loop Until myNum = 10

MsgBox "このループは " & counter & " 回繰り返されました。"

End Sub

ループ内での Do...Loop ステートメントの終了

Do...Loop ステートメントを終了するには、Exit Do ステートメントを使います。無限ループを避けるためなど、ある条件でのみ処理を終了させたい場合には、If...Then...Else ステートメントの真 (True) のステートメント ブロックの中で Exit Do ステートメントを使います。条件が偽 (False) の場合は、通常どおりループを実行します。

次の例では、変数 myNum に無限ループを発生させる値が代入されています。If...Then...Else ステートメントはこの条件を調べ、プログラムの実行を終了し、無限ループから抜け出します。

Sub ExitExample()

counter = 0

myNum = 9

Do Until myNum = 10

myNum = myNum - 1

counter = counter + 1

If myNum < 10 Then Exit Do

Loop

MsgBox "このループは " & counter & " 回繰り返されました。"

End Sub

メモ   無限ループを停止するには、Esc キーまたは Ctrl + Break キーを押します。


For...Next ステートメントの使い方

For...Next ステートメントは、指定した回数分のステートメント ブロックを実行するときに使います。For ループでは、繰り返したループに応じて値が増減するカウンタ変数が使われます。

次のプロシージャは、コンピュータの警告音を 50 回に設定します。For ステートメントには、カウンタ変数 x と、その開始値および終了値を指定しています。Next ステートメントは、カウンタ変数を 1 ずつ増加させます。

Sub Beeps()

For x = 1 To 50

Beep

Next x

End Sub

キーワード Step を使用すると、指定した値でカウンタ変数を増減できます。次の例では、ループを繰り返すごとにカウンタ変数 j は 2 ずつ加算されます。ループが終了すると、変数 total は 2、4、6、8、および 10 を合計した値になります。

Sub TwosTotal()

For j = 2 To 10 Step 2

total = total + j

Next j

MsgBox "合計値 " & total

End Sub

カウンタ変数を減少させるには、キーワード Step に負の値を使います。その場合は、開始値より小さい値を終了値に指定しなければなりません。次の例では、カウンタ変数 myNum は、ループを繰り返すごとに 2 ずつ減算されます。ループが終了すると、変数 total は 16、14、12、10、8、6、4、および 2 を合計した値になります。

Sub NewTotal()

For myNum = 16 To 2 Step -2

total = total + myNum

Next myNum

MsgBox "合計値 " & total

End Sub

メモ   Next ステートメントの後にカウンタ変数名を指定する必要はありません。前の例では、わかりやすくするためにカウンタ変数名を指定しています。

Exit For ステートメントを使用すると、カウンタが終了値に達する前に、For...Next ステートメントを終了できます。たとえば、エラーが発生する場合、特定のエラーをチェックするために、If...Then...Else ステートメントまたは Select Case ステートメントの真 (True) のステートメント ブロックで、Exit For ステートメントを使います。エラーが発生せず、If...Then...Else ステートメントが偽 (False) の場合は、通常どおりループを実行します。


For Each...Next ステートメントの使い方

For Each...Next ステートメントは、コレクションの各オブジェクトまたは配列の各要素に対して、一連のステートメント ブロックを繰り返し実行します。Visual Basic では、ループを実行するごとに、自動的に変数を設定します。たとえば、次のプロシージャは、実行中のプロシージャに含まれるフォームを除き、すべてのフォームを閉じます。

Sub CloseForms()

For Each frm In Application.Forms

If frm.Caption <> Screen. ActiveForm.Caption Then frm.Close

Next

End Sub

次のコードは、配列の各要素をループし、各要素の値をインデックス変数 I に設定します。

Dim TestArray(10) As Integer, I As Variant

For Each I In TestArray

TestArray(I) = I

Next I

セルの範囲内でのループの実行

For Each...Next ループを使って指定した範囲のセルをループします。次のプロシージャは、Sheet1 の A1:D10 の範囲でループを実行し、絶対値が 0.01 より小さい数値を 0 に設定します。

Sub RoundToZero()

For Each myObject in myCollection

If Abs(myObject.Value) < 0.01 Then myObject.Value = 0

Next

End Sub

For Each...Next ループの終了

For Each...Next ステートメントを終了するには、Exit For ステートメントを使います。たとえば、エラーが発生する場合、特定のエラーを調べるために、If...Then...Else ステートメントまたは Select Case ステートメントの真 (True) ステートメント ブロック中で Exit For ステートメントを使います。エラーが発生せず、If...Then...Else ステートメントが偽 (False) の場合、ループは通常どおりに続行されます。

次の例は、セル範囲 A1:B5 で数値を含まないセルがあるかどうかを調べます。そのようなセルが見つかるとメッセージが表示され、Exit For ステートメントによってループが終了します。

Sub TestForNumbers()

For Each myObject In MyCollection

If IsNumeric(myObject.Value) = False Then

MsgBox "オブジェクトに数値以外の値が含まれています。"

Exit For

End If

Next

End Sub


If...Then...Else ステートメントの使い方

If...Then...Else ステートメントを使用すると、条件の値に応じて特定のステートメントまたはステートメント ブロックを実行できます。If...Then...Else ステートメントは、必要なレベルまでネスト (入れ子) 構造にすることができます。ただし、複数のレベルのネスト構造を持つ If...Then...Else ステートメントよりも、Select Case ステートメントを使用する方が、コードは読みやすくなります。

条件が真 (True) の場合のステートメントの実行

条件が真 (True) の場合に 1 つのステートメントだけを実行するときは、If...Then...Else ステートメントの 1 行の構文を使います。次の例は、キーワード Else を省略した 1 行の構文を示しています。

Sub FixDate()

myDate = #95/2/13#

If myDate < Now Then myDate = Now

End Sub

複数行のコードを実行するには、複数行の構文を使用する必要があります。この構文には、次の例のように End If ステートメントが含まれます。

Sub AlertUser(value as Long)

If value = 0 Then

AlertLabel.ForeColor = "Red"

AlertLabel.Font.Bold = True

AlertLabel.Font.Italic = True

End If

End Sub

条件に応じたステートメントの実行

条件に応じて、実行可能な 2 つのブロックのステートメントを定義する場合には、If...Then...Else ステートメントを使います。条件が真 (True) の場合には、あるブロックが実行され、偽 (False) の場合には、別のブロックが実行されます。

Sub AlertUser(value as Long)

If value = 0 Then

AlertLabel.ForeColor = vbRed

AlertLabel.Font.Bold = True

AlertLabel.Font.Italic = True

Else

AlertLabel.Forecolor = vbBlack

AlertLabel.Font.Bold = False

AlertLabel.Font.Italic = False

End If

End Sub

2 番目の条件のテスト

If...Then...Else ステートメントに ElseIf ステートメントを追加して、最初の条件が偽 (False) の場合に 2 番目の条件をテストすることができます。たとえば、次の例の Function プロシージャは、仕事別にボーナスを計算します。Else ステートメントの後のステートメントは、If ステートメントおよび ElseIf ステートメントの条件がすべて偽 (False) の場合に実行されます。

Function Bonus(performance, salary)

If performance = 1 Then

Bonus = salary * 0.1

ElseIf performance = 2 Then

Bonus = salary * 0.09

ElseIf performance = 3 Then

Bonus = salary * 0.07

Else

Bonus = 0

End If

End Function


コードでのかっこの使い方

Sub プロシージャ、組み込みのステートメント、およびいくつかのメソッドは値を返さないので、指定する引数はかっこで囲みません。次に例を示します。

MySub "stringArgument", integerArgument

Function プロシージャ、組み込み関数、およびいくつかのメソッドは値を返しますが、無視することができます。戻り値を無視する場合はかっこで囲まず、Sub プロシージャを呼び出すときと同じように関数を呼び出します。かっこを省略して引数を列挙すると、変数に関数を代入しません。次に例を示します。

MsgBox "タスクが完了しました。", 0, "タスク ボックス"

関数の戻り値を使用するには、次の例のように引数をかっこで囲みます。

Answer3 = MsgBox("現在の給与に満足していますか ?", 4, "質問 3")

Sub プロシージャまたは Function プロシージャのステートメントは、名前付き引数を使って、呼び出されたプロシージャに値を引き渡すことができます。名前付き引数を使用する場合も、かっこの使用方法は同じです。名前付き引数を使用する場合、それらを任意の順に指定し、省略可能な引数は省くことができます。名前付き引数を指定するには、引数名、コロンと等号 (:=)、引数に代入する値の順で記述します。

次の例は、名前付き引数を使って MsgBox 関数を呼び出しますが、戻り値を無視します。

MsgBox Title:="タスク ボックス", Prompt:="タスクが完了しました。"

次の例は、名前付き引数を使って MsgBox 関数を呼び出し、戻り値を変数 answer3 に代入します。

answer3 = MsgBox(Title:="質問 3", _

Prompt:="現在の給与に満足していますか ?", Buttons:=4)


Select Case ステートメントの使い方

1 つの条件式の値と複数のステートメント ブロックごとに異なる値を比較する場合、If...Then...Else ステートメントの ElseIf ステートメントを使用する代わりに、Select Case ステートメントを使います。If...Then...Else ステートメントは、ElseIf ステートメントごとに異なる条件式を記述しますが、Select Case ステートメントは、実行するステートメント ブロックの先頭で、1 つの条件式を記述します。

次の例では、Select Case ステートメントはプロシージャに渡される引数 performance と各 Case ステートメントの値を比較します。各 Case ステートメントには、複数の値、範囲指定した値、または値と比較演算子を組み合わせて指定できます。省略可能な Case Else ステートメントは、Select Case ステートメントがいずれの Case ステートメントの値とも一致しない場合に実行されます。

Function Bonus(performance, salary)

Select Case performance

Case 1

Bonus = salary * 0.1

Case 2, 3

Bonus = salary * 0.09

Case 4 To 6

Bonus = salary * 0.07

Case Is > 8

Bonus = 100

Case Else

Bonus = 0

End Select

End Function


With ステートメントの使い方

With ステートメントを使用すると、一度指定したオブジェクトやユーザー定義型に対してオブジェクト名の再指定を省略して、一連のステートメントを実行できます。With ステートメントを実行すると、プロシージャの実行速度が向上します。また、オブジェクトを繰り返し入力をする必要がありません。

次の例は、セル範囲に数値 30 を入力し、書式を太字に設定します。また、内部の色を黄色に設定します。

Sub FormatRange()

With Worksheets("Sheet1").Range("A1:C10")

.Value = 30

.Font.Bold = True

.Interior.Color = RGB(255, 255, 0)

End With

End Sub

処理効率を高めるために、With ステートメントをネスト (入れ子) 構造にすることができます。次の例は、セル A1 に数式を挿入し、次にフォントの書式を設定します。

Sub MyInput()

With Workbooks("Book1").Worksheets("Sheet1").Cells(1, 1)

.Formula = "=SQRT(50)"

With .Font

.Name = "Arial"

.Bold = True

.Size = 8

End With

End With

End Sub


Visual Basic の名前付け規則

Visual Basic のモジュールで、プロシージャ、定数、変数、および引数に名前を付ける場合、次の規則に従います。

•	名前の先頭は文字でなければなりません。

•	名前にはスペース、ピリオド (.)、感嘆符 (!)、および @、&、$、# などの文字を使うことはできません。

•	名前は 255 文字 (半角の場合) 以内でなければなりません。

•	通常、Visual Basic の関数、ステートメント、およびメソッドと同じ名前を使うことはできません。Visual Basic で使用している同じ名前のキーワードの機能が使えなくなります。割り当てた名前と競合する組み込み関数、ステートメント、またはメソッドを使用する場合、明示的に識別する必要があります。組み込み関数、ステートメント、またはメソッドの前に、関連するタイプ ライブラリの名前を指定してください。たとえば、Left と呼ばれる変数がある場合、VBA.Left を使って Left 関数だけを呼び出すことができます。

•	同じレベルの適用範囲内で、同じ名前を使用することはできません。たとえば同じプロシージャ内で、age という名前の 2 つの変数を宣言することはできません。ただし、age という名前のプライベート変数と age という名前のプロシージャ レベルの変数は、同じモジュールで宣言できます。

メモ   Visual Basic では、大文字と小文字は区別されませんが、名前を宣言するステートメントの大文字は保持されます。


アプリケーション間の連携

Visual Basic を使って新しいオブジェクトを作成したり、マイクロソフト社のアプリケーションから既存のオブジェクトを取得できます。その他のアプリケーションから Visual Basic を使って作成できるオブジェクトが提供されることもあります。詳細については、アプリケーションのマニュアルを参照してください。

新しいオブジェクトを作成したり、別のアプリケーションから既存のオブジェクトを取得するには、CreateObject 関数または GetObject 関数を使います。

' Microsoft Excel を起動し、新しい Worksheet オブジェクトを作成します。

Set ExcelWorksheet = CreateObject("Excel.Sheet")

' Microsoft Excel を起動し、既存の Worksheet オブジェクトを開きます。

Set ExcelWorksheet = GetObject("SHEET1.XLS")

' Microsoft Word を起動します。

Set WordBasic = CreateObject("Word.Basic")

多くのアプリケーションは、アプリケーションが表示されているかどうかに応じてアプリケーションを閉じる Exit ステートメントまたは Quit メソッドを提供します。アプリケーションによって提供されるオブジェクト、メソッド、およびプロパティの詳細については、アプリケーションのマニュアルを参照してください。

アプリケーションによっては、タイプ ライブラリに存在する任意のクラスのオブジェクトをキーワード New を使って作成できます。次に例を示します。

Dim X As New Field

この場合、Field オブジェクトはデータ アクセス用のタイプ ライブラリ内のクラスの例です。Field オブジェクトの新しいインスタンスは、この構文を使って作成されます。どのオブジェクト クラスがこの方法で作成できるかについては、アプリケーションのマニュアルを参照してください。


Function プロシージャの記述方法

Function プロシージャは、Function ステートメントおよび End Function ステートメントで囲まれた Visual Basic の一連のステートメントです。Function プロシージャは Sub プロシージャと似ていますが、Function プロシージャは値を返すこともできます。Function プロシージャは、呼び出したプロシージャを通じて定数、変数、式などの引数を取得できます。Function プロシージャが引数を持たない場合、その Function ステートメントには空のかっこを指定する必要があります。関数はプロシージャ内の 1 つまたは複数のステートメントでプロシージャ名に値を代入することにより、値を返します。

次の使用例では、Celsius 関数は、温度を華氏から摂氏に変換します。この関数を Main プロシージャから呼び出すと、引数値を含む変数が関数に渡されます。計算結果は、呼び出したプロシージャに返され、メッセージ ボックスに表示されます。

Sub Main()

temp = Application.InputBox(Prompt:= _

"華氏で温度を入力してください。", Type:=1)

MsgBox "温度は摂氏 " & Celsius(temp) & " 度です。"

End Sub

Function Celsius(fDegrees)

Celsius = (fDegrees - 32) * 5 / 9

End Function


Property プロシージャの記述方法

Property プロシージャは、プログラマが独自のプロパティを作成し、処理するための Visual Basic の一連のステートメントです。

•	Property プロシージャを使用すると、フォーム、標準モジュール、およびクラス モジュールの取得専用のプロパティを作成することができます。

•	プロパティの値が設定されている場合に実行しなければならないコードでは、パブリック変数の代わりに Property プロシージャを使うことをお勧めします。

•	パブリック変数と異なり、Property プロシージャには、オブジェクト ブラウザで指定したヘルプのコンテキスト文字列を設定することができます。

Property プロシージャを作成した場合、そのプロシージャは定義されたモジュールのプロパティになります。Property プロシージャには、次の 3 種類があります。

プロシージャ	内容
Property Let	プロパティに値を設定するプロシージャ
Property Get	プロパティの値を取得するプロシージャ
Property Set	オブジェクトへの参照を設定するプロシージャ
Property プロシージャを宣言する構文は次のとおりです。

[Public | Private] [Static] Property {Get | Let | Set} propertyname_ [(arguments)] [As type]

statements

End Property

通常、Property プロシージャは 2 つ 1 組で使います。この組み合わせは、Property Let プロシージャと Property Get プロシージャ、または Property Set プロシージャと Property Get プロシージャのいずれかです。Property Get プロシージャだけを宣言した場合は、値の取得のみ可能なプロパティが作成されます。また、3 種類の Property プロシージャをすべて組み合わせて使うこともできます。この場合は、バリアント型 (Variant) 変数を使用すると便利です。オブジェクトまたは他のデータ型の情報を格納することができるのは、バリアント型 (Variant) だけです。Property Set プロシージャはオブジェクトを対象としていますが、Property Let プロシージャはオブジェクトを対象としていません。

Property プロシージャを宣言する場合の引数の指定方法は、次の表に示すとおりです。

プロシージャ	宣言の構文
Property Get	Property Get propname(1, ..., n) As type
Property Let	Property Let propname(1, ...,,,, n, n+1)
Property Set	Property Set propname(1, ..., n, n+1)
同じ名前の Property プロシージャの宣言では、1 番目の引数から、最後から 2 番目の引数まで (1, ..., n)、それぞれ同じ名前とデータ型を使う必要があります。

Property Get プロシージャの宣言では、Property Let プロシージャまたは Property Set プロシージャの宣言よりも 1 つ少ない引数を指定します。Property Get プロシージャのデータ型は、関連する Property Let プロシージャまたは Property Set プロシージャの宣言の最後の引数 (n+1 番目の引数) と同じデータ型にしてください。たとえば、次のような Property Let プロシージャを宣言する場合、Property Get プロシージャの宣言では、Property Let プロシージャの引数と同じ名前とデータ型を持つ引数を指定する必要があります。

Property Let Names(intX As Integer, intY As Integer, varZ As Variant)

' ステートメント

End Property

Property Get Names(intX As Integer, intY As Integer) As Variant

' ステートメント

End Property

Property Set プロシージャを宣言する場合、最後の引数のデータ型は、オブジェクト型 (Object) またはバリアント型 (Variant) でなければなりません。


Sub プロシージャの記述方法

Sub プロシージャは、Sub ステートメントと End Sub ステートメントの間の、Visual Basic の一連のステートメントです。Sub プロシージャは、処理を実行するだけで値は返しません。Sub プロシージャは、呼び出したプロシージャを通じて定数、変数、または式などの引数を取得できます。Sub プロシージャが引数を持たない場合、その Sub ステートメントには空のかっこを指定する必要があります。

次の Sub プロシージャは、各行を説明するコメントを指定します。

' GetInfo という名前のプロシージャを宣言します。

' この Sub プロシージャは引数を持ちません。

Sub GetInfo()

' answer という名前の文字列変数を宣言します。

Dim answer As String

' InputBox function の戻り値を answer に代入します。

answer = InputBox(Prompt:="名前を入力してください。")

' 条件付きの If...Then...Else ステートメント

If answer = Empty Then

' MsgBox 関数を呼び出します。

MsgBox Prompt:="名前が入力されていません。"

Else

' MsgBox 関数は変数と連結しました。

MsgBox Prompt:="あなたの名前は " & answer & " です。"

' If...Then...Else ステートメントを終了します。

End If

' Sub プロシージャを終了します。

End Sub


代入ステートメントの記述方法

代入ステートメントは、値または式を変数や定数に代入します。代入ステートメントには、必ず等号 (=) が含まれます。次の例は、InputBox 関数の戻り値を変数 yourName に代入します。

Sub Question()

Dim yourName As String

yourName = InputBox("名前を入力してください。")

MsgBox "あなたの名前は " & answer & " です。"

End Sub

Let ステートメントは省略可能で、通常省略されます。たとえば、上記の代入ステートメントは、次のようにも記述できます。

Let yourName = InputBox("名前を入力してください。")

Set ステートメントは、オブジェクトとして宣言された変数にオブジェクトを代入します。キーワード Set は必ず指定します。次の例では、Set ステートメントはオブジェクト変数 myCell に Sheet1 の範囲を代入します。

Sub ApplyFormat()

Dim myCell As Range

Set myCell = Worksheets("Sheet1").Range("A1")

With myCell.Font

.Bold = True

.Italic = True

End With

End Sub

プロパティ値を設定するステートメントも、代入ステートメントです。次の例は、アクティブ セルに Font オブジェクトの Bold プロパティを設定します。

ActiveCell.Font.Bold = True


宣言ステートメントの記述方法

宣言ステートメントを使用して、プロシージャ、変数、配列、および定数に名前を付け、定義することができます。プロシージャ、変数、または定数を宣言する場合、宣言を記述する場所、および宣言で使用するキーワードにより、その適用範囲も定義します。

次の例には、3 つの宣言が含まれています。

Sub ApplyFormat()

Const limit As Integer = 33

Dim myCell As Range

' 追加のステートメントを記述します。

End Sub

Sub ステートメント (End Sub ステートメントと 1 組で使用) は、ApplyFormat という名前のプロシージャを宣言します。Sub ステートメントと End Sub ステートメントの間のすべてのステートメントは、ApplyFormat プロシージャが呼び出されるかまたは実行されると、必ず実行されます。

•	Sub プロシージャの記述方法

Const ステートメントは定数 limit を整数型 (Integer) と指定し、値として 33 を設定することを宣言します。

•	定数の宣言

Dim ステートメントは、変数 myCell を宣言します。この場合のデータ型はオブジェクト型で、Microsoft Excel の Range オブジェクトを指定します。変数は使用中のアプリケーションで公開されているどのオブジェクトとしても宣言できます。Dim ステートメントは、変数を宣言するために使用されるステートメントです。このほかに宣言するときに使用するキーワードには、ReDim ステートメント、Static ステートメント、Public ステートメント、Private ステートメント、および Const ステートメントがあります。

•	変数の宣言


実行可能なステートメントの記述方法

実行可能なステートメントは、処理を起動します。このステートメントは、メソッドまたは関数を実行し、コードのブロック間をループしたり分岐することができます。実行可能なステートメントには、通常、算術演算子や条件演算子が含まれます。

次の例は、For Each...Next ステートメントを使用して、アクティブな Microsoft Excel のブックの Sheet1 の MyRange という名前の範囲の各セルに対して操作を繰り返します。変数 c は、MyRange に含まれるセルのコレクション内の 1 つのセルです。

Sub ApplyFormat()

Const limit As Integer = 33

For Each c In Worksheets("Sheet1").Range("MyRange").Cells

If c.Value > limit Then

With c.Font

.Bold = True

.Italic = True

End With

End If

Next c

MsgBox "All done!"

End Sub

上記の例の If...Then...Else ステートメントは、セルの値を調べます。セルの値が 33 よりも大きい場合、With ステートメントはそのセルに、Font オブジェクトの Bold プロパティと Italic プロパティを設定します。If...Then...Else ステートメントは、End If  ステートメントで終了します。

With ステートメントで指定したステートメントは、キーワード With の後のオブジェクトで自動的に実行されるため、オブジェクト名の記述を省略できます。

Next ステートメントは、範囲 MyRange に含まれるセルのコレクション内の次のセルを呼び出します。

MsgBox 関数は Visual Basic の組み込みのダイアログ ボックスを表示して、Sub プロシージャが終了したことを示すメッセージを表示します。


ファイルへのデータの書き込み

大量のデータを処理する場合、ファイルにデータを書き込んだり、ファイルからデータを読み込むと便利です。Open ステートメントを使用すると、ファイルを直接作成したり、操作できます。Open ステートメントは、3 種類のファイル操作を提供します。

•	シーケンシャル アクセス (Input モード、Output モード、および Append モード) は、エラー ログやレポートなどをテキスト ファイルに書き込むときに使用します。

•	ランダム アクセス (Random モード) は、ファイルを開いたままデータを読み書きするときに使用します。ランダム アクセス ファイルでは、データをレコードの形で扱います。したがって、情報へのアクセスが迅速に、しかも簡単に行えます。

•	バイナリ アクセス (Binary モード) は、ビットマップ イメージの保存や表示など、ファイル内の任意のバイト位置に読み書き行うときに使用します。

メモ   Open ステートメントは、アプリケーション独自のファイル形式を開く場合には使用できません。たとえば、Word 文書、Microsoft Excel スプレッドシート,、または Microsoft Access データベースを開くときに、Open ステートメントを使用してはいけません。Open ステートメントを使用すると、ファイルの整合性が失われたり、破損の原因となります。

次の表は、ファイルにデータを読み書きするときに使用される主なステートメントを示します。

アクセスの種類	データの書き込み	データの読み取り
シーケンシャル	Print #, Write #	Input #
ランダム	Put	Get
バイナリ	Put	Get


Visual Basic ステートメントの作成

Visual Basic 内のステートメントは、1 つの完結した命令です。ステートメントには、キーワード、演算子、変数、定数、および式を指定できます。各ステートメントは、次のいずれかに分類されます。

•	宣言ステートメント。変数、定数、またはプロシージャに名前を付け、データ型も指定できます。

    宣言ステートメントの記述方法

•	代入ステートメント。変数または定数に値や式を代入します。

    代入ステートメントの記述方法

•	実行可能なステートメント。処理を起動します。このステートメントは、メソッドまたは関数を実行し、コードのブロック間をループしたり分岐することができます。実行可能なステートメントには、通常算術演算子や条件演算子が含まれます。

実行可能なステートメントの記述方法

複数行のステートメントの作成

ステートメントは、通常、1 行に記述できますが、行継続文字を使用してステートメントを次の行に続けることができます。次の例では、MsgBox 関数を 3 行に継続して記述しています。

Sub DemoBox()  'このプロシージャは文字列を宣言し、

' 値 Claudia を代入し、

' 次に連結メッセージを表示します。

Dim myVar As String

myVar = "Hanako"

MsgBox Prompt:="こんにちは " & myVar, _

Title:="グリーティング ボックス", _

Buttons:=vbExclamation

End Sub

コメントの記述

コメントはコードを見る人に、プロシージャや特定の命令についての説明を提供します。Visual Basic はプロシージャを実行するときに、コメントを無視します。コメント行は、先頭にクォーテーション (') または Rem ステートメントのいずれかと、その後ろにスペースを挿入することにより、プロシージャの任意の場所に記述できます。コメントをステートメントと同じ行に記述するには、ステートメントの後にクォーテーションを挿入し、コメントを記述します。特に指定しない限り、コメントは緑色の文字列で表示されます。

構文エラーの調査

コード行を入力した後、Enter キーを押したときにその行が赤で表示されたり、エラー メッセージが表示された場合、ステートメントの誤りを見つけ、訂正する必要があります。


アドイン マネージャの使用

アドインをロードしたり、アンロードするには、[アドイン マネージャ] ダイアログ ボックスを使用します。たとえば、システム メニューをダブルクリックしたり、システム メニューの [閉じる] ボタンをクリックして、アドインの可視部分を閉じて、そのフォームが画面上で非表示になっても、メモリ上にアドインは存在します。アドイン オブジェクトは、[アドイン マネージャ] ダイアログ ボックスで切断するまで、常にメモリに存在します。