• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:エクセルVBA での繰り返し処理について)

エクセルVBAでの繰り返し処理について

このQ&Aのポイント
  • エクセルVBAで特定の作業を20回繰り返す方法について詳しく教えてください。
  • 現在のコードでは、ループ処理がうまく機能していないようです。正しいループ処理の方法をお知らせください。
  • ループ処理中に、「初期設定」シートの最終行のみが貼り付けられてしまう問題が発生しています。原因と解決策を教えてください。

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

  • ベストアンサー
  • web2525
  • ベストアンサー率42% (1219/2850)
回答No.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 こんな形

AMEFURIO
質問者

お礼

どこが間違っているのかまで、ご指摘をいただき、ありがとうございました。

その他の回答 (6)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.6

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 関数の二種類があります。もちろん、ループで入れ替える方法もあります。

AMEFURIO
質問者

お礼

いろいろとご指摘いただき、ありがとうございました。 「実践の難しさ」を日々実感しているところです。またよろしくお願いします。

  • mimeu
  • ベストアンサー率49% (39/79)
回答No.5

質問者さんは 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冊、がんばって読んでみるといいですよ。 (図書館にもあります) 世界が広がりますから。

AMEFURIO
質問者

お礼

「入れ子ループ」についてご指摘いただき、ありがとうございました。 「参考書」は1冊もっていますが、なかなか読み込めていません。 「ここまで足をつっこんだら、一度しっかり勉強してみる」べきですね。 ありがとうございました。

  • MRT1452
  • ベストアンサー率42% (1391/3293)
回答No.4

修正。 for k = 1 to 95 ↓ for k = 1 to 19 基本的なところ間違ってたorz

AMEFURIO
質問者

お礼

ありがとうございました

  • MRT1452
  • ベストアンサー率42% (1391/3293)
回答No.3

実際に動かしていないので、まともに動かないかもしれませんが、 自分なら 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使ったりとかするけど。

AMEFURIO
質問者

お礼

ありがとうございました

  • MRT1452
  • ベストアンサー率42% (1391/3293)
回答No.2

たぶん、マクロの登録で出来たマクロを参考に作っているのだと思うけど、 きちんとしたものを作るならきちんと勉強したほうが良いですよ。 マクロの登録で出来るマクロって、無駄が多いし、汎用的には使えないことが多々あるので。 根本的にこれで出来るマクロは参考にしないこと。 値を別のシートにセットするだけなら、たとえば、 Worksheets("Sheet2").Cells(2, 2) = Worksheets("Sheet1").Cells(1, 1) こんな感じで書けば1行で済む話だし。 (ループさせるならこれにCells内の行列の指定を算出すれば良いだけ) 今後もプログラムとか組むのであれば、コピペでやるのは良くないです。 (Excelでしか使えない考え方。VBとかになると、この考え方は全く使えない。) セル1個1個を変数とみなして考えれば良いかと。 また、セルの指定の仕方も、RangeでやるのかCellsでやるのか統一した方が良いです。 まずは根本的なプログラムの基礎を叩き込んだ方が良いです。 ExcelVBAであれば、サンプルはネットを探せばゴロゴロあります。 きちんとしたプログラムの作り方に慣れれば、これがVBになってもJavaになっても基本的な考え方として、融通が利きます。

AMEFURIO
質問者

お礼

ご指摘のとおり、マクロで登録したものから作っています。 なかなか本格的なところを勉強するところまでいけずに、いつもここのような質問サイトのお世話になって なんとか乗り切っていました。 他の方からのご指摘もありましたので、もう少し自力でできるように、基礎から勉強してみます。 ありがとうございました。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.1

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 一例です。

AMEFURIO
質問者

お礼

迅速にご回答いただき、ありがとうございました。

関連するQ&A

専門家に質問してみよう