この人頭いいなと思ったエピソード

ExcelでC2からデータが縦に5つずつ入力されています。
そのデータをG列(G1から開始)に横にデータをはりつけたいのですがどこがおかしいでしょうか?
添付画像は、実行した結果こうしたいという意味ではりつけてます。


エラーになる個所は

Cells(i, Q + 7) = myList(Z, 1) ' G列からK列にコピーです



全体コード↓↓

Sub 縦リストを横リストに変換()


Dim i As Long
Dim Q As Long
Dim Z As Long
Dim lastRow As Long
Dim myList As Variant

' C列のデータを配列に格納
myList = Range("C2", Range("C" & Rows.Count).End(xlUp))

' 最終行を取得
lastRow = Cells(Rows.Count, 3).End(xlUp).Row
Z = 1

' 列をループ
For i = 1 To lastRow / 5

' 配列を5つ分ループ
For Q = 0 To 4
Cells(i, Q + 7) = myList(Z, 1) ' G列からK列にコピー
Z = Z + 1
Next Q

Next i

End Sub

「VBA コードどこがおかしいですか?」の質問画像

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

  • うーん・・・

    いつも書込みありがとうございます。m(_ _"m)
    すみません。添付の図が間違っていました。実際には1行目には項目がはいっているため、やはりC2からになります。申し訳ありません。
    >myList = Range("C2", Range("C" & Rows.Count).End(xlUp))

    不思議なことに4項目のときは問題なく動いているんですが、項目を5つにすると
    稼働しなくなるんです。(GからKにはデータはきちんと表示されるのですがそのあとエラーメッセージ「インデックスが有効な範囲にありません)が表示されその後の処理が稼働しない)
    デバック内容については添付します。

    あと、関数ありがとうございます。処理はできました。
    ただデータが大量のため、関数だとファイルがかなり重くなっていました。

    何かまたアドバイスがありましたらよろしくお願いします。

    「VBA コードどこがおかしいですか?」の補足画像1
    No.1の回答に寄せられた補足コメントです。 補足日時:2024/08/30 09:45
  • 理由それだったんですね。B列に項目の文字データはあるのにC列のデータが入ってないから
    動かなかったのが判明しました。
    その箇所を行を選んで削除したらエラーメッセージでなくなりました。
    勉強になりました。
    ありがとうございました。

    No.2の回答に寄せられた補足コメントです。 補足日時:2024/08/30 13:57

A 回答 (3件)

個数の項目まで、値がきちんと埋まってないと、


エラーメッセージ「インデックスが有効な範囲にありません)が表示されます。
C列の最後のデータは、個数のある行になっていますか?
添付図の場合、C16(黄色のセル)が空白の場合、エラーになります。
「VBA コードどこがおかしいですか?」の回答画像2
この回答への補足あり
    • good
    • 0
この回答へのお礼

助かりました

お礼日時:2024/08/30 13:53

No1です。



>関数だとファイルがかなり重くなっていました。

もしも、お使いのバージョンがOffice365等であれば、G1セルに
=INDEX(C:C,ROW(OFFSET(A1,,,ROUNDUP((MAX(FILTER(ROW(C:C),C:C<>""))-1)/5,0)))*5-4+COLUMN(A1:E1))&""
の式を入力すれば、下方、右方の必要な範囲に自動でスピルされます。
(こちらなら、1セルだけの関数入力なので重くなることはないと思います)

※ 上記は、「C列に値が入っているセルまで」全て反映しますが、「5つのデータが揃っている行まで」とするなら、ROUNDUP関数をROUNDDOWN関数に変えればそのようになります。


どうしてもVBAで行いたいのなら、以下のようなものでも可能と思います。
Sub Sample()
 For r = 2 To Cells(Rows.Count, 3).End(xlUp).Row Step 5
  Cells(Int(r / 5) + 1, 7).Resize(, 5).Value = _
  Application.Transpose(Cells(r, 3).Resize(5).Value)
 Next r
End Sub

※ 上記は数式の例と同様に「C列に値が入っているセルまで」としていますが、「5つのデータが揃っている行まで」としたいのなら、For文の繰り返し制御の最大値を同様に切り捨てることで可能になります。
    • good
    • 0
この回答へのお礼

いつも書込みありがとうございますm(__)m

お礼日時:2024/09/04 10:35

こんにちは



添付図が正しいのなら、元データはC1セルから5行分ずつのはず。
これに対して、
 >myList = Range("C2", Range("C" & Rows.Count).End(xlUp))
としているので、例示の図で言えば、C2:C15の範囲の値を取得しています。
出力する際に、1行分ずれてしまうし、最後に値が存在しないのでエラーになる。
・・ということが起きていると思いますが?

とりあえず、C1セルから取得するようにすれば、意図した結果になるでしょう。


別法として、G1セルに
 =INDEX(OFFSET($C$1,ROW(A1)*5-5,0,5),COLUMN(A1))&""
の関数式を入れておいて、G:K列の適当な行までフィルコピーしておけば、
VBAを実行しなくても、入力内容が即時に反映されるようになります。
(365環境なら、配列計算式にしておけばフィルコピーも不要になります)
この回答への補足あり
    • good
    • 0

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

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


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