vbaで構造体を関数の引数と戻値で使う
vba構造体の防備録
vbaはちょっと便利に使えるようにしようとすると途端にややこしくなる。
実はこりゃ便利、という話なんだが、最近まで困っていなかったので使わなかった。
いや、実は使ってみたのだが、速度を犠牲にしても困らないときに限るとおもう。
しっかし便利だな。これは。戻り値が簡単に複数戻せる。
以下は構造体の見本。
タイトル通り、構造体を宣言しておき、プロシージャ内部で(シートの2列を構造体配列に読み出しておき)目的の関数に構造体を引数として渡す。関数内部では配列をReDimして増やしデータを追加する。
プロシージャ内部で関数の戻り値を受け取りシートに追加(というより書き換え)している。
'---------------------------------------------------
Option Explicit
'ユーザ定義型と呼ぶらしいが、ここでは構造体と呼ぶことにする。
Type Dt '構造体の名称
name As String '名前
num As Integer '数値データ
End Type
' 構造体(変数)の受渡の見本。構造体を関数の引数に渡す。
'※下記のプロシージャ内にカーソルをおいてF5キーを押すと実行される。
Sub test()
Dim dtArray() As Dt '構造体の配列
Dim lastrow As Long: lastrow = Range("A65536").End(xlUp).Row
Dim ii As Integer
Debug.Print "これは呼出元"
'+--- 構造体の配列に読み出す ----------+
For ii = 1 To lastrow
ReDim Preserve dtArray(ii)
dtArray(ii).name = Cells(ii, 1).Value
dtArray(ii).num = Cells(ii, 2).Value
Debug.Print dtArray(ii).name, dtArray(ii).num
Next ii
Dim tmpArray() As Dt
tmpArray = hyoji(dtArray())
'+--- 関数の戻り値を表示する ----------+
Debug.Print "これは関数の戻り値"
For ii = 1 To UBound(tmpArray)
Debug.Print tmpArray(ii).name, tmpArray(ii).num
'+--- シートにもここで追加される -----+
Cells(ii, 1).Value = tmpArray(ii).name
Cells(ii, 2).Value = tmpArray(ii).num
Next ii
End Sub
' 構造体(変数)を引数として受け取り、戻り値に追加してセットする
Function hyoji(ByRef dtArray() As Dt) As Dt()
Dim ii As Integer
Dim kk As Integer
Debug.Print "これは関数内"
kk = UBound(dtArray)
For ii = 1 To kk
Debug.Print dtArray(ii).name, dtArray(ii).num
Next ii
ReDim Preserve dtArray(kk + 2) '関数内部で配列を追加した
'+--- 追加した --------------------+
dtArray(kk + 1).name = "sheet4" '追加した配列に値セット
dtArray(kk + 1).num = 500 '追加した配列に値セット
dtArray(kk + 2).name = "sheet5" '追加した配列に値セット
dtArray(kk + 2).num = 400 '追加した配列に値セット
'+--- 関数の戻り値に構造体を渡す --+
hyoji = dtArray() '戻り値セット
End Function
'---------------------------------------------------
このまま標準モジュールに貼り付けてF5キーで実行可能。
sheet1のa1,b1からa3,b3に下記のように入力しておく。
sheet1 100
sheet2 200
sheet3 300
実行するとシートに下記が追加される。
sheet3 500
sheet3 400
注)処理内容に意味はなし。
構造体のメリットは、
共通Public変数を排除できること、
引数が沢山あっても1個にまとまること。
複数の戻り値を返せるようになること。
見た目がすっきりすること。
などが挙げられる。
ま、誤解を恐れずに簡単にざっくり表現すると、
親分として構造体に子分としての個別変数がぶら下がっているイメージ。
oyabun.kobun1
oyabun.kobun2
oyabun.kobun3
配列にもできる。
oyabun(1).kobun4
以上
vbaはちょっと便利に使えるようにしようとすると途端にややこしくなる。
実はこりゃ便利、という話なんだが、最近まで困っていなかったので使わなかった。
いや、実は使ってみたのだが、速度を犠牲にしても困らないときに限るとおもう。
しっかし便利だな。これは。戻り値が簡単に複数戻せる。
以下は構造体の見本。
タイトル通り、構造体を宣言しておき、プロシージャ内部で(シートの2列を構造体配列に読み出しておき)目的の関数に構造体を引数として渡す。関数内部では配列をReDimして増やしデータを追加する。
プロシージャ内部で関数の戻り値を受け取りシートに追加(というより書き換え)している。
'---------------------------------------------------
Option Explicit
'ユーザ定義型と呼ぶらしいが、ここでは構造体と呼ぶことにする。
Type Dt '構造体の名称
name As String '名前
num As Integer '数値データ
End Type
' 構造体(変数)の受渡の見本。構造体を関数の引数に渡す。
'※下記のプロシージャ内にカーソルをおいてF5キーを押すと実行される。
Sub test()
Dim dtArray() As Dt '構造体の配列
Dim lastrow As Long: lastrow = Range("A65536").End(xlUp).Row
Dim ii As Integer
Debug.Print "これは呼出元"
'+--- 構造体の配列に読み出す ----------+
For ii = 1 To lastrow
ReDim Preserve dtArray(ii)
dtArray(ii).name = Cells(ii, 1).Value
dtArray(ii).num = Cells(ii, 2).Value
Debug.Print dtArray(ii).name, dtArray(ii).num
Next ii
Dim tmpArray() As Dt
tmpArray = hyoji(dtArray())
'+--- 関数の戻り値を表示する ----------+
Debug.Print "これは関数の戻り値"
For ii = 1 To UBound(tmpArray)
Debug.Print tmpArray(ii).name, tmpArray(ii).num
'+--- シートにもここで追加される -----+
Cells(ii, 1).Value = tmpArray(ii).name
Cells(ii, 2).Value = tmpArray(ii).num
Next ii
End Sub
' 構造体(変数)を引数として受け取り、戻り値に追加してセットする
Function hyoji(ByRef dtArray() As Dt) As Dt()
Dim ii As Integer
Dim kk As Integer
Debug.Print "これは関数内"
kk = UBound(dtArray)
For ii = 1 To kk
Debug.Print dtArray(ii).name, dtArray(ii).num
Next ii
ReDim Preserve dtArray(kk + 2) '関数内部で配列を追加した
'+--- 追加した --------------------+
dtArray(kk + 1).name = "sheet4" '追加した配列に値セット
dtArray(kk + 1).num = 500 '追加した配列に値セット
dtArray(kk + 2).name = "sheet5" '追加した配列に値セット
dtArray(kk + 2).num = 400 '追加した配列に値セット
'+--- 関数の戻り値に構造体を渡す --+
hyoji = dtArray() '戻り値セット
End Function
'---------------------------------------------------
このまま標準モジュールに貼り付けてF5キーで実行可能。
sheet1のa1,b1からa3,b3に下記のように入力しておく。
sheet1 100
sheet2 200
sheet3 300
実行するとシートに下記が追加される。
sheet3 500
sheet3 400
注)処理内容に意味はなし。
構造体のメリットは、
共通Public変数を排除できること、
引数が沢山あっても1個にまとまること。
複数の戻り値を返せるようになること。
見た目がすっきりすること。
などが挙げられる。
ま、誤解を恐れずに簡単にざっくり表現すると、
親分として構造体に子分としての個別変数がぶら下がっているイメージ。
oyabun.kobun1
oyabun.kobun2
oyabun.kobun3
配列にもできる。
oyabun(1).kobun4
以上