VBA入門
第133回.引数の数を可変にできるパラメーター配列(ParamArray)

ExcelマクロVBAの基本と応用、エクセルVBAの初級・初心者向け解説
最終更新日:2019-10-07

第133回.引数の数を可変にできるパラメーター配列(ParamArray)


Subプロシージャー、Functionプロシージャーにおいて、
引数リストの数を特定せず、不定個数の引数を渡せるよう可変にしたい場合があります。


ワークシートの関数では、引数の個数が不定の関数が多数あります。
=SUM(数値1,数値2,...)
このように、最後が「,...」となっていて、いくつでも(限度はありますが)指定できる関数です。

マクロVBAのプロシージャーで、これと同様に引数を可変で定義するためには、
ParamArrayキーワード(パラメーター配列)を使用します。
以下では、引数の構文と名前付き引数について確認しつつParamArrayについて解説します。

引数の構文

Sub name [(arglist)]
Function name [(arglist)] [As type]

arglistは次の形式で指定します。

[Optional] [ByVal | ByRef] [ParamArray] varname[( )] [As type] [= defaultvalue]



Optional

省略可能です。
指定した引数が省略可能であることを示します。
このキーワードを指定した場合、引数 arglist のそれ以降の引数も省略可能でなければならず、すべてキーワード Optional を付けて宣言する必要があります。
キーワード ParamArray を使った場合は、どの引数に対してもキーワード Optional は指定できません。

ByVal

省略可能です。
その引数が、値渡しで渡されることを示します。

ByRef

省略可能です。
その引数が、参照渡しで渡されることを示します。
既定値は ByRef です。

ParamArray

省略可能です。
引数 arglist の最後の引数でのみ使用できます。
その引数がバリアント型 (Variant) の要素を持つ省略可能 (Optional) な 配列であることを示します。
キーワード ParamArray を使うと、任意の数の引数を渡すことができます。
ByVal、ByRef、Optional の各キーワードと共に使うことはできません。

varname

必ず指定します。
引数を表す変数名を指定します。
変数の標準的な名前付け規則に従って指定します。

type

省略可能です。
プロシージャに渡す引数のデータ型を指定します。
バイト型 (Byte)、ブール型 (Boolean)、整数型 (Integer)、長整数型 (Long)、通貨型 (Currency)、単精度浮動小数点数型 (Single)、倍精度浮動小数点数型 (Double)、10 進型 (Decimal) (現在はサポートされていません)、日付型 (Date)、文字列型 (String) (可変長のみ)、オブジェクト型 (Object)、バリアント型 (Variant) のいずれかを指定できます。
パラメータにキーワード Optional が指定されていない場合は、ユーザー定義型またはオブジェクトの種類を指定することもできます。

defaultvalue

省略可能です。
任意の定数または定数式を指定します。
キーワード Optional を指定したパラメータに対してのみ有効です。
データ型がオブジェクト型 (Object) の場合、明示的な既定値は Nothing だけです。


ByValの値渡しとは
変数の中のデータを渡すもので、呼出側の変数は影響を受けません。
つまり、値渡しでは、呼び出し先で引数の値を変更しても、呼び出し元の引数は変更されません。

ByRefの参照渡しとは
変数そのものを渡すもので、呼出側の変数が影響を受けます。
つまり、参照渡しでは、呼び出し先で引数の値を変更すると、呼び出し元の引数も変更されます。

名前付き引数について

通常、複数の引数がある場合は、その順番通りに指定します。
先頭より、
第1引数, 第2引数, 第3引数, ・・・ 
と呼びます。
しかし、
引数の数が多いと、何番目なのかを意識することは面倒になりますし混乱します。
そこで、
引数に名前を付けて、その名前で指定できるようにしてあります。
それが、
名前付き引数です。

名前付き引数を指定する場合は、
名前付き引数名:=値
このように、:=で値を指定します。

ParamArrayキーワード(パラメーター配列)とは

