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

エクセルVBAの二重ループで最新投稿を残して表に出力する

このQ&Aのポイント
  • 今月VBAを勉強し始めた初心者が、Webで入力されたcsvファイルを編集し、最新投稿を残して表に出力するためのマクロを作成して実行したところ、変数iとjが0になるまでループが繰り返されてエラーが発生してしまいます。どこに問題があるのでしょうか?
  • エクセルVBAの二重ループを使用した最新投稿の編集と出力のマクロで、変数iとjが0になるまでループが繰り返されてエラーが発生してしまいます。具体的には、ループ範囲の指定が問題かもしれません。どのように修正すればよいでしょうか?
  • エクセルVBAの二重ループで最新投稿を残して表に出力するためのマクロを作成して実行したところ、変数iとjが0になるまでループが繰り返されてエラーが発生してしまいます。ループ範囲の指定に問題があるかもしれません。どこに修正が必要でしょうか?

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

  • ベストアンサー
  • imogasi
  • ベストアンサー率27% (4737/17069)
回答No.4

コードの不適格個所は他の回答で勉強して。 ーー 質問には、データ例を10行内外で書け。 そしてやりたいことをデータ例に沿って、文章で書け。 回答者にコードを読み解かせるようなことは少なくせよ。 質問者の意図とコードがちぐはぐであることもあり(むしろそれが多い)判りにくいコードを読まされて、よくわからないことがある。 ーー ほかに プログラムを考えるときには、処理の大枠(わたしはロジックといっている)の適当なものを考えて、捜して想を練る必要がある。 これは1週間や数個の課題では習得できないものだ。 初心者はこの段階で変なやり方で取り組み勝ち。 ーー 本件は質問の意味がよくわからないが、要らない行を削除しないで、元データは元のままで、別シートに(別列に)必要なデータを整えるという式で考えると良い。 また同じものを省くときデータをキーでソートすると、同じものは付近行に塊となってくれるので、前後を考えておれば済むことが多く、処理が簡単になることが多い。 1週間ぐらいの学習で、VBAの自分がしたいことが出来るのは立派なものだが、 むしろ重点は、他人の組んだWEBや解説書の例を多数追試して、取り入れることが大切な時期と思う。 VBAやプログラムをを甘く見ないこと。

nirapon114
質問者

お礼

理解しがたい質問をしてしまい大変申し訳ございませんでした。 オンラインゲームでのイベント運営にて参加者の表を作成する為、今回のコードを書くに至りました。 下記が例になります。 date 名前 lv  職 1   A   40  片手 2   B   40  片手 3   B   40  大剣 4   C   40  片手 5   D   40  大剣 6   E   40  片手 7   F   40  大剣 8   D   40  大剣 上記のように投稿順にデータが格納されて、名前が同じ場合に新しいもののみを残して(上記で言うと3行目と5行目のBとDを削除します)新しく表を作り直して参加者をソートする目的です。 >要らない行を削除しないで、元データは元のままで、別シートに(別列に)必要なデータを整えるという式で考えると良い。 こちらは別シート(別列)にコピーアンドペーストを行うようにするのでしょうか。 >他人の組んだWEBや解説書の例を多数追試して、取り入れることが大切な時期と思う。 >VBAやプログラムをを甘く見ないこと。 ご助言ありがとうございます。 一つだけではなく、複数の入門書にて学習し直していきます。

nirapon114
質問者

補足

皆様方のアドバイスの結果、二重ループを下記のようにすることで求めていた処理が得られました。ありがとうございます。 ただ、下記は無駄な処理が非常に多いので、もう少し手を加えて無駄を省いていきたいと思います。 ご回答者の皆様方、親身になっていただき本当にありがとうございました。 以降も学習を続けて様々なマクロを作成できるように精進してまいります。 mct = Worksheets("result").UsedRange.Rows.Count '最大行数を指定 Label1: '変数iを最終行数~2まで指定 For i = 2 To mct Name1 = Cells(i, 2).Value '名前1 Time1 = Cells(i, 1).Value '時間1 '変数jを最終行数~2まで指定 For j = 2 To mct '2列目iと2列目jが等しい(名前が同じ)場合、日時が小さい方を削除する Name2 = Cells(j, 2).Value '名前2 Time2 = Cells(j, 1).Value '時間2 If Name1 = Name2 And Time1 < Time2 Then Cells(i, 1).EntireRow.Delete GoTo Label1 End If Next Next

その他の回答 (3)

  • mu2011
  • ベストアンサー率38% (1910/4994)
回答No.3

ループの考え方が全然だめですね、Do~Loop間でName、Timeが変動しません。 考え方を少し変えてみては如何でしょうか。 例えば、(1)データを時間列で降順にソート、(2)名前列で重複削除では駄目 でしょうか。 (上記の操作をマクロ記録で一度コードを参照してみては如何でしょうか)

nirapon114
質問者

お礼

ご回答ありがとうございます。 Name及びTimeのみをIf文で処理を行ったところ削除が行われなかったり、必要のない行の削除が行われていました。 この処理の前に別の列にてソート処理を行っておりまして、そちらを流用してソートをかけ直してみようと思います。 マクロ記録という機能はまだ試したことがなかった為、一度使用して機能を把握致します。

  • mt2008
  • ベストアンサー率52% (885/1701)
回答No.2

[F8]でステップ実行してみました? 変数について変な思い違いをされている様に思います。  Name1 = Cells(i, 2).Value と、すると変数iが1,2,3と変化するたびにName1の値がCells(1, 2).Value、Cells(2, 2).Value、Cells(3, 2).Value  と変わっていく訳では有りません。代入した時点のiの値、つまりi=0で代入が行われます。 従って、  Name1 = Cells(0, 2).Value が実行され、エラーになっています。 現在のコードではループが回って0まで行ってエラーになっているのではなく、ループに入る前にエラーになっています。 今のコードをそのまま活かすなら、  Name1 = Cells(i, 2).Value '名前1  Time1 = Cells(i, 1).Value '時間1 を Do While i > 2 の下に移動し、  Name2 = Cells(j, 2).Value '名前2  Time2 = Cells(j, 1).Value '時間2 を Do While j > 2 の下に移動して見てください。

nirapon114
質問者

お礼

ご回答ありがとうございます。 Cor_moriyan様へのお礼でも記入致しましたが、iとjに初期値を与えることでその部分のエラーは解決いたしました。 その他のループ処理の考え違いを勉強しなおして再び作成していきます。

回答No.1

そもそも Do While に入る前の Name1 = Cells(i,2).Value でエラーになりませんか?この時点での i の値はゼロですし。。。 本当に > 変数i、jが0になるまでループが繰り返されてエラー となってます?もう一度、エラーの出た箇所とエラー内容を良く確認してみて下さい。 それと。 今回の様に、変数の値が一定の増減があって繰り返すような場合、For~Next の方がわかりやすいデス。   For i=mct to 2 Step -1    For j=mct to 2 Step -1     If Name1 = Name2 And Time1 > Time2 Then      Cells(j, 1).EntireRow.Delete     End If    Next   Next

nirapon114
質問者

お礼

ご回答ありがとうございます。 ループ処理に入る前にエラーが出ていたのですね・・・ 勘違いをしてしまい申し訳ございません。 i と jに初期値を与えるとその部分でのエラーは発生しなくなりました。 他の方もおっしゃっているように他にも色々と問題があるようですので再勉強をしてもう一度作成し直してみます。