2018年6月5日火曜日

【VBA】配列の結合


VBAとかってさ、いろいろ甘く作ってくれてるから、
簡単に配列を結合できるコマンドがあったりしないかな?思ったんだけど…
…どうやら無いらしいorz

そんなわけで、ぐぐってたら、配列の要素をつなげてString型にするJoin()と、
逆に、Stringをセパレータで切り分けて配列にするSplit()を組み合わせてできるらしい。

  Dim Arr_A As Variant
  Dim Arr_B As Variant
  Dim Arr_C As Variant
  
  Arr_A = Array("あ", "い")
  Arr_B = Array("う", "え", "お")
  
  Arr_C = Split(Join(Arr_A) & " " & Join(Arr_B))

要点だけ書くとこう。

ここで、やっとVariant型ってのがどーゆーモノか、わかった気がする。
…ボク、いままで、Arrayつかって配列要素書くとき、
Dim Arr_A() As Variant
って書いてたのだ。
Array()を調べたとき、Exampleがこー書かれていて、
しかも、Variant型にしか入れられませんよ。と、注釈されていたのだ。
わかった気がすると、コレで動くのもわかった気がするけど、
まず、釈然としないながらも丸写ししてたボクがゆるせず、
あの説明を書いたヤツを(2048MB省略)

つまりはVariantの変数は、アドレスが格納されている。
ArrayやSplitの返り値は、配列の先頭メモリアドレスだってーコトがやっと理解できた。
恐らくは、BooleanでもObjectでも叩き込めるのは、
Variant型に指定した変数のサイズが変わるんではなく、
参照先がかわるだけなんじゃないかな( ゚-゚)~゚(わかった気分

そんなわけでテスト

Public Sub JoinAndSplit()
  
  Dim Arr_A As Variant
  Dim Arr_B As Variant
  Dim Arr_C As Variant
  Dim i As Integer
  
  Arr_A = Array("あ", "い")
  Arr_B = Array("う", "え", "お")
  
  VerTypeCheck (Arr_C)  'Empty:Empty値 (未初期化)
  
  Debug.Print Join(Arr_A)
  Debug.Print Join(Arr_B)
  
  Arr_C = Split(Join(Arr_A) & " " & Join(Arr_B))

  For i = 0 To UBound(Arr_C)
   Debug.Print Arr_C(i)
  Next

  VerTypeCheck (Join(Arr_B)) 'String:文字列型
  VerTypeCheck (Arr_A(0))    'String:文字列型
  VerTypeCheck (Arr_C)       '配列:Variant:バリアント型 (バリアント型配列にのみ使用)

End Sub

納得の結果(*゚-゚) ちなみに、VerTypeCheck は、変数がナニモノかを知るボク作関数
てゆか返り値はStringの方が使いやすいか。なにげによく使うのでそのうち変えよう。

…はて、文字列型はコレでいいとしてIntegerだったらどーすんだろ…
と、思い、ぺぺいっと…

Public Sub JoinAndSplit2()
  
  Dim Arr_A As Variant
  Dim Arr_B As Variant
  Dim Arr_C As Variant
  Dim i As Integer
  
  Arr_A = Array(1, 2)
  Arr_B = Array(3, 4, 5)
  
  VerTypeCheck (Arr_C)  'Empty:Empty値 (未初期化)
  
  Debug.Print Join(Arr_A)
  Debug.Print Join(Arr_B)
  
  Arr_C = Split(Join(Arr_A) & " " & Join(Arr_B))

  For i = 0 To UBound(Arr_C)
   Debug.Print Arr_C(i)
  Next

  VerTypeCheck (Join(Arr_B)) 'String:文字列型
  VerTypeCheck (Arr_A(0))    'Integer:整数型
  VerTypeCheck (Arr_C)       '配列:Variant:バリアント型 (バリアント型配列にのみ使用)

End Sub

おおお、Arr_A(0)がちゃんとIntegerになってる!!
すげーぜBASIC!!

って…ホントはLongにしたかったらどーすんだよ( ゚-゚)~゚
Array()で仕込むときにcastとかで明示的にできるんだろうか。
要素の一つを明示的に宣言した変数を入れりゃいいかも…?

…疑問は尽きないが、ねむいしめんどちいので、この件はココまで(ぉぃ