VBA共通の基本的な使い方をまとめました。
目次
----
VBE
演算子
変数
制御分
プロシージャ
モジュール
プロジェクト
===================================
..VBE
===================================
よく使うショートカット
F5 実行(継続)
F8 ステップイン
Shift + F8 ステップオーバー
Ctrl + F8 カーソル行まで実行
F9 ブレークポイント設定
F1 ヘルプ(調べたい語句に文字カーソルを置いて)
F2 オブジェクトブラウザ
Alt + F11 VBE起動
Alt + F8 マクロ実行ダイアログを開く
Ctrl + Space/J 入力候補、自動メンバー表示
tab space . ( =で確定、enterは改行
ただし、(数字).の後ではこの機能が働かない
Ctrl + I クイックヒント
Ctrl + Shift + I パラメータヒント
Ctrl + F3 次を検索(検索ダイアログを閉じた後)
Shift +(Ctrl)+F3 前を検索
Shift + F2 定義元へジャンプ(関数へ)
Ctrl + Shift + F2 元表示していた個所に戻る
Ctrl + ↑、↓ 前、後のプロシージャ―へ移動
Ctrl + ←、→ 前、後の単語へ移動
Ctrl + Y 1行削除(カット)
Ctrl + Delete 単語の最後まで削除
Atl + R->R マクロ実行のリセット
Ctrl + Break プロシージャの強制終了
コメントアウトにアクセスキーを設定
Alt + / コメントアウト
Alt + \ 解除
(設定方法)
ツールバー->右クリック->ユーザー設定->編集のコメントブロック、非コメントブロックをツールバーへドラッグ
アイコンをクリック->選択したボタンの編集
名前=(&/)
イメージとテキストを表示=True
Option
Option Base 1 配列の添え字を1から始める(デフォルトでは0から)
Option Explicit 変数宣言の強制
_ 改行して記述を続ける場合、半角スペース+アンダーバー(行連結文字)
大文字と小文字の区別はない
'コメント
コメントの例
'--------------------
'関数の機能
'引数:i/説明、s/説明
'戻り値:説明
'--------------------
'***** ブロックの説明 *****
デバッグモードに入る方法
ブレークポイントを設定する
コードに Stop を記述する方法
If i = 5 Then Stop
コードに Debug.Assert を記述する方法
Debug.Assert i <> 5 'Falseの場合にデバッグモードに入る
ウォッチウィンドウに記述する方法
式がTrueの時に中断
式に「i > 10」と記入
式の内容が変化したときに中断
式に「i」と記入
イミディエイトウィンドウ
Debug.Print "a"
Debug.Print i; ' 改行せずに出力
Debug.Print i, ' タブ区切りで出力
a=1 : ?a ' 複数の文を1行に記述
a=1 ' 変数の宣言は不要(不可)、宣言せずに使える
?1+1
?F1(1) ' 関数の実行
sub1 ' プロシージャの実行
ローカルウィンドウ
ウォッチウィンドウ
式i=3
ウォッチの種類:式がTrueのときに中断
呼び出し履歴
ローカルウィンドウの左上の「...」ボタンを押すと表示される
中断モードでのみ表示可
上にある履歴ほど新しい
過去に呼び出されたプロシージャ―で使用中の変数を、ローカルウィンドウに表示できる
オブジェクトブラウザ
F2
オブジェクトのメソッドやプロパティを調べることができる
検索文字列は大文字小文字を区別しない
1行に複数のステートメントを記述
i=1:i=2
無限ループをストップさせる方法
ESC
Ctrl+Break(連打、長押し)
必ず中断できるとは限らない
上記で止まらない場合
ESCを押しながら、タスクバーのエクセルをクリックする(10回程度)
ダメなら、Ctrl+Breakを押しながらウィンドウを切り替える
それでも止まらなければ強制終了(Ctrl+Alt+Del)
Microsoft公式ドキュメントの表記規則
Sub(先頭が大文字、太字)→VBA固有のキーワード
a(斜体)→ユーザーが入力
[a](角かっこ)→省略可能
{a|b}(波かっこ、パイプ文字)→いずれかを選択
[a|b](角かっこ、パイプ文字)→いずれかを選択するか、両方とも省略可能
===================================
..演算子
===================================
演算子の優先順位
算術演算子
連結演算子
比較演算子
論理演算子
算術演算子
^ べき乗
*
/
\ 割り算の商
Mod 割り算の余り(剰余)
+
-
関数Modとの違い
10 Mod -3 除算の余り
両方が正でない場合、下記の2つの結果は異なる
10 Mod -3→1
=Mod(10,-3)→-2
連結演算子
&
+ 算術演算子と区別が難しいため使わないほうがよい
Debug.Print "10"+"10" →1010
比較演算子
=
<>
<
>
<=
>=
Is
Like
Is演算子
2つのオブジェクト型の参照が等しいかを判定する
obj1 Is Obj2
obj1 Is Nothing
obj1 = Obj2 '不可
Rangeには使えない
Rangeは取得するたびに別のアドレスに格納されるため
Addressプロパティを使って比較する
Like演算子
"abc" Like "*c"
a?b 任意の1文字
*c 0文字以上の文字
1# 任意の1桁の数字(全角数字を含む)
[abc] abcの任意の1文字
[!abc]abc以外の任意の1文字
[a-z] a~z
論理演算子
Not
And
Or
Xor
Eqv
Imp
A Xor B
排他的論理和
AとBの片方のみがTrueのときTrueを返す
A Eqv B
論理等価
AとBの両方がTrue、または、両方がFalseのときTrueを返す
A←→B、AとBは同値
A Imp B
論理包含、implication
AがFalse、または、BがTrueのときTrueを返す
AがTrue、かつ、BがFalseのときFalseを返す
A→B、AならばB、AがBに含まれている
ビット演算子
And
Or
Not
Xor
(ビット演算子の例)
If(1 And 3) Then → True(非0)となる
And
1= 0 0 0 1
1+2= 0 0 1 1
結果 0 0 0 1
===================================
..変数
===================================
変数名の記述法
キャメル記法
userName
ローカル変数
パスカル記法
UserName
グローバル変数、プロシージャ
スネーク記法
user_name
大文字記法(アッパースネーク記法)
USER_NAME
定数
ハンガリアン記法
strUserName
その他
ラベル Error_Handler:
変数名の方針
英単語を使う
変数は名詞、プロシージャは動詞で始める
配列は複数形
識別子(変数、定数、プロシージャなどの名前)の名目規則
数字、記号で始めることはできない
記号(!、ピリオド)、スペースは使えない
255文字以内
PrivateとPublic
省略時の既定
Private扱い
外部変数(Dimで宣言した場合)、Const
Public扱い
プロシージャ(Sub、Function)
Typeの定義は標準モジュールではPublic扱い。それ以外のモジュールではPrivate扱い。
標準Moduleでしか宣言できない
Public
定数、配列、ユーザー定義型の変数、ユーザー定義型の定義(Type)
外部変数(パブリック変数、モジュールレベル変数)
宣言セクションに記述
Public s As String 全モジュールで有効
Private s As String モジュール内で有効
Dim s As String Private扱い(一般的には、Dimはプロシージャー内で使う)
外部変数はマクロが終了しても初期化されない
Endステートメントで終了したときに初期化される
Endステートメントはすべてのコードの実行を強制終了する(通常は使わない)
ローカル変数(プロシージャレベル変数)
Dim s1 As String,s2 As String
Static s As String 実行後も値が保持される(宣言セクションでは使えない)
Dim s As String : Set s = "abc"
Dim x データ型を省略するとVariant型
変数の型
Byte 0~255
Integer -32,768~32,767
Long -21億~21億(4byte)
Single 4byte
Double 8byte
Variant 16byte(数値、文字列、日付型など何でも入れられる)
Currency 通貨型、小数点の左側に15桁、右側に4桁の固定小数点数
小数点以下が4桁以内なら演算誤差は出ない
書式設定されていないセルに出力すると通貨記号が付く
Date
String
Object オブジェクトへの参照を格納する、If obj1 Is Nothing Then
初期値
0 Byte、Integer、Long、Single、Double、Currency
Date(1899/12/30 00:00:00)
Boolean(False)
Empty Variant
Nothing Object、Range
"" String型の初期値vbNullStringとほぼ同じ
Null Variant(ほとんど使われない)
小数以下の演算誤差
コンピューターでは小数点以下を正しく計算できない
VBAでは、Double、Singleを使った場合に演算誤差が発生する
理由
10進数の0.1は、2進数では0.0001100110011・・・と表現できない
例
d1 = 1
d2 = 0.1
d3 = d1-d2 →d3は0.9とならない
対応策
Currency型を使う(小数点以下が4桁以内の場合)→簡単で確実
必要な桁数で丸める(誤差はずっと小さい小数で発生しているため
d3 = round(d1-d2,1)
d3 = format(d1-d2,"0.0")
Dicimal型を使う→型宣言できないため扱いづらい
変数はVariantで宣言
CDec関数を使う
数値リテラルに型宣言文字を付与する
@0.9 = @1 - @0.1 'True
型宣言文字
% Integer
& Long
! Single
# Double
@ Currency
定数
Private Const A = 10
Private Const A As Integer = 10
Public Const A = "abc"
Const A = "abc"
Publicは標準モジュールの宣言セクションでのみ可
宣言セクションで省略した場合はPrivate扱い
プロシージャ内で使う場合はPrivate、Publicを付けない
定数の配列は不可
定数の宣言は、値の代入を兼ねる
右辺はリテラル、他の定数。右辺に変数や関数は使えない
Object型変数は定数とすることができない
静的変数
Static s As String
プロシージャ内で宣言する、プロシージャ―が終了しても保持される
列挙型
Private Enum e
i1 = 1
i2 = 4
End Enum
Debug.Print e.a
Const定数をまとめたもの
列挙型のメンバーが持てる値は整数値のみ
ユーザー定義型(他の言語では構造体と呼ばれる)
Private Type Type1
s As String
i As Integer
End Type
Sub Sub1()
Dim t1 As Type1
t1.s = "abc"
End Sub
Sub Sbu2()
Dim t1() As Type1
Dim i As Integer
For i = 1 to 10
Redim Preserve t1(i)
t1(i).s = "a"
Next
End Sub
宣言セクションで定義
標準モジュールでは既定でPublic、それ以外のモジュールではPrivateとなる
Publicは標準モジュールでのみ定義可
要素を配列で宣言できない
要素のデータ型を指定する必要がある
参照渡しのみ
Variant、Collection、Dictionaryに入れられない
1つの変数に複数の異なるデータ型の値を格納できる
クラスを使っても同様のことができる
配列
Dim i(2) As Integer 固定配列、i(0)~i(2)
Option Base 1ではi(1)~i(2)
Dim i(2 to 4) As Integer i(2)~i(4)
Dim i(2,2) 二次元配列、最大60次元まで
Dim i() As Integer 動的配列
ReDim i(2) 既存データは初期化される
インデックスの下限の変更可 ReDim i(3 To 5)
二次元以上の配列の変更可
次元数の変更可
ReDim Preserve i(2)既存データを保持したまま要素数を変更
インデックスの下限の変更は不可 ×ReDim Preserve i(3 To 5)
2次元以上の配列では最終次元のみ変更可
それ以外の次元を変更しようとするとエラー発生
→Collectionオブジェクトを使う
worksheetFunction.transpose()を使う
次元数の変更は不可(2次元→3次元など)
Dim i As Integer 動的配列(省略)
ReDim i(100)
配列の初期値のセット
Dim v As Variant
v = Array("A", "B", "C")
v = Array(0,1,5)
Dim v(1,2) As Variant
v = Array(Array(1,1,1),Array(1,1,1),Array(1,1,1))
Dim ss() As String '動的配列、または、Variant型で宣言
Dim v As Variant
ss = Split("a,b,c", ",")'戻り値の配列の添え字の下限値は常に0(Option Baseに関わらず)
v = Split("a,b,c", ",")
配列の出力
Debug.Print Join(ss) 'a b c
Debug.Print Join(ss,",") 'a,b,c
Debug.Print Filter(ss,"b")(0) 'b(bを含む要素を抽出)、Filterの添え字の下限値は常に0(Option Baseに関わらず)
配列の初期化と解放
Erase i
固定配列の場合、要素が初期化される。メモリは解放されない
動的配列の場合、メモリが解放される。再使用する場合は、Redimを使う
UBound
配列で使用できるインデックスの最大値(Option Base 0の場合は要素数ではない)
For i = 0 To UBound(v)
For i = 0 To UBound(v,2) 2次元目、2次元目がない配列の場合はエラー
For i = LBound(v) To UBound(v)
i = WorksheetFunction.sum(v) '配列の合計
多次元配列への代入
Dim v(5, 10) As string
For i = 1 To 5
For j = 1 To 10
v(i, j) = "abc"
Next
Next
配列から配列への代入
Dim ss1() as String
Dim ss2() as String
Dim ss3(2) as String
ss1 = ss2 動的 = 動的(可能)
ss1 = ss3 動的 = 静的(可能)
型が一致していないと代入できない
静的配列には代入できない
配列の結合
v1 = Split(Join(ss1,",") & "," & Join(ss2,","), ",") 'ただし配列内に,を含まない
Joinは二次元配列では使えない
配列の代わりにDictionaryやCollectionを使ったほうがよい場合も多い
配列とRange
Dim ss(5,5) As string
Dim ss(5) As string
r = ss
rの範囲内のみに代入
代入する値が配列にない場合は「#N/A」(2次元配列)か「0」(1次元配列)が代入される
r(1).Resize(UBound(ss,1),UBound(ss,2) = ss
Dim v() As Variant
v = r
vのサイズはrの範囲に応じて自動的に決定される
Option Baseに関わらず添え字の下限値は1
連想配列
DictionaryとCollectionの違い
Dictionary(こちらを使う方がよい)
多くの点でCollectionの上位互換となっている
Collection
Keyに日付、数値を格納できない
Keyは省略可
異なるデータ型を格納できる
Addメソッドの引数が多い(Before、Afterがある)
Dictionary(辞書型)
Dim obj1 As Object
Set obj1 = CreateObject("Scripting.Dictionary") 参照設定不要
obj1.Add "key1", 10 格納される項目(値)は任意の型
obj1.Count
obj1.Item("key1")
obj1("key1")
obj1.Key("key1") = "key2" keyの変更
obj1.Add("key1", 20) 代入
If obj1.Exists("key1") Then
v = obj.Items 配列vに項目(値)返す
v = obj.Keys 配列vにkeyを返す
obj1.Remove("key1") keyと項目(値)の削除
obj1.RemoveAll 全削除
二次元のDictionary
Dim dic1 As Object
Dim dic2 As Object
Set dic1 = CreateObject("Scripting.Dictionary")
Set dic2 = CreateObject("Scripting.Dictionary")
dic2.Add "key2_1","a"
dic2.Add "key2_2","b"
dic1.Add "key1_1",dic2
Set dic2 = CreateObject("Scripting.Dictionary")
dic2.Add "key2_1","c"
dic2.Add "key2_2","d"
dic1.Add "key1_2",dic2
Dim v1 As Variant
Dim v2 As Variant
For Each v1 In dic1.keys
For Each v2 In dic1(v1).keys
Debug.Print dic1(v1)(v2)
Next
Next
Collection
Dim collection1 As Collection
Set Collection1 = New Collection
または、 Dim Collection1 As New Collection
collection1.Add 10, "key1"
collection1.Add "a", "key2" '辞書型とは異なり、異なるデータ型を格納できる
collection1.Count
collection1("key1")
collection1(1)
For Each v In collection1
If isExists(collection1,"a")
collection1.Remove "key1"
配列の次元数を返す関数
Public Function GetArrayDimension(ByVal v As Variant) As Long
On Error GoTo ENDPOINT
Dim i As Long, tmp As Long
For i = 1 To 100
tmp = LBound(v, i)
Next
GetArrayDimension = 0
Exit Function
ENDPOINT:
GetArrayDimension = i - 1
End Function
Set
オブジェクトへのポインタを取得する
Dim book1 As Workbook
Set book1 = Workbooks("Book1.xls")
Set book1 = Nothing
特殊な文字列を表す組み込み定数
vbCrLf Chr(13) & Chr(10) Windowsで一般的に使われる改行
vbCr Chr(13) キャリッジリターン
vbLf Chr(10) ラインフィード
vbTab Chr(9)
vbNewLine vbCrLfと同じ
vbNullString 文字列型の初期値
改行コードを調べる方法
Hex(AscB(MidB(s1, 1, 1))
0A →LF
0D 0A →CRLF
Officeでの改行
Accessの改行(関数内で使用)
chr(13) & chr(10)
Excelのセル内改行(ワークシート関数内で使用)
CHAR(10)
LF(Alt+Enter)
Excelの検索 Ctrl+Jで検索置換できる
Excelの改行を Accessの改行に変更するマクロ
Cells.Replace What:=Chr(10), Replacement:=vbCrLf
Excelの改行を Accessの改行に変更するクエリ
Replace([F1], chr(10), chr(13) & chr(10))
コントロールを変数を使って参照する方法
コントロール名、オブジェクト名による変数の参照
Set obj1 = Me.Controls("a")
Me.Controls("a" & i).Value
===================================
..制御文
===================================
If
--
If i=1 Then
Debug.Print "1"
ElseIf i=2
Debug.Print "2"
Else
Debug.Print "3"
End [If]
If i=1 Then Debug.Print "1" Else MsgBox Debug.Print "2"
すべての判定処理が実行される
If(A And B) Then
AがFalseでも、Bも実行(判定)される
Select
------
Select Case s
Case "a"
Msgbox "a" '実行後にSelect Caseを抜ける
Case "b","c","d"
Msgbox "bかcかd"
Case Else
MsgBox "その他"
End Select
Select Case i
Case Is >= 10
Msgbox "10以上"
Case 5 To 9
Msgbox "5-9"
End Select
For
---
Dim i As Integer
For i = 1 to 100
Exit For
Next
抜けた後はi=101となる
Exit For は For が入れ子構造になっている(ネストされている)と、内側の1個だけ抜ける
2個抜けるにはフラグを立てる、または、外側をDo whileにしてExit Doで抜ける
iをループの中で変えることは可(無限ループに注意する)
For i = 1 to iEnd として、ループ中でiEnd=2としても、当初のiEndまでループされる
For i = 100 To 1 Step -1
For i = 1 To 10 Step 2
skipやcontinueに相当するコマンドはない。if、または、GoToを使う
For Each
--------
For Each sheet1 In ActiveWorkbook.Worksheets '全シート
For Each sheet1 In ActiveWindow.SelectedSheets ' 選択されているシート
ループ内で選択シートが変更されても、当初選択されていたシート全て繰り返される
In Selection '行→列
In Worksheets
In Range("A1:A3")
In Cells
In Rows
In Columns
In Names '名前範囲
For Each shape1 In sheet1.Shapes 'グループ化されている図形も1つの図形と見なされる
For Each shape2 In shape1.GroupItems 'グループ化されている図形内の個々の図形
For Each con1 In Me.Controls ' フォーム上のコントロール全て
配列の繰り返し処理
Dim v1 As Variant '配列の繰り返しはVariant型
For Each v1 As ss 'ssは二次元配列でも可
Debug.Print v1
Next
While
-----
While i < 10
Wend
Do While i < 10
Exit Do
Loop
Do Until i = 10
Loop
Do
Loop Until i = 10
無限ループ(Ctrl+Break、または、Escで中断)
Do
Loop
エラー処理
----------
一般的なエラー処理
Sub Sub1()
On Error GoTo Err_error1
i = 100 / 0
Exit sub
Err_error1:
MsgBox "エラー番号:" & Err.Number & "エラー内容: " & Err.Description
End Sub
エラーが発生してもプログラムを中断せず、エラーが発生した箇所の次の処理から継続して実行する。
Sub Sub1()
On Error Resume Next
i = 100 / 0
Debug.Print Err.Number '11が表示される(エラーなしの場合は0)
End Sub
エラー処理を無効にする
Sub Sub1()
On Error Resume Next
i = 100 / 0
On Error GoTo 0 'エラー処理を無効にする(上記の「On Error Resume Next」が機能する範囲を終了する)
End Sub
エラーが発生したステートメントに処理を戻す
Sub Sub1()
On Error GoTo Err_error1
i0 = 0
i = 100 / i0
Exit sub
Err_error1:
i0 =10
Resume '上記の「i = 100 / i0」に戻る
End Sub
エラーが発生した次の行のステートメントに処理を戻す
Sub Sub1()
On Error GoTo Err_error1
i0 = 0
i = 100 / i0
Exit sub
Err_error1:
Resume Next '上記の「i = 100 / i0」の次に戻る
End Sub
行ラベルに処理を戻す
Sub Sub1()
label1:
On Error GoTo Err_error1
i0 = 0
i = 100 / i0
Exit sub
Err_error1:
Resume label1 'label1に戻る
End Sub
エラーの種類
コンパイルエラー
実行時エラー
論理エラー
コンパイルエラー、実行時エラーが発生しないが、プログラムが意図通りに動作しないこと
例えば、小数が必要な変数を、Integerで宣言しているなど
With
----
With sheet1
.[A3] = "a"
End With
Withを使うと、オブジェクト参照の回数を減らせる
Forと組み合わせる場合は、Forの前にWithを使うほうが、実行速度が速くなる
制御分その他
------------
GoTo Label1
Label1:
try-catch-finallyの代わり(終了処理の共通化)
If A Then
Goto Finish
End If
Finish:
Set b = Nothing
===================================
..プロシージャ
===================================
Sub、Functionをプロシージャという
プロシージャの基本
Private Function func1(i as integer, s as string) As String
If(i=1) Then
func1 = "a" ' 戻り値
Exit Function
End If
func1 = "b"
end functin
Public、Private
Public Function func1(i) As String
標準Moduleに記述した場合は、全モジュールから、func1のみで呼び出せる
シートやフォームに記述した場合は、Form1.func1のように呼び出す
Private Function func1(i) As String モジュール内で有効
Function func1(i) As String
省略した場合はPublic扱い
Subも同じ
マクロの実行メニューに表示させない方法
Privateは表示されない
Public Function func1(Optional void = 0) ' 引数がある関数は表示されない
Optional
Sub func1(i1 As Integer, Optional ByVal i2 As Integer)
If IsMissing(i2) Then msgbox "省略されています"
Sub func1(i1 As Integer, Optional i2 As Integer = 5)' 引数省略指定
Functionの呼び出し方(Subも同じ)
Call func1(a,b) この形式に統一するのがよい
func1 a,b この形式でも可
i = func1(a,b) 戻り値を引き取る場合
func1(a) 引数が1つであればCallを省略できるが、値渡しなる。わかりにくいため、使わないほうがよい
func1(a,b) 不可
Call func1 a,b 不可
i = func1 a,b 不可
MsgBox title:="タイトル", prompt:="a" (名前付き引数による呼び出し)
Application.Run "Book2!Test2"(他のブックのマクロを呼び出す)
ByRef、ByVal
Sub、Function の引数につけることができる
引数はデフォルトで参照渡し
ByRef 参照渡し
Sub sub1(i As integer)
Sub sub1(ByRef i As integer)
ByVal 値渡し
Sub sub1(ByVal i As integer)
値渡しと参照渡しの混在
Function myF(ByVal i1, i2)
Function myF(ByVal i1, ByRef i2)
呼び出し方による違い
参照渡し
sub1 i
Call sub1(i)
値渡し
sub(i)
配列を引数として渡す
Sub Sub1()
Dim ss(3,3) As String
Dim v1 As Variant
Call Sub2(ss)
v = ss
Call Sub3(v)
End Sub
Sub Sub2(byRef ss() As String) '動的配列で受け取る、byValは不可、固定配列は不可
ss(1,1) = "a"
End Sub
Sub Sub3(byVal v As Variant) 'Variant型で受け取る、byVal可
MsgBox( v(1,1) )
End Sub
※配列をVariantで宣言してArrayで初期値を代入した場合は、関数間もVariantで渡す(Variantの()なし)
※配列をOptionalで渡したい場合は、Variant型を使う
func1(Optional vars)
※パラメーター配列を使うと、任意の数の引数を配列として受け取ることができる
ユーザー定義型を引数として渡す
Sub Sub1(ByRef type1 As Type) 'byValは不可
値で渡したい場合は、要素の1つずつを引数で渡す
オブジェクトを戻す
Private Function func1() As Object
Set func1 = obj1 '戻す側にもSetが必要
End Function
Private Sub Sub1()
Set obj1 = func1()
End Sub
配列を戻す
Private Function func1() As Variant
Dim vs() As Variant
func1 = vs
End Sub
Private Sub Sub1()
Dim s() As Variant
s = func1()
End Sub
変数にプローシージャ名を入れて実行する
Application.Run "func1"
Application.Run "Sheet1.func1" ' モジュールを指定(func1はPrivateで構わない)
Application.Run "Book2!func1" ' Book2は開いている状態
Application.Run "call_" & func1", 10, "abc" ' 引数のある場合
Functionの戻り値は複数回配置でき、最終的な戻り値が戻される
Private Function func1() As Integer
func1=1
func1=2 ' 最終的に2が戻る
End Function
Private Function func1() As Integer
Dim i As Integer
For i = 1 To 5
func1 = func1 & i 'プロシージャ―名は変数と同じように利用できる
Next
End Function
===================================
..モジュール
===================================
標準モジュール、オブジェクトモジュール
--------------------------------------
モジュールの2種類
標準モジュール
オブジェクトモジュール
シートモジュール
ブックモジュール
フォームモジュール
クラスモジュール
標準モジュール、オブジェクトモジュールの違い
他のモジュールからPublic変数、プロシージャを呼び出す
標準モジュール
他のモジュールから、モジュール名を省略して呼び出せる
オブジェクトモジュール
他のモジュールから呼び出すには、「モジュール名(オブジェクト名).」が必要
Meキーワード
標準モジュール
使用不可
オブジェクトモジュール
使用可
Public Constの宣言
標準モジュール
宣言可
オブジェクトモジュール
宣言不可
クラスモジュール
----------------
オブジェクトを生成することをインスタンス化、生成されたオブジェクトをインスタントという
Dim c1 As Class1 '変数の宣言
Set c1 = New Class1 'クラスのインスタンス化
Dim c1 As New Class1 '変数の宣言と、クラスのインスタンス化を1行で記述。分かりにくいので2行に分けたほうがよい
===================================
..プロジェクト
===================================
参照設定
--------
参照設定する場合(事前バインディング、アーリーバインディング)
Dim cn As New Connection
Dim rs As New Recordset
参照設定しない場合(実行時バインド、遅延バインディング、レイトバインディング)
CreateObject関数を使う
Dim cn As Object
Dim rs As Object
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
GetObject関数を使う(開かれているファイルや実在するインスタンスを取得)
Dim doc1 As Object
Set doc1 = GetObject(path)
備考
開発環境で参照設定したライブラリが、実行環境にも存在すれば、マクロは動く
開発環境と実行環境で、ライブラリのバージョンが違うとエラーとなる
→実行環境でVBEを開いて手作業で参照設定するか、開発時にVBAコードで参照設定する
互換性重視であれば、参照設定をした状態で開発を進め、完成直前に参照設定を解除してCreateObjectに変更するという考え方もある
そのような面倒をさけるため、参照設定しないという考え方もある
CreateObjectを使えば、実行環境にインストールされているバージョンのライブラリが使われる
参照設定は、Bookごとに保持されている。book1とbook2を同時に開いた場合、それぞれの参照設定が適用される
そもそも、実行環境にライブラリが存在しない場合は、実行時バインドでも動かない
アドイン
--------
ライブラリ
----------
初期設定で参照設定されているライブラリ
Excel(Microsoft Excel Object Library)
Office(Microsoft Office Object Library)
stdole(OLE Automation)
VBA(Visual Basic For Application)
MSForms(Microsoft Forms Object Library)
オートメーション
別のアプリケーションのオブジェクトを操作する仕組み