質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

2回答

1893閲覧

VBA 配列にループで条件に一致したものをセル範囲ごと格納したいが、エラーが表示され正しく処理が行うことができない

beggest_011

総合スコア0

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2022/05/31 06:39

編集2022/05/31 06:41

VBAについて勉強中の身で現在配列のところで躓いたためご質問させてください。

■やりたいこと
①L列目をループして空白だった場合
②セル範囲ごと配列に格納
③配列に格納した分を出力

■エラー発生点
上記のようにセル範囲ごと配列に格納していく処理を作成したものの、
『x(j) = arry』のところでエラーが表示され、正しく処理が行うことが出来ない状況です。

■エラー内容
実行時エラー(9)
インデックスが有効範囲にありません。

■試行した内容
エラー内容から『x(j)』の部分が正しくないのでは推察し、
『x(j,1)』に変換するなり色々試しました。

『x(j,1)』にしたところ最後まで処理は行えたものの、
A列目の情報しか抽出されませんでした。

正しく処理が行えた内容からして、
1~29列それぞれ分けて(x(j,1),x(j,2),x(j,3)・・・)
格納していく方法でないと処理できないのでしょうか?

他にセル範囲を条件に一致した分をループで格納していく方法ありましたら、
ご教授頂けないでしょうか。

VBA

1Dim wb As Workbook 2Set wb = ThisWorkbook 3 4Dim ws As Worksheet 5Set ws = wb.Sheets("Sheet1") 6 7Dim sRow As Long 8Dim mRow As Long 9Dim arry 10Dim x 11 12'開始行 13sRow = 4 14'終了行 15mRow = ws.Cells(Rows.Count, "B").End(xlUp).Row 16 17j = 1 18 19'L列目が空白の場合は配列へ格納 20ReDim x(1 To mRow, 1 To 29) 21 22For i = sRow To mRow 23 24 arry = ws.Range(ws.Cells(i, 1), ws.Cells(i, 29)) 25 26 If Not Cells(i, 12) = "" Then 27 28 x(j) = arry 29 30 j = j + 1 31 32 End If 33 34Next i 35 36 37'最大要素数の調整 38ReDim Preserve x(1 To UBound(x), 1 To 29) 39 40'元々セル入っていた分(A4からR最終行まで)を削除 41Range("A4:AC" & mRow).ClearContents 42 43'配列に格納している分を貼付 44Range("A4:AC" & UBound(x) + 4) = x 45

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ジャグ配列(配列の要素に配列を格納)として格納していって、Transposeで2次元配列にすれば可能です。

vba

1Sub Sample() 2 3 Dim wb As Workbook 4 Set wb = ThisWorkbook 5 6 Dim ws As Worksheet 7 Set ws = wb.Sheets("Sheet1") 8 9 Dim sRow As Long 10 Dim mRow As Long 11 Dim arry 12 Dim x 13 14 '開始行 15 sRow = 4 16 '終了行 17 mRow = ws.Cells(Rows.Count, "B").End(xlUp).Row 18 19 Dim j As Long, i As Long 20 j = 1 21 22 'L列目が空白でない場合は配列へ格納 23 ReDim x(1 To mRow) 24 25 For i = sRow To mRow 26 27 28 If Not Cells(i, 11) = "" Then 29 arry = ws.Range(ws.Cells(i, 1), ws.Cells(i, 29)) 30 31 x(j) = arry 32 33 j = j + 1 34 35 End If 36 37 Next i 38 39 '最大要素数の調整 40 ReDim Preserve x(1 To j - 1) 41 42 'ジャグ配列を2次元配列に変換 43 Dim y 44 y = WorksheetFunction.Transpose(WorksheetFunction.Transpose(x)) 45 46 '元々セル入っていた分(A4からR最終行まで)を削除 47 Range("A4:AC" & mRow).Range("A4:AC" & mRow).ClearContents 48 49 '配列に格納している分を貼付 50 Range("A4").Resize(UBound(y), UBound(y, 2)).Value = y 51 52End Sub

ただ、jinojiさんの回答のように、最初から二次元配列にして、2重ループで1セルずつ格納していく方が分かりやすいかも。

投稿2022/05/31 09:48

hatena19

総合スコア33780

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jinoji

2022/05/31 11:30

すみません。言及していただいた後に、作り替えてしまいました。 (二次元配列だとReDim Preserveがうまくいかないためです) あと、実行した結果を改めて見てみると、 実は「ループして対象行を削除」でよかったりする? とも思いました。
hatena19

2022/05/31 12:30 編集

あっ、気が付きませんでした。 ほとんど同じですね。 二次元配列だと最後の次元(列)しか増やせないですね。 私がする場合は、1時限目(行)を大きめにしておいて、代入するセル範囲の方で制限する方法を使います。 ReDim x(1 To mRow, 1 to 19) For i = sRow To mRow   If Not Cells(i, 11) = "" Then     arry = ws.Range(ws.Cells(i, 1), ws.Cells(i, 29))     For k = 1 to 29       x(j, k) = arry(1, k)     Next k     j = j + 1   End If Next i Range("A4:AC" & j + 3).Value = x
guest

0

こんな感じでどうでしょうか。

Sub test() Dim wb As Workbook Set wb = ThisWorkbook Dim ws As Worksheet Set ws = wb.Sheets("Sheet1") Dim sRow As Long Dim mRow As Long Dim arry Dim x Dim i, j '開始行 sRow = 4 '終了行 mRow = ws.Cells(Rows.Count, "B").End(xlUp).Row j = 1 'L列目が空白の場合は配列へ格納 ReDim x(1 To mRow) For i = sRow To mRow arry = ws.Range(ws.Cells(i, 1), ws.Cells(i, 29)) If Not Cells(i, 12) = "" Then x(j) = arry j = j + 1 End If Next i '最大要素数の調整 ReDim Preserve x(1 To j - 1) '元々セル入っていた分(A4からR最終行まで)を削除 Range("A4:AC" & mRow).ClearContents '配列に格納している分を貼付 Range("A4:AC" & UBound(x) + 3) = WorksheetFunction.Transpose(WorksheetFunction.Transpose(x)) End Sub

投稿2022/05/31 07:39

編集2022/05/31 09:14
jinoji

総合スコア4585

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問