こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

-広告-

解決済みの質問

二次元配列のVBA

二次元配列のVBAの書き方がよくわからないのですが、
私が作ったサンプルプログラムのSub 二次元()において
二次元配列で表すにはどうすればいいのでしょうか?

Sub 二次元()では
配列を格納する変数はtmpしか使っていませんが
もう一つ配列を格納する用の変数を作ればいいのでしょうか?

数字とアルファベットは別々に取り出したいです。

-----------------------------------------------------
Sub 一次元()
Dim myStr As String
Dim tmp As Variant
Dim i As Long

For i = 1 To 5
myStr = myStr & "," & i
Next

myStr = Mid(myStr, 2)
tmp = Split(myStr, ",")

For i = LBound(tmp) To UBound(tmp)
Debug.Print tmp(i)
Next i

End Sub
Sub 二次元()
Dim myStr As String
Dim tmp As Variant
Dim i As Long

For i = 1 To 5
myStr = myStr & "," & i & "と" & Chr(64 + i)
Next

myStr = Mid(myStr, 2)
tmp = Split(myStr, ",")

For i = LBound(tmp) To UBound(tmp)
Debug.Print tmp(i)
Next i

End Sub

投稿日時 - 2016-01-10 21:13:09

QNo.9109291

暇なときに回答ください

質問者が選んだベストアンサー

こんにちは。

ソースの概要(条件と具体的な処理内容)と最終的な出力方法
が判らないと何とも言えない面もありますが、
差し当たり需要がありそうな処理例で4例挙げてみます。
私の第一感では、/// j あたりのことをお求めなのかな?と思いましたが、
他の例も理解した上で目的に照らして使い分けて頂ければ、と。
例えば、/// a と /// j では、
数値なのか数字(文字列)なのか、どちらにも容易に切り替え可能です。
Split()関数に拘らずにArray()関数を使うなら、/// b と /// b でも
同様に扱えます。
ただ、区切り文字を挟んで連結された文字列がソースになる処理って
需要が多いですから、Split()関数じゃないと困る?こともあろうかと。

最終的には
 matrix(1 To 5, 1 To 2)
というサイズの二次元配列を扱うように書いていますが、
X方向のサイズ「2」が固定でない場合は、工夫が必要です。
具体的な条件を説明できるようでしたら、補足してみて下さい。

' ' /// a
' ' 予め定義した二次元配列に直接格納する場合
Sub ReW9109291a()
Dim matrix() As Variant
Dim nYSize As Long
Dim i As Long
Dim j As Long

 nYSize = 5
 ReDim matrix(1 To nYSize, 1 To 2)
 ' ' 二次元配列に直接格納する
 For i = 1 To nYSize
'  matrix(i, 1) = i ' option 1/2 数値として扱う場合
  matrix(i, 1) = CStr(i) ' option 2/2 数字文字列値として扱う場合
  matrix(i, 2) = Chr$(64 + i)
 Next i

 ' ' 二次元配列の全要素をイミディエイトウィンドウに出力
 For i = LBound(matrix) To UBound(matrix)
  Debug.? "-"; i; "-",
  For j = LBound(matrix, 2) To UBound(matrix, 2)
   Debug.? matrix(i, j),
  Next j
  Debug.?
 Next i

 ' ' デバッグ・トレース
 Stop ' ローカルウィンドウで変数の中身を(構造と要素について)確認
 ' ' 確認が済んだら[中断(デバッグ)モード]を[F5キー]で抜けて、以下を実行

 ' ' 出力例 セル範囲に出力
 With Cells(1).Resize(UBound(matrix), UBound(matrix, 2))
  .NumberFormat = "@" ' option 数字(文字列)として扱う場合
  .Value = matrix()
 End With

End Sub

' ' /// b
' ' Split()を使う例:二段配列(ジャグ配列) (数字(文字列)として扱う場合)
Sub ReW9109291b()
Dim matrix As Variant
Dim nYSize As Long
Dim i As Long
Dim j As Long

 nYSize = 5
 ReDim matrix(1 To nYSize)
 ' ' 連結文字列を取得(作成)して、一次元配列に格納
 For i = 1 To nYSize
'  matrix(i) = i & "," & chr$(64 + i)
  matrix(i) = CStr(i) & "," & Chr$(64 + i) ' 省略せずに書く場合
 Next i

 ' ' 一次元配列に格納された連結文字列をSplit()関数で一次元配列にして、
 ' ' 一次元配列の要素が一次元配列である二段配列(ジャグ配列)として配列を書き換える
 For i = 1 To nYSize
  matrix(i) = Split(matrix(i), ",")
 Next i

 ' ' 二段配列の全要素をイミディエイトウィンドウに出力
 For i = LBound(matrix) To UBound(matrix)
  Debug.? "-"; i; "-",
  For j = LBound(matrix(i)) To UBound(matrix(i))
   Debug.? matrix(i)(j),
  Next j
  Debug.?
 Next i

 Stop

 ' ' 出力例
 ' ' 一次元配列の要素が一次元配列である二段配列(ジャグ配列)を二次元配列に変換
 matrix = Application.Transpose(Application.Transpose(matrix))

 With Cells(1).Resize(UBound(matrix), UBound(matrix, 2))
  .NumberFormat = "@" ' option 数字文字列値
  .Value = matrix
 End With

End Sub

' ' /// c
' ' Split()を使う例:各行ごとに連結文字列を一旦一次元配列に格納しておいて、二次元配列に変換 (数字文字列値として扱う場合)
Sub ReW9109291c()
Dim ary() As String
Dim matrix() As Variant
Dim tmp As Variant
Dim nYSize As Long
Dim i As Long
Dim j As Long

 nYSize = 5
 ReDim ary(1 To nYSize)
 ' ' 一次元配列に連結文字列を格納する
 For i = 1 To nYSize
  ary(i) = CStr(i) & "," & Chr$(64 + i)
 Next i

 ReDim matrix(1 To nYSize, 1 To 2)
 ' ' 一次元配列の要素である連結文字列をSplit()関数で配列として分けてから二次元配列に格納する
 For i = 1 To nYSize
  tmp = Split(ary(i), ",")
  For j = 1 To 2
   matrix(i, j) = tmp(j - 1)
  Next j
 Next i

 ' ' 二次元配列の全要素をイミディエイトウィンドウに出力
 For i = LBound(matrix) To UBound(matrix)
  Debug.? "-"; i; "-",
  For j = LBound(matrix, 2) To UBound(matrix, 2)
   Debug.? matrix(i, j),
  Next j
  Debug.?
 Next i

 Stop

 ' ' 出力例
 With Cells(1).Resize(UBound(matrix), UBound(matrix, 2))
  .NumberFormat = "@" ' option 数字(文字列)
  .Value = matrix()
 End With

End Sub

' ' /// j
' ' 格納する文字列を連結しながら文字列変数に格納してEvalateメソッドでダイレクトに二次元配列にする例
Sub ReW9109291j()
Dim matrix As Variant
Dim buf As String
Dim nYSize As Long
Dim i As Long
Dim j As Long

 nYSize = 5
 ' ' 文字列を連結して文字列型変数に格納
 For i = 1 To nYSize
'  buf = buf & ";" & i & "," & """" & chr$(64 + i) & """" ' option 1/2 数値
  buf = buf & ";" & """" & i & """" & "," & """" & Chr$(64 + i) & """" ' option 2/2 数字文字列値
 Next i

 ' ' 連結文字列をExcel数式の配列表記として整形
 buf = "{" & Mid$(buf, 2) & "}"
 Debug.? "Excel数式: "; buf

 ' ' Evaluateメソッドで、二次元配列を取得
 matrix = Application.Evaluate(buf)

 ' ' 二次元配列の全要素をイミディエイトウィンドウに出力
 For i = LBound(matrix) To UBound(matrix)
  Debug.? "-"; i; "-",
  For j = LBound(matrix, 2) To UBound(matrix, 2)
   Debug.? matrix(i, j),
  Next j
  Debug.?
 Next i

 Stop

 ' ' 出力例
 With Cells(1).Resize(UBound(matrix), UBound(matrix, 2))
  .NumberFormat = "@" ' option 数字文字列値
  .Value = matrix
 End With

End Sub

' ' ///

投稿日時 - 2016-01-11 03:04:50

お礼

ありがとうございました。

投稿日時 - 2016-01-18 21:37:47

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(2)

ANo.1

001;AA1;BB1;CC1<;>
002;AA2;BB2;CC2<;>

1、まず、用意するデータは二次元配列であること。
2、次に、二次元データを取り込むSplits()を自作すること。

既存のSplit()は一次元配列でデータを格納します。ですから、二次元配列でデータを取り込むには、(Array()を利用しないのであれば)そういう関数であるSplits()を自作するしかありません。

【行と列の二次元データを取り込むSplits()の仕様】

1、データが完全な二次元であるかを検証する。
2、検証で確認した行数と列数とを変数として記憶する。
3、二次元配列変数を行数と列数とで再宣言する。
4、行データを一次言配列tmpRows()に代入する。
5、行(R)と列(C)との二重ループで二次元配列変数に取り込むことを開始。

FOR I=0 TO RowTotal
  FOR J=0 TO ColTotal
    strDatas(I, J) = CutStr(tmpRows(I), ";", J+1)
  NEXT J
NEXT I

こんな感じで行と列の二次元データを取り込むSplits()は書くことが出来ると思います。

PS、CutStr()は次のようです。

Public Function CutStr(ByVal Text As String, _
            ByVal Separator As String, _
            ByVal N As Integer) As String
  Dim strDatas() As String
  
  strDatas = Split("" & Separator & Text, Separator, , 0)
  CutStr = strDatas(N * Abs(N <= UBound(strDatas)))
End Function

CutStr()を利用すれば、Splits()のメインは5行で書けるかもです。

投稿日時 - 2016-01-10 23:37:30

お礼

ありがとうございました。

投稿日時 - 2016-01-18 21:37:48

-広告-
-広告-
-広告-
-広告-
-広告-