VBAにおける配列操作　配列削除、追加。汎用モジュール化して開発効率UP！

## 導入
VBAで重い処理といったら、ワークシートのセル操作です。ひとつずつセルに値を入れていくとトンデもない処理時間になります。
そういった場合は配列をつかって処理してください。
配列とは？→youtubeでたくさん配列解説動画があるのでご覧になってください。
おすすめ→https://www.youtube.com/watch?v=-0X2p8hhzNE
配列の考え方は他のプログラミング言語でも役立ちますのでこの際学習しましょう。学習コスパいいです。
## 配列操作をモジュール化してしまおう。
配列は覚えたけど、配列のある行or列を削除したい。追加したい。切り出したい。など思ってくる人、いらっしゃるのではないでしょうか。
ここからの記事はそういった人が対象となります。

率直に書きますが配列操作を汎用モジュール化します。まずプログラム全体を紹介。後で詳細に説明します。
今紹介するものは、このプログラムは賢い方が作成されたもので、それらを使いやすいようにまとめただけです。
``` 


Function ArrayRemove(ByRef arr As Variant, ByVal num As Long)
'一次元配列で〇番目の指定要素を削除する
Dim i As Long
'削除したいn番目の要素以降を前に詰めて上書きする。
For i = num To UBound(arr) - 1
    arr(i) = arr(i + 1)
Next i

'配列を再定義し、最終の要素を詰める
ReDim Preserve arr(UBound(arr) - 1)

ArrayRemove = arr
End Function

'■二次元配列内の〇番目の行を削除する
Public Function Call_Array2D_Remove(arr As Variant, DelRow As Long)
     
    Dim rMin As Long: rMin = LBound(arr, 1)
    Dim rMax As Long: rMax = UBound(arr, 1)
    Dim cMin As Long: cMin = LBound(arr, 2)
    Dim cMax As Long: cMax = UBound(arr, 2)
     
    '■縦方向の要素を最大値-1で1行少ない状態で定義
    Dim temp As Variant
    ReDim temp(rMin To rMax - 1, cMin To cMax)
                     
    Dim R As Long               '二次元配列のRow要素
    Dim C As Long               '二次元配列のColumn要素
    Dim i As Long: i = rMin     '二次元配列のRow要素(元配列arr)
     
    For R = rMin To rMax - 1
        '■配列要素が削除行ならi+1をして飛ばす
        If R = DelRow Then
            i = i + 1
        End If
        For C = cMin To cMax
            temp(R, C) = arr(i, C)
        Next C
        i = i + 1
    Next R
     
    Call_Array2D_Remove = temp
End Function


'■二次元配列内の〇番目の列を削除する
Public Function Call_Array2D_RemoveColumn(arr As Variant, DelCol As Variant)
     
    Dim rMin As Long: rMin = LBound(arr, 1)
    Dim rMax As Long: rMax = UBound(arr, 1)
    Dim cMin As Long: cMin = LBound(arr, 2)
    Dim cMax As Long: cMax = UBound(arr, 2)
     
    '■横方向の要素を最大値-1で1行少ない状態で定義
    Dim temp As Variant
    ReDim temp(rMin To rMax, cMin To cMax - 1)
                     
    Dim R As Long               '二次元配列のRow要素
    Dim C As Long               '二次元配列のColumn要素
    Dim i As Long: i = rMin     '二次元配列のColumn要素(元配列arr)
     
    '■配列要素が削除列ならi+1をして飛ばす
    For R = rMin To rMax
        For C = cMin To cMax - 1
            If C = DelCol Then
                i = i + 1
            End If
            temp(R, C) = arr(R, i)
            i = i + 1
        Next C
            i = rMin
    Next R
 
    Call_Array2D_RemoveColumn = temp
End Function

'■2次元配列の1次元目を増やすモジュール
Public Function Call_ArraySizeUp(arr As Variant, sLen As Long)
 
    '■仮配列tmpを作る
    Dim tmp As Variant
    ReDim tmp(LBound(arr, 1) To sLen, LBound(arr, 2) To UBound(arr, 2))
     
    '■forでarr→tmpに入れる(最終行は空白)
    Dim i As Long, j As Long
    For i = LBound(arr, 1) To UBound(arr, 1)
        For j = LBound(arr, 2) To UBound(arr, 2)
            tmp(i, j) = arr(i, j)
        Next
    Next
 
    Call_ArraySizeUp = tmp
End Function

'二次元配列で〇番目の指定列に空白列を追加する
Public Function Call_Array2D_addColums(tmp1 As Variant, num As Long)
'引数1配列、引数2指定列番号
Dim tmp2 As Variant

'元の配列(tmp1)より一つ大きく定義する。
ReDim tmp2(UBound(tmp1, 1), UBound(tmp1, 2) + 1)

Dim fig As Long: fig = 0
Dim R As Long
Dim C As Long

For C = LBound(tmp1, 2) To UBound(tmp1, 2) + 1
    If C = num Then
        For R = LBound(tmp1, 1) To UBound(tmp1, 1)

            tmp2(R, C) = ""
        Next
    fig = 1

    Else
        For R = LBound(tmp1, 1) To UBound(tmp1, 1)
            tmp2(R, C) = tmp1(R, C - fig)
        Next
    End If
Next

Call_Array2D_addColums = tmp2

End Function
``` 

----------------
まず一つ目から紹介します
``` 
Function ArrayRemove(ByRef arr As Variant, ByVal num As Long)
'一次元配列で〇番目の指定要素を削除する
Dim i As Long
'削除したいn番目の要素以降を前に詰めて上書きする。
For i = num To UBound(arr) - 1
    arr(i) = arr(i + 1)
Next i

'配列を再定義し、最終の要素を詰める
ReDim Preserve arr(UBound(arr) - 1)

ArrayRemove = arr
End Function
``` 
'一次元配列で〇番目の指定要素を削除する関数です。
呼び出す際は、
``` 
arr = ArrayRemove(arr,2)
``` 
みたいな感じで、arrの2行目を削除したものをarrに入れるイメージです。

-------
2つ目、
``` 
'■二次元配列内の〇番目の行を削除する
Public Function Call_Array2D_Remove(arr As Variant, DelRow As Long)
     
    Dim rMin As Long: rMin = LBound(arr, 1)
    Dim rMax As Long: rMax = UBound(arr, 1)
    Dim cMin As Long: cMin = LBound(arr, 2)
    Dim cMax As Long: cMax = UBound(arr, 2)
     
    '■縦方向の要素を最大値-1で1行少ない状態で定義
    Dim temp As Variant
    ReDim temp(rMin To rMax - 1, cMin To cMax)
                     
    Dim R As Long               '二次元配列のRow要素
    Dim C As Long               '二次元配列のColumn要素
    Dim i As Long: i = rMin     '二次元配列のRow要素(元配列arr)
     
    For R = rMin To rMax - 1
        '■配列要素が削除行ならi+1をして飛ばす
        If R = DelRow Then
            i = i + 1
        End If
        For C = cMin To cMax
            temp(R, C) = arr(i, C)
        Next C
        i = i + 1
    Next R
     
    Call_Array2D_Remove = temp
End Function
``` 

二次元配列内の〇番目の行を削除する関数です。
使い方は、
``` 
arr = Call_Array2D_Remove(arr,2)
``` 
みたいな感じで、arrの2行目を削除したものをarrに入れるイメージです。

---------------------
3つ目、
``` 
'■二次元配列内の〇番目の列を削除する
Public Function Call_Array2D_RemoveColumn(arr As Variant, DelCol As Variant)
     
    Dim rMin As Long: rMin = LBound(arr, 1)
    Dim rMax As Long: rMax = UBound(arr, 1)
    Dim cMin As Long: cMin = LBound(arr, 2)
    Dim cMax As Long: cMax = UBound(arr, 2)
     
    '■横方向の要素を最大値-1で1行少ない状態で定義
    Dim temp As Variant
    ReDim temp(rMin To rMax, cMin To cMax - 1)
                     
    Dim R As Long               '二次元配列のRow要素
    Dim C As Long               '二次元配列のColumn要素
    Dim i As Long: i = rMin     '二次元配列のColumn要素(元配列arr)
     
    '■配列要素が削除列ならi+1をして飛ばす
    For R = rMin To rMax
        For C = cMin To cMax - 1
            If C = DelCol Then
                i = i + 1
            End If
            temp(R, C) = arr(R, i)
            i = i + 1
        Next C
            i = rMin
    Next R
 
    Call_Array2D_RemoveColumn = temp
End Function
``` 
二次元配列内の〇番目の列を削除する関数です。
使い方は、
``` 
arr = Call_Array2D_RemoveColumn(arr,3)
``` 
みたいな感じで、arrの3列目を削除したものをarrに入れるイメージです。

---------------------
4つ目、
``` 
'■2次元配列の1次元目を増やすモジュール
Public Function Call_ArraySizeUp(arr As Variant, sLen As Long)
 
    '■仮配列tmpを作る
    Dim tmp As Variant
    ReDim tmp(LBound(arr, 1) To sLen, LBound(arr, 2) To UBound(arr, 2))
     
    '■forでarr→tmpに入れる(最終行は空白)
    Dim i As Long, j As Long
    For i = LBound(arr, 1) To UBound(arr, 1)
        For j = LBound(arr, 2) To UBound(arr, 2)
            tmp(i, j) = arr(i, j)
        Next
    Next
 
    Call_ArraySizeUp = tmp
End Function
``` 

2次元配列の〇番目に1次元目を増やす関数です。つまり行を増やす。
使い方は、
```
arr = Call_ArraySizeUp(arr,4)
```
2次元配列arrの4行目に新しい行を挿入して、それをarrとするイメージ。

-------------------------
5つ目、
```
'二次元配列で〇番目の指定列に空白列を追加する
Public Function Call_Array2D_addColums(tmp1 As Variant, num As Long)
'引数1配列、引数2指定列番号
Dim tmp2 As Variant

'元の配列(tmp1)より一つ大きく定義する。
ReDim tmp2(UBound(tmp1, 1), UBound(tmp1, 2) + 1)

Dim fig As Long: fig = 0
Dim R As Long
Dim C As Long

For C = LBound(tmp1, 2) To UBound(tmp1, 2) + 1
    If C = num Then
        For R = LBound(tmp1, 1) To UBound(tmp1, 1)

            tmp2(R, C) = ""
        Next
    fig = 1

    Else
        For R = LBound(tmp1, 1) To UBound(tmp1, 1)
            tmp2(R, C) = tmp1(R, C - fig)
        Next
    End If
Next

Call_Array2D_addColums = tmp2

End Function
```

2次元配列の〇番目に2次元目を増やす関数です。つまり列を増やす。
使い方は、
```
arr =Call_Array2D_addColums(arr,4)
```
2次元配列arrの4列目に新しい列を挿入して、それをarrとするイメージ。