ＶＢＡはじめました　- 配列・コレクション・ユーザー定義型（構造体）・クラス ｰ

###・はじめに
以下このデーターを使用したサンプルを記載します。
![rei_daata.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/f3768d61-a90c-4cf0-27dd-6fd2940d6b29.png)
#配列とユーザー定義型配列（構造体配列）
###・配列
変数名と値で一連のデーターを扱えます。
'あらかじめ扱う枠数を決めておくことができます。
```Dim a(10) As Long``` 
プログラムの途中で枠数を増やすこともできます。
```Dim b As Long
ReDim B(10)```

```vb
Sub test01()
'複数列の配列変数
 'Dim a(1 To 5, 1 To 3) As Variant
  Dim a(5, 3) As Variant
  Dim R As Long
  Dim C As Long
  Dim Ws As Worksheet
  
  Set Ws = ThisWorkbook.Worksheets("Sheet1")
  For R = 3 To 7
    For C = 2 To 4
      a(R - 2, C - 1) = Ws.Cells(R, C).Value
    Next C
  Next R
  
  Debug.Print a(2, 1)
  Debug.Print a(5, 2)
  
  Dim x As Long
  Dim Kei As Long
  x = 2
  Kei = a(x, 2) * a(x, 3)
  Debug.Print Kei
  
  Dim I As Long
  Dim GKei As Long
 'For I = 1 to 5
  For I = LBound(a, 1) To UBound(a, 1)
    GKei = GKei + a(I, 2) * a(I, 3)
  Next I
  Debug.Print GKei
'検索
  Dim srch As String
  srch = "いす"
  Kei = 0
  For I = LBound(a, 1) To UBound(a, 1)
    If a(I, 1) = srch Then
      Kei = a(I, 2)
    End If
  Next I
  Debug.Print srch & Kei
  
End Sub
```

![Class1_hennsuu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/f4ba0bdd-9435-2efd-c8b5-a92d79838b46.png)
品名、単価、個数は１，２，３と数値での指定になります。
この変数の型は、すべてVariantになります。

###・ユーザー定義型を使った配列変数

```vb
Private Type Record
  Hinmei As String
  Tanka  As Long
  Kosu As Long
End Type
Sub test03()
'ユーザー定義型を使った配列変数
  
  Dim a(5) As Record
  Dim R As Long
  Dim C As Long
  Dim Ws As Worksheet
 
  Set Ws = ThisWorkbook.Worksheets("Sheet1")
  For R = 3 To 7
    a(R - 2).Hinmei = Ws.Cells(R, 2).Text
    a(R - 2).Tanka = Ws.Cells(R, 2).Offset(0, 1).Value
    a(R - 2).Kosu = Ws.Cells(R, "D").Value
  Next R
  
  Debug.Print a(2).Hinmei
  Debug.Print a(5).Tanka
  
  Dim x As Long
  x = 2
  Debug.Print Kei(a(), x)
  
  Debug.Print GKei(a())
  
'検索
  Dim srch As String
  srch = "いす"
  Debug.Print srch & TankaSh(a(), srch)
End Sub

Function Kei(a() As Record, x As Long) As Long
  Kei = a(x).Tanka * a(x).Kosu
End Function

Function GKei(a() As Record) As Long
  'For I = 1 to 5
  For I = LBound(a, 1) To UBound(a, 1)
    GKei = GKei + a(I).Tanka * a(I).Kosu
  Next I
End Function

Function TankaSh(a() As Record, srch As String) As Long
  For I = LBound(a, 1) To UBound(a, 1)
    If a(I).Hinmei = srch Then
      TankaSh = a(I).Tanka
      Exit For
    End If
  Next I
End Function

```
![Class1_hennsuu3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/b5e111ac-511c-bfd0-5134-97fad4733521.png)
先頭にある```Type～EndType```で設定した変数のセットが```Dim a(5) As Record```によって```a()``` の下につながります。配列(test001)の時、品名、単価、個数を列の数値で指定していましたが、ここではHinmei、Kosu、Tankaと指定できるので視認性がよくなります。また```Type～EndType```内で変数の型を指定します。 

#クラスモジュール
プロジェクトの追加にクラスモジュールがあります。
ここにモジュール内で使用できる関数とか作れます。
先ほどのユーザー定義型と関連する計算（処理）をクラスにすると

```vb:BuyList&nbsp;ClassModule
'<<ByList>>
Public List As Collection 'コレクション格納用
Public Hinmei As String '品名
Public Tanka As Long  '単価
Public Kosu As Long   '個数

Property Get Self() As BuyList
  Set Self = Me
End Property

Property Get Kingaku(I As Long) As Long
  Dim Kei As Long
  With List(I)
    Kei = .Tanka * .Kosu
  End With
  Kingaku = Kei
End Property
Property Get Goukei() As Long
  Dim GKei As Long
  GKei = 0       '初期値
  Dim Item As BuyList
  For Each Item In List
    GKei = GKei + (Item.Tanka * Item.Kosu)
  Next
  Goukei = GKei
End Property
Property Get TankaSh(srch As String) As Long
  Dim Item As BuyList
  For Each Item In List
    If Item.Hinmei = srch Then
      TankaSh = Item.Tanka
      Exit For
    End If
  Next
  
End Property
```

```vb:Module1&nbsp;Module
Sub test02()
  Dim R As Long
  Dim Items As New BuyList
  Set Items.List = New Collection
  Dim Ws As Worksheet
  Set Ws = ThisWorkbook.Worksheets("Sheet1")
  
  For R = 3 To 7
    With New BuyList
      .Hinmei = Ws.Cells(R, 2).Text
      .Tanka = Ws.Cells(R, 2).Offset(0, 1).Value
      .Kosu = Ws.Cells(R, "D").Value
      Items.List.Add .Self
    End With
  Next R
  
  Debug.Print Items.List(2).Hinmei
  Debug.Print Items.List(5).Tanka
  
  Dim x As Long
  x = 2
  Debug.Print Items.Kingaku(x)
  
  Debug.Print Items.Goukei
'検索
  Dim srch As String
  srch = "いす"
  Debug.Print srch & Items.TankaSh(srch)

End Sub
```
![Class1_hennsuu2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617865/abb4ec80-0a55-a5e3-f373-436d5cc7ac30.png)
構造体と関連する計算（処理）を一つのクラスにまとめられ、修正や機能追加の時に探しやすくなる。
配列として納めるのにコレクションを使用しました。
※クラスの使い方の一例です。
#まとめ
列を数値の計算で求める場合は配列変数が扱いやすいが、クラスにすると関連する処理を1か所にまとめれるので良いと思う。

#環境
Win10　Excel for Microsoft365MSO(16)64ビット

#訂正
2020/5/27 ユーザー定義型を構造体と記載していました。