- ベストアンサー
エクセルVBAでの繰り返し処理について
- エクセルVBAで特定の作業を20回繰り返す方法について詳しく教えてください。
- 現在のコードでは、ループ処理がうまく機能していないようです。正しいループ処理の方法をお知らせください。
- ループ処理中に、「初期設定」シートの最終行のみが貼り付けられてしまう問題が発生しています。原因と解決策を教えてください。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
質問のマクロの動作だと For j = 6 To 26 For k = 4 To 384 Step 20 <<処理>> Next k Next j j=6の時にk=4 からk=384までの処理を20回繰り返す j=7の時にk=4 からk=384までの処理を20回繰り返す ・ ・ ・ j=26の時にk=4 からk=384までの処理を20回繰り返す 行っている処理は jの範囲のデータをkのセルに貼り付ける つまり変化しているjのデーターを毎回kのセルに上書きしている状態です 最終的にはjの最終データで埋め尽くされる形になります jのデータは決まったkのセルに一度だけ貼り付ければよいわけですからkのループ自体が必要ないですね 貼り付けるkのセルをjから求める形式に変えたら解決します 質問のマクロを修正すると r=0 For j = 6 To 26 Sheets("初期設定").Range(Cells(j, 1), Cells(j, 3)).Copy k=j-2+r 'ここでkの値を計算しています Sheets(TS).Cells(k, 2).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True r=r+20 '次回のkの位置を20行送るための処理 Next j こんな形
その他の回答 (6)
- Wendy02
- ベストアンサー率57% (3570/6232)
Sub MacroTest1() '元のマクロを直しました。 Dim j As Long, k As Long Const TS As String = "TS" k = 4 Application.ScreenUpdating = False For j = 6 To 26 With Worksheets("初期設定") .Range(.Cells(j, 1), .Cells(j, 3)).Copy End With With Worksheets(TS) .Cells(k, 2).PasteSpecial Paste:=xlPasteValues, _ Operation:=xlNone, _ SkipBlanks:=False, _ Transpose:=True End With k = k + 20 If k > 384 Then Exit For '?元のコードに疑問がありますが残しました。 Next j Application.ScreenUpdating = True Application.CutCopyMode = False End Sub '//別の方法 Sub MacroTest2() Dim i As Long, j As Long Dim sh As Worksheet Set sh = Worksheets("TS") j = 4 Application.ScreenUpdating = False For i = 6 To 26 With Worksheets("初期設定") sh.Cells(j, 2).Resize(3).Value = _ Application.Transpose(.Range(.Cells(i, 1), .Cells(i, 3)).Value) j = j + 20 ''If j > 384 Then Exit For 'コメントブロックを置きました。 End With Next Application.ScreenUpdating = True Set sh = Nothing End Sub '// Rangeオブジェクトの引数に、初歩的なですが、Range の引数は、オブジェクトも可能です。だから、Cells プロパティでも可能です。ただ、ミスしやすくなります。どちらかとというと、"A" & i スタイルの型のキャストを利用した文字列変換は、可読性は上がりますが、わずかなロスはあります。それは、気にするほどのことはありません。 今回のコードは、入門レベルでは気が付かない点がいくつもありますから、いくつかの人のコードをみて慣れていくしかありません。テキストだけではおぼられない実践のむつかしさだと思います。残念ながら、回答者の方も、どちらかというと、質問を読み解く側の慣れによって違いが出てしまっています。「行列を入れ替え」るテクニックは、ご質問者さんの方法と、Transpose 関数の二種類があります。もちろん、ループで入れ替える方法もあります。
お礼
いろいろとご指摘いただき、ありがとうございました。 「実践の難しさ」を日々実感しているところです。またよろしくお願いします。
- mimeu
- ベストアンサー率49% (39/79)
質問者さんは For ~ Next 文を二重につかっておられますが こういうのを入れ子のループといいます。 そのばあい、 k と j の値がどう変わっていくか、ご自分の頭で考えてください。 << それがこの問題の鍵です >> 例えば次のプログラムを実行して、 k と j の値を見れば なぜウマクいかなかったか理解されると思います。 Sub 実験 () Dim j As Integer, k As Integer For j = 6 To 26 For k = 4 To 384 Step 20 Debug.Print "k =" ; k ; " j =" ; j Next k Next j End Sub なので正解は、ループを入れ子にしないこと。 Sub 正解() Dim j As Integer, k As Integer k = 4 For j = 6 To 26 Worksheets("初期設定").Range("A" & j & ":C" & j).Copy Worksheets("TS").Range("B" & k) k = k + 20 Next j End Sub せっかく For ~ Next 文にまで挑戦されたのですから VBAの参考書を1冊、がんばって読んでみるといいですよ。 (図書館にもあります) 世界が広がりますから。
お礼
「入れ子ループ」についてご指摘いただき、ありがとうございました。 「参考書」は1冊もっていますが、なかなか読み込めていません。 「ここまで足をつっこんだら、一度しっかり勉強してみる」べきですね。 ありがとうございました。
- MRT1452
- ベストアンサー率42% (1391/3293)
修正。 for k = 1 to 95 ↓ for k = 1 to 19 基本的なところ間違ってたorz
お礼
ありがとうございました
- MRT1452
- ベストアンサー率42% (1391/3293)
実際に動かしていないので、まともに動かないかもしれませんが、 自分なら dim j as integer dim k as integer for j = 1 to 21 for k = 1 to 95 Worksheets("TS").Cells(((k-1)*20)+4, 2) = Worksheets("初期設定").Cells(j+5, 1) Worksheets("TS").Cells(((k-1)*20)+4, 3) = Worksheets("初期設定").Cells(j+5, 2) Worksheets("TS").Cells(((k-1)*20)+4, 4) = Worksheets("初期設定").Cells(j+5, 3) next k next j こうするかな。 写すデータが増えるならさらに固定させてる位置の方もループ化するとか。 実際には、20とか固定値はConst使ったりとかするけど。
お礼
ありがとうございました
- MRT1452
- ベストアンサー率42% (1391/3293)
たぶん、マクロの登録で出来たマクロを参考に作っているのだと思うけど、 きちんとしたものを作るならきちんと勉強したほうが良いですよ。 マクロの登録で出来るマクロって、無駄が多いし、汎用的には使えないことが多々あるので。 根本的にこれで出来るマクロは参考にしないこと。 値を別のシートにセットするだけなら、たとえば、 Worksheets("Sheet2").Cells(2, 2) = Worksheets("Sheet1").Cells(1, 1) こんな感じで書けば1行で済む話だし。 (ループさせるならこれにCells内の行列の指定を算出すれば良いだけ) 今後もプログラムとか組むのであれば、コピペでやるのは良くないです。 (Excelでしか使えない考え方。VBとかになると、この考え方は全く使えない。) セル1個1個を変数とみなして考えれば良いかと。 また、セルの指定の仕方も、RangeでやるのかCellsでやるのか統一した方が良いです。 まずは根本的なプログラムの基礎を叩き込んだ方が良いです。 ExcelVBAであれば、サンプルはネットを探せばゴロゴロあります。 きちんとしたプログラムの作り方に慣れれば、これがVBになってもJavaになっても基本的な考え方として、融通が利きます。
お礼
ご指摘のとおり、マクロで登録したものから作っています。 なかなか本格的なところを勉強するところまでいけずに、いつもここのような質問サイトのお世話になって なんとか乗り切っていました。 他の方からのご指摘もありましたので、もう少し自力でできるように、基礎から勉強してみます。 ありがとうございました。
- n-jun
- ベストアンサー率33% (959/2873)
Dim r1 As Range Dim r2 As Range Set r2 = Sheets(TS).Range("B4") ' TSがシート名なら ↑を↓に変更 ' Set r2 = Sheets("TS").Range("B4") For Each r1 In Sheets("初期設定").Range("A6:A25") r1.Resize(, 3).Copy r2.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=True Set r2 = r2.Offset(20) Next Set r2 = Nothing 一例です。
お礼
迅速にご回答いただき、ありがとうございました。
お礼
どこが間違っているのかまで、ご指摘をいただき、ありがとうございました。