- 配列の要素を値で指定して削除する関数です。
コピペですぐ使えます。 - (例)配列[a,b,c,d]から「b」を指定して削除したい
⇒配列[a,c,d]が得られます。 - 最初に出てきた値を消すバージョンと
全ての要素を消すバージョンがあります。 - (例)配列[a,b,c,d,b,b]
最初の一つを消す⇒[a,c,d,b,b]
全部消す⇒[a,c,d]
こんにちはhokkyokunです。
配列の要素を指定して削除する関数
を紹介いたします。
配列は要素数の再宣言が面倒で
あまり使わないんだよ
特定の要素を一気に消すのも面倒だし…
配列はプログラミングの基本ですが、
VBAは配列が不親切な設計になっています。
コピペですぐ使える関数を作りましたのでご紹介します。
以下の二つの関数を作りました。
- 特定の要素を最初に現れた一つだけ消す関数
remove_Elm関数 - 特定の要素を配列から全て消す関数
remove_Elm_All関数
これらの関数を使うと以下のメリットがあります。
ググってみましたが、
配列で位置を指定して削除するコードを公開している人は多いですが、
あまり要素の値を指定して削除するコードを公開している人は少ないです。
ご自身のお仕事自動化にぜひ活用してみてください。
なぜ関数を作ったか?⇒VBAの配列は不親切
VBAと他言語の違い
VBAはお手軽に始められて、
実務の効率化に直で影響を与えることができる素晴らしいツールなのですが、
VBAは他のプログラミング言語に比べて不親切なつくり方をしている
ことが多いです。
実際に比べてみました。
下記記事は
株価データから月当たりの価格変動率を計算し、
グラフ化するプログラムを
VBAとPythonで書いてみたものです。
記事を見て頂ければわかりますが、
VBAの方が基本的にはコード量が多くなります。
それだけ、機能が不親切ということです。
配列は特にひどい
なかでもVBAの配列は特にひどいです。
試しに、配列から最初に現れた特定の要素を削除するプログラムを書いてみました。
書いててなんですが、特に中身を読まなくてもいいです(笑)
配列から削除するだけなのにとにかく長い(笑)
Sub test_remove_array()
Dim arr As Variant
Dim arrs As Variant '元になる配列。ここから特定の要素を削除する
Dim results As Variant '削除後の配列。これを求める。
Dim target As Variant '特定の要素
Dim i As Long
'適当に配列を用意
arrs = Array("a", "b", "c", "d", "b")
'ターゲットとする要素
target = "b"
'配列の要素を一つずつ確認する。
'特定の要素が現れたらFor文を抜けて次の処理に向かう
'特定の要素が現れる前の要素は全てresultsに入れる
For Each arr In arrs
If arr <> target Then
If i = 0 Then
ReDim results(i)
Else
ReDim Preserve results(i)
End If
results(i) = arr
i = i + 1
Else
Exit For
End If
Next
'targetを「b」とした場合、i=1になっているはず
'つまり、arrsの「0」番目はresultsに格納している
'i+1=2番目以降のarrsの要素を問答無用でresultsに格納する
Do While i < UBound(arrs)
If i = 0 Then
ReDim results(i)
Else
ReDim Preserve results(i)
End If
results(i) = arrs(i + 1)
i = i + 1
Loop
Dim msg As String
For Each arr In results
msg = msg & arr & ","
Next
Debug.Print Left(msg, Len(msg) - 1)
'>>a,c,d,b
End Sub
配列はプログラムの基本なのに
ただ、要素を指定して削除するだけで大変ですね。
いちいち書いていられないことだけ
理解していただければと思います。
- 配列から要素を消すコードはめんどくさい
- 普通はこんなのいちいち書いていられない
remove_Elm関数 特定の要素を一つだけ削除する関数
特定の要素のうち、最初に現れた分を削除します。
コード
こちらをコピペしてお使いください
注意点は必ずお読みください
Function remove_Elm(ByRef arrs As Variant, ByVal elm As Variant)
Dim arr As Variant
Dim results As Variant '削除後の配列。これを求める。
Dim i As Long
'配列が空の場合は何もせずに終了
If Not Is_correct_array(arrs) Then
Exit Function
End If
'配列の要素を一つずつ確認する。
'特定の要素が現れたらFor文を抜けて次の処理に向かう
'特定の要素が現れる前の要素は全てresultsに入れる
For Each arr In arrs
If arr <> elm Then
If i = 0 Then
ReDim results(i)
Else
ReDim Preserve results(i)
End If
results(i) = arr
i = i + 1
Else
Exit For
End If
Next
'特定の要素が現れた位置プラス1以降の処理です。
'問答無用でresultsに格納する
Do While i < UBound(arrs)
If i = 0 Then
ReDim results(i)
Else
ReDim Preserve results(i)
End If
results(i) = arrs(i + 1)
i = i + 1
Loop
'resultsの結果を元の配列に入れる
'=戻り値ではなく、引数が変更される
'=call remove_Elm()で使用する
arrs = results
End Function
注意点
①サブ関数
関数中にサブ関数を使っています。
Is_correct_array関数です。
配列の処理は繊細で、
空の状態だと、エラーが発生する場合があり、
配列の状態を見極める必要があります。
こちらがコードです。
Function Is_correct_array(ByVal arrs As Variant)
Dim a As Long
'なんでもいいが、エラーを生じさせる
On Error GoTo err
a = UBound(arrs)
'エラーが生じたときエラー番号で9か13の場合はFalse
err:
If err.number = 9 Or err.number = 13 Then
Is_correct_array = False
Else
Is_correct_array = True
End If
End Function

②配列の宣言の仕方
配列の宣言の仕方にはいろいろとありますが、
下記のように宣言してください。
Dim 配列名 as Variant
例えば
Dim arrs as Variant
のように宣言します。
arrsの後に()や(2)などをつけないのがポイントです。
このように宣言しないと
以下のようなエラーが発生する可能性があります。

()に数値をあらかじめ入れるのは静的配列といいます。
が、実務では全く使う機会はありません。
私は社内で大規模なシステムをVBAでくんだりもしますが、
静的配列を使う必要に迫られたことは一度もありません。
実際に使ってみます
使ってみます。
Sub test_Function_remove_Elm()
Dim arrs As Variant
arrs = Array("a", "b", "c", "d", "b", "b")
Call remove_Elm(arrs, "b")
'arrsの中身を確認
Debug.Print Join(arrs, ",")
'>>a,c,d,b,b
End Sub
remove_Elm_All関数 特定の要素を全て消す関数
コード
こちらをコピペしてお使いください
注意点は必ずお読みください
Function remove_Elm_All(ByRef arrs As Variant, ByVal elm As Variant)
Dim arr As Variant
Dim results As Variant '削除後の配列。これを求める。
Dim i As Long
'配列が空の場合処理せず終了する
If Not Is_correct_array(arrs) Then
Exit Function
End If
'特定の要素は格納せず、他の要素は全てresultsに入れる
For Each arr In arrs
If arr <> elm Then
If i = 0 Then
ReDim results(i)
Else
ReDim Preserve results(i)
End If
results(i) = arr
i = i + 1
End If
Next
arrs = results
End Function
注意点
remove_Elm関数と同様です。
こちらをご確認ください(ページ内ジャンプします)
実際に使ってみます
使ってみます。
Sub test_Function_remove_Elm_All()
Dim arrs As Variant
arrs = Array("a", "b", "c", "d", "b", "b")
Call remove_Elm_All(arrs, "b")
'arrsの中身を確認
Debug.Print Join(arrs, ",")
'>>a,c,d
End Sub
まとめ
いかがでしょうか。
まとめてみます。
- 配列から要素を指定して削除する関数を作成
- 配列から指定した要素のうち、最初の一つだけ削除する関数
remove_Elm関数 - 配列から指定した要素を全て削除する関数
remove_Elm_All関数
配列を便利に使いやすくする関数を作っています。
VBAの学習方法をまとめました。

VBAを高コスパで、短期間で学ぶにはUdemyがおすすめです。
Udemyは良質の学習プラットフォームですが、
動画数が多すぎてどれを見ればよいか迷います。
おすすめの講師をまとめました。