引数リストでキーワードParamArrayを使うと、任意の数の引数を渡すことができます。
ParamArrayキーワードは、その引数がバリアント型(Variant)の要素を持つ省略可能(Optional)な配列であることを示します。

ParamArrayキーワードの制限
引数リストの最後の引数でしか使用できない
ParamArrayキーワードを指定した引数より後ろには、他の引数を指定できません。
ByVal、ByRef、Optionalの各キーワードと共に使うことはできない
ParamArrayキーワードを指定した引数は、ByRefかつOptionalになります。
ByVal,ByRefやOptionalの指定はできません。
データ型はVaiantのみ
ParamArrayキーワードを指定した引数はVariant固定となります。
Variant以外の型を指定した場合はエラーとなります。
名前付き引数は使えません
呼び出し時に、名前付き引数と共に使う事はできません。
ParamArray引数を指定する場合には、名前付き引数を使うことはできません。
ただし、ParamArray引数を省略する場合には名前付き引数を使う事はできます。

呼び出し時に、ParamArray引数を省略した場合
IsMissing関数の戻り値がTrueとなります。
UBound関数の戻り値が-1となります。
ParamArray引数が省略されたかどうかは、上記のどちらかを使用して判断します。

ParamArrayキーワード(パラメーター配列)の使用例

以下では、ParamArrayの記述だけに特化する為、データ型は全て省略しています。

ParamArrayだけの場合
Sub sample1()
  Call sample1_sub(123, "abc", #10/7/2019#)
End Sub

Sub sample1_sub(ParamArray p())
  Dim i
  For i = LBound(p) To UBound(p)
    Debug.Print p(i)
  Next
  
  Dim v
  For Each v In p
    Debug.Print v
  Next
End Sub

For~とFor Each~の2通りサンプルになります。
ParamArray引数が省略された場合は、どちらの場合もイミディエイトには何も出力されません。

他の引数がある場合


Sub sample2()
  Call sample2_sub(123, 456, "abc")
End Sub

Sub sample2_sub(arg1, ParamArray p())
  Dim i
  For i = LBound(p) To UBound(p)
    Debug.Print p(i)
  Next
End Sub

ParamArray引数が省略された場合、
Call sample2_sub(123)
この場合はイミディエイトには何も出力されません。

ParamArray引数を省略した場合
Sub sample3()
  Call sample3_sub
End Sub

Sub sample3_sub(ParamArray p())
  If IsMissing(p) Then
    Debug.Print "引数なし"
  Else
    Debug.Print "引数あり"
  End If
  
  If UBound(p) < LBound(p) Then
    Debug.Print "引数なし"
  Else
    Debug.Print "引数あり"
  End If
End Sub

IsMissing関数で判定するほうが良いでしょう。
UBound関数で判定する場合は、-1判定でも問題ないとは思いますが、
念のためUBound < LBoundで判定するこをお勧めします。

ParamArray引数を配列で返す関数
Sub sample4()
  Dim v
  v = sample4_fnc(123, "abc", #10/7/2019#)
  Debug.Print Join(v, ",")
End Sub

Function sample4_fnc(ParamArray p()) As Variant()
  Dim i, ary
  ReDim ary(LBound(p) To UBound(p))
  For i = LBound(p) To UBound(p)
    ary(i) = p(i)
  Next
  sample4_fnc = ary
End Function

ここでは配列にして返していますが、
実際は、Functionの中で配列を使って処理する場合のサンプルです。

エラーとなる記述
VBA ParamArray 引数可変

↑名前付き引数と共用出来ません。

VBA ParamArray 引数可変

↑引数の最後にのみ指定できます。

VBA ParamArray 引数可変

↑OptionalとParamArrayは同時に使う事はできません。

VBA ParamArray 引数可変

↑配列指定は必須です。

VBA ParamArray 引数可変

↑Variant以外のデータ型は指定できません。

VBA ParamArray 引数可変

↑ByVal,ByRef指定はできません。

サイト内の関連ページ

第25回.名前付き引数について
引数とは、関数やメソッド等を呼び出すときに渡す値の指定のことです。この引数を渡す時の記述方法として、名前付き引数があります。マクロVBAでの記述では、:=が使われます。この:=は名前付き引数のみで使用される記述になります。
第107回.プロシージャーの引数
Subプロシージャー、Functionプロシージャーにおける、引数リストの指定について説明します。引数は、呼び出し先のプロシージャーに渡すデータを指定するものです。Callステートメントでプロシージャーを呼び出すときに指定する引数を、呼び出される側のプロシージャーで受け取る記述についてのVBA記述の説明になります。

値渡し、参照渡しについて(ByVal,ByRef)
ByValが値渡し、ByRefが参照渡しです。ここまでは、どこにでも書いてありますし、なんとなく理解していても、実際の活用がなかなか出来ない事が多いようです。使用例を通じて、理解して下さい。上記のsample1を実行すると、2,3の順にメッセージ表示されます。
IsMissing関数|ExcelマクロVBA関数
プロシージャを呼び出すときに省略可能なバリアント型(Variant)の引数がプロシージャに渡されたかどうかを調べるために使用します。IsMissing関数 IsMissing(argname) 引数argnameは必ず指定します。引数argnameには、プロシージャの省略可能なバリアント型(Variant)の引数の名前を指定します。
VBAクラスの作り方:独自Rangeっぽいものを作ってみた
クラスの作成は、標準モジュールで作成していた時とは様相が違い戸惑う部分も多いと思います、それは、初めてVBAに取り組んだ時の戸惑いと同じかもしれません。最初はとにかく慣れることが一番です、細かい文法や機能は、少し慣れてから改めて学んでも遅くはありません。



同じテーマ「VBA入門」の記事

第127回.他のブックのマクロを実行(Runメソッド)
第128回.マクロをショートカットで起動(OnKeyメソッド)
第129回.レジストリの操作(SaveSetting,GetSetting,GetAllSettings,DeleteSetting)
第130回.テーブル操作の概要(ListObject)
第131回.テーブル操作のVBAコード(ListObject)
第132回.その他のExcel機能(グループ化、重複の削除、オートフィル等)
第133回.引数の数を可変にできるパラメーター配列(ParamArray)
第134回.Errオブジェクトとユーザー定義エラー
第135回.ジャンプの選択オプション(SpecialCells)
第136回.フォームコントロール
第136回.ActiveXコントロール


新着記事NEW ・・・新着記事一覧を見る

SQL関数と演算子|SQL入門(12月1日)
データの取得:集約集計、並べ替え(DISTINKT,GROUP BY,ORDER BY)|SQL入門(11月30日)
データの取得:条件指定(SELECT,WHERE)|SQL入門(11月29日)
データの挿入:バルクインサート|SQL入門(11月28日)
データの挿入(INSERT)と全削除|SQL入門(11月26日)
テーブル名変更と列追加(ALTER TABLE)とテーブル自動作成|SQL入門(11月25日)
テーブルの作成/削除(CREATE TABLE,DROP TABLE)|SQL入門(11月24日)
データベースに接続/切断|SQL入門(11月23日)
SQLiteのインストール|SQL入門(11月22日)
SQL入門:VBAでデータベースを使う|エクセルの神髄(11月22日)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.RangeとCellsの使い方|VBA入門
4.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
5.変数宣言のDimとデータ型|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.マクロって何?VBAって何?|VBA入門
8.セルに文字を入れるとは(Range,Value)|VBA入門
9.空白セルを正しく判定する方法(IsEmpty,IsError,HasFormula)|VBA技術解説
10.ひらがな⇔カタカナの変換|エクセル基本操作



  • >
  • >
  • >
  • 引数の数を可変にできるパラメーター配列(ParamArray)

  • このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


    記述には細心の注意をしたつもりですが、
    間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
    掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
    掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



    このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
    本文下部へ