プロが教えるわが家の防犯対策術!

ExcelVBAで質問です。初心者です。2つの離れた二次元配列を1つにしたいのですが、
3行3列、出力されるのですが、後3行3列、出力されません。配列の勉強をしているので、意味不明かもしれませんが、大変、お手数ですが、どなたか、ご存じの方、教えて頂けでしょうか?
コード↓
Sub sample2()
Dim testValues As Variant

Dim i, j As Long

testValues = Union(Range("a1:c12"), Range("f1:h12"))
ReDim Preserve testValues(1 To 12, 1 To 6)

For i = 1 To 12
For j = 1 To 6
Cells(i + 16, j) = testValues(i, j) '←上手く、出力されません
Next j
Next i
End Sub

質問者からの補足コメント

  • 写真添付の為

    「ExcelVBAで質問です。離れた二次元」の補足画像1
      補足日時:2022/07/26 19:11
  • 写真の画像が荒いため、写真を取り直しました。2つになってすみません。

    「ExcelVBAで質問です。離れた二次元」の補足画像2
      補足日時:2022/07/26 20:53
  • a1:c12の二次元配列と、f1:h12の二次元配列、この離れた2つ配列を、a17:f28の1つの二次元配列にしたいのですが、a17:c28の二次元配列になり、a17:f28になる為には、後3行3列足りません。

      補足日時:2022/07/27 18:02

A 回答 (4件)

結局「何をやりたいか?」ですよね。



今回はセル範囲が 12×3 と 12×3 でセル選択の矩形が同じなので、無理やり配列化できなくはないです。
しかし、12×3 と 4×8 みたいな場合はどうする?って話です。
また、セル範囲の行位置や列位置がずれている場合、つまり A1:C3 と F10:E100 みたいな場合はどのような2次元配列にできそうですか?
破綻しそうですよね。

↓Areas でセル範囲毎のループ回す例

Sub sampleProc()

  Dim dat_range  As Range
  Set dat_range = Range("A1:C12,F1:H12")

  '初期出力先
  Dim r_pos As Long: r_pos = 17
  Dim c_pos As Long: c_pos = 1
  
  Dim area As Range
  Dim buf  As Variant
  For Each area In dat_range.Areas
    'Areas コレクションのループはセル範囲毎のRangeを返します
    buf = area.Value
    Cells(r_pos, c_pos).Resize(UBound(buf), UBound(buf, 2)).Value = buf
    '次の書き込み先オフセット
    c_pos = c_pos + UBound(buf, 2)
  Next

End Sub

#余談

なお、Union は Range を返すプロパティーです。したがって

>testValues = Union(Range("a1:c12"), Range("f1:h12"))

は、Range のディフォルトプロパティー Value が補完され、Union(~).Value と解釈されます。結果 Variant 型変数 testValues にはセル範囲の値が2次元配列で代入されますが、この時連続しない2番目のセル範囲は無視されます。Value プロパティーの仕様ですね。
    • good
    • 2
この回答へのお礼

すみません。a1:c12,f1:h12の離れた二次元配列を、a17:f28のひとつの二次元配列にしたいのですが、出来ないですよね。

お礼日時:2022/07/27 07:34

こんばんは



目的はシートへの出力ということで良いのでしょうか?
>3行3列、出力されるのですが~
12行ではないの?

よくわからないので、「a1:c12、f1:h12の範囲を、A17:F28へ転記したい」ということと解釈しました。
すでに回答にあるように、配列に直接代入できるのは連続したセル範囲のみです。
全体を含む範囲で取得して、そこから必要な範囲を配列に抽出する方法も考えられますが、シートへの転記が目的なら、配列を介さずとも直接セル範囲を転記すれば足りますね。

ご提示の例で言うなら、
 Range("A17:C28").Value = Range("A1:C12").Value
 Range("D17:F28").Value = Range("F1:H12").Value
とすれば足りると思います。


値を配列に格納するのが目的なら、上記の転記後の範囲を配列として取得するか、あるいは以下のような方法もあります。(あるいは、ループで回して、プリミティブに代入しても勿論可能です)
https://infoment.hatenablog.com/entry/2019/10/22 …
    • good
    • 1
この回答へのお礼

ありがとうございます。

お礼日時:2022/07/26 22:55

良くわからないけどこう?


Sub sample2()
Dim testValues As Variant
Dim i, j As Long
Dim v, v2 As Variant
testValues = Push(Range("a1:c12").Value, Range("f1:h12").Value)
j = 1
For Each v In testValues
i = 16
For Each v2 In v
Cells(i, j) = v2
i = i + 1
Next
j = j + 1
Next
End Sub
Function Push(ParamArray a() As Variant) As Variant
Push = a
End Function
    • good
    • 0
この回答へのお礼

有難うございます。イメージと違うんですが、2行2列になりましたが、これは配列の勉強になります。参考になります。

お礼日時:2022/07/26 20:39

こんにちは。



離れたセル範囲は1度にValueプロパティで2次元配列化出来なかったと思います。

For Each を Areas コレクションで回してセル範囲のかたまり毎に配列に読み込む、リターンとなる配列に順次追加、これを繰り返していく形になると思います。

簡単に言えば、1回でまとめてポンとはできないです。
    • good
    • 1
この回答へのお礼

そうなんですね。調べてもなかなかどうりでなかなか出でこないんですね。有難うございます。

お礼日時:2022/07/26 20:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A