【エクセル】基礎構文

# 識別子
## Option Explicit
・記述あり : 変数未定義の場合、コンパイルエラーとして扱ってくれる。
・記述なし : これがない場合、未定義の変数がVariant型？として扱われ処理が進む。
・「ツール -> オプション -> 編集 -> 変数の宣言を強制する」をチェックすること自動的に挿入される。

## Erase
変数の初期化に用いる。
###
| 型 | 挙動 |
|:--|:--|
| プリミティブ型  | 初期値  |
| Variant型  | Empty値  |
| オブジェクト型  | Nothing  |
| 静的配列  | 配列の型で各要素を初期値  |
| 動的配列  | 配列に割り当てたメモリを解放  |

# 変数
## 型の種類
### プリミティブ型
・整数 : Integer, Long, LongLong
・小数 : Single , Double
・その他:Byte, Bool, Date
### オブジェクト型
・Object 　 : 全てのオブジェクト型を格納できる。初期値は<b>Nothing</b>
・Variant　：全てのオブジェクト型／プリミティブ型を格納できる。初期値は<b>Empty値</b>
## 初期値判定
```vb
  obj1 Is Nothing   'Object型が初期化されていない場合⇒True
  var1 Is Empty     'Valiant型が初期化されていない場合⇒True
```


# 演算子
## 結合演算子 「&，+」
### 説明
・& ：文字列結合
・+ ：数値なら演算，文字列なら結合
### 例
```vb
  MsgBox ("10" + "20")   ` 1020
  MsgBox (10 + 20)       ` 30
  MsgBox ("10" & "20")`  ` 1020
  MsgBox (10 & 20)`      ` 1020
```


## Like演算子
### 説明
　ワイルドカードを用いた文字列比較を行うことが可能
### ワイルドカードの種類
| 記号 | 意味 | 例 | 判定 |
|:--|:--|:--|:--|
| .  | 任意の1文字  | "300" LIKE "3.0"<br> "30" LIKE "3.0"  | TRUE <br> FALSE |
| *  | 0文字以上の文字列  | 1234" LIKE "1*4"  | TRUE  |
| #  | 半角or全角数字1文字  | "12345" LIKE "#####" <br> "１２３４５"LIKE "#####" | TRUE  |
| []  | 文字リストに含まれる1文字  | "AYC" LIKE "A[X-Z]C"  | TRUE  |
| [!] | 文字リストに含まれない1文字  | "AYC" LIKE "A[!X-Z]C"  | FALSE  |



## Variantの特徴
・Asを省略して変数宣言した場合Variant型になる。
・なんでも格納できる万能な型

# 列挙型

#### 説明
　・列挙型で変数を定義できるが、実行時にはLong型となる。(As E_TYPE = As Long)
　・値を省略した場合、0からの連番が割り振られる。
#### 定義

```vb
Enum E_TYPE
  TYPE1 = 1
  TYPE2 = 2
  TYPE3 = 3
  TYPE4 = -1
  TYPE5 = -2
End Enum

```
#### 使用
```vb
  Dim e As E_TYPE
  e = E_TYPE.TYPE4
  Dim e2 As Long
  e = E_TYPE.TYPE5
```

# クラス

#### 注意点
・プリミティブ型の場合「Let」,オブジェクト型の場合「Set」でSetterを定義する。
・フィールドの定義は一番上に書かないと、参照時に未定義エラーとなる。(C言語と同じ)

#### 定義
```vb
Option Explicit

' インスタンスフィールド
Private mParam As Integer
Private mSheet As Worksheet

' クラスのコンストラクタ
Private Sub Class_Initialize()
End Sub
' クラスのデストラクタ
Private Sub Class_Terminate()
End Sub


' Getter - Setter
Public Property Let Param(ByVal p As Integer)
    mParam = p
End Property
Public Property Get Param() As Integer
    Param = mParam
End Property

Public Property Set MySheet(s As Worksheet)
    Set mSheet = s
End Property
Public Property Get MySheet() As Integer
    MySheet = mSheet
End Property
```

#### 使用
```vb
  Dim t As New Test1Class
  t.Param = 10
  Set t.MySheet = ThisWorkbook.Worksheets("Sheet1")
```

# Withステートメント
・ドット演算子が頻発する場合、それを省略して記載することができる。

```vb
   With ThisWorkbook
    With .Worksheets("Sheet1")
      .Range("A1") = 100
      .Range("A2") = "あ"
    End With
  End With
```

# 配列
## 静的配列
### 1次元配列
・通常のプログラミング言語と違い、<b>要素数が初期値より1多くなる。</b>

```vb
  ` 定義
  Dim myArray1(10) As Long           '要素数は0 ~ 10の11個
　Dim myArray2(1 To 10) As Long      '要素数は1 ~ 10の10個
  ` 代入
  myArray1(3) = 25
```
### 2次元配列
```vb
  ` 定義
  Dim myArray1(3, 3) As Long            ' 要素数は4 * 4 = 16個
  Dim myArray2(1 To 3, 1 To 3) As Long  ' 要素数は3 * 3 = 9個
  ' 代入
  myArray1(2, 2) = 25  
```

## 動的配列
・Preserveあり:配列の値を初期化しない。
・Preserveなし:配列の値を初期化する。

```vb
  ' 要素を5個確保する
  Dim myArray() As Integer
  ReDim myArray(1 To 5)           ' 0, 0, 0, 0, 0
 
  For i = 1 To 5
    myArray(i) = i                ' 1, 2, 3, 4, 5
  Next
  
  ' 要素の値を保ったままリサイズする。
  ReDim Preserve myArray(1 To 8)  ' 1, 2, 3, 4, 5, 0, 0, 0
  
  ' 要素の値をすべて初期化しリサイズする。
  ReDim myArray(1 To 3)           '0, 0, 0
```

## 配列に関連する関数
```vb
  Dim myArray(3 To 5) As Integer
  
  'L/UBound : 配列の下限／上限のインデクス(3, 5)を取得
  MsgBox (LBound(myArray))
  MsgBox (UBound(myArray))
  
  'Array : Variant型の配列 0:10, 1:20, 2:30を返却
  Dim myArray2
  myArray2 = Array(10, "20", 3.3)

  'IsArray : 配列であればTrueを返却
  MsgBox (IsArray(myArray))
```

# コレクション
　他言語でのMap型と同様「キー」と「値」のペアの集合体
## 定義
```vb
　Dim c As New Collection
```
## 追加
```vb
  With c
    .Add Key:="Key1", Item:=10
    .Add Key:="Key2", Item:="20"
    .Add Key:="Key3", Item:=30.3
  End With
```
## 要素数
```vb
 c.Count
```
## 削除
```vb
  c.Remove ("Key1") ' キーを指定する
```

## 参照
　Collectionは複数の型が混在できるので参照する際はVariant型を使う。

```vb
  ' 単一参照 (下記はどちらも同じ値を取得できる。)
  c("Key1")
  c.Item("Key1")

  ' For Eachによる参照
  Dim elem As Variant
  For Each elem In c
    MsgBox (elem)
  Next
```

# 例外処理
### On Error GoTo 行ラベル
#### 1.メソッド呼び出しなしの場合
　OnErrorの定義以降でエラーが発生した場合、指定ラベル(ZeroDevideError)へジャンプする。

```vb
Dim i As Integer
Public Sub Main()
  On Error GoTo ZeroDevideError
  i = 1 / 0
  Exit Sub
ZeroDevideError:
  MsgBox ("0除算が行われました。")
End Sub
```

#### 2.メソッド呼び出しありの場合
　呼び出し先メソッド「Child2」で例外が発生した場合も指定ラベル(ZeroDevideError)へジャンプする。

```vb
Dim i As Integer
Public Sub Main()  
  On Error GoTo ZeroDevideError
  Call Child1  
  Exit Sub
ZeroDevideError:
  MsgBox ("0除算が行われました。")  
End Sub

Sub Child1()
  Call Child2
End Sub

Sub Child2()
  i = 1 / 0
End Sub
```

#### 3.メソッド呼び出しありの場合 (On Error再定義)
　複数回にわたってエラー定義がされた場合、<b>後述のエラー定義(LocalError)</b>が優先される。

```vb
Dim i As Integer
Public Sub Main()
  On Error GoTo ZeroDevideError
  Call Child1
  Exit Sub
ZeroDevideError:
  MsgBox ("0除算が行われました。")
End Sub

Sub Child1()
  On Error GoTo LocalError
  i = 1 / 0
LocalError:
 MsgBox ("child内でエラー発生")
End Sub
```
### On Error Resume Next
　エラーが発生した次の行から処理を継続する。
#### 1.メソッド呼び出しなしの場合
　エラーは発生せず「親：次の行」が表示される。

```vb
Dim i As Integer
Public Sub Main()
  On Error Resume Next
  i = 1 / 0
  MsgBox ("親:次の行")
End Sub
```
#### 2.メソッド呼び出しありの場合
　0除算が発生した時点でChild1は終了し、次に「親：次の行」が表示される。

```vb
Dim i As Integer
Public Sub Main()
  On Error Resume Next
  Call Child1
  MsgBox ("親:次の行")
End Sub

Public Sub Child1()
  i = 1 / 0
  MsgBox ("子:次の行1")
  MsgBox ("子:次の行2")
End Sub
```

### On Error GoTo 0
　On Error Goto, On Error Resume Nextの以下のいずれかにより有効範囲外となる。
　　・On Errorが定義されているプロシージャが終了
　　・On Errorが定義されているプロシージャ内でOn Error GoTo 0を定義した時。

```vb
Dim i As Integer
Public Sub Main()
  On Error GoTo ZeroDevideError
  i = 1 / 1
  On Error GoTo 0
  i = 1 / 0        ' ラベルへ遷移せず、エラーが発生し処理はVBAは停止する。
Exit Sub
ZeroDevideError:
  MsgBox ("0除算が行われました。")
End Sub
```

### エラー情報の参照
　エラーの情報はErrオブジェクトに格納されている。
　・Err.Number
　　　0 : エラーなし, 0以外 : エラー
　・Err.Description
　　 エラーに関するメッセージ

```vb
  On Error Resume Next
  i = 1 / 0
  If Err.Number <> 0 Then
    MsgBox ("エラー番号 : " & Err.Number)                ' 11
    MsgBox ("エラーメッセージ : " & Err.Description)     ' 0除算が行われました。
  End If
End Sub
```