• ベストアンサー

エクセルのマクロでループ処理

エクセルのマクロで、ループを使っています 下の様な感じです。 sub TEST() a: re=re+1 if ○○=○▲ THEN GOTO b: 処理・・・ goto a: b: end sub() ですが、これの書き方はDo WhileやDo Untilを使った方が 早く処理できるのでしょうか? また、書き方等もお教え下されば助かります。

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

  • ベストアンサー
  • yukika-37
  • ベストアンサー率39% (26/66)
回答No.8

#1です。 変な回答をしてしまったようですね。申し訳ありません。 またもや的外れっぽいの承知で書かせていただきます。 >早く処理できるのでしょうか? 現在の処理速度を遅いと感じているのですか? でしたら参考URLを参考にしてみるとちょっと改善されるかもしれません。 While文とFor文の違いなんてミリ秒単位じゃないですかね。 初心者の方が気にするほどの差ではないと思いますが…。 あと、先ほども書きましたが、GoToは見づらいです。 先ほどのお礼に書いてあったサンプルですら「Bってどこよ?あれ、Aって?ないじゃん」という感じです。 これでコードがもっと長くなったら探すのが嫌になります。 naopon2000さんも今はいいかもしれませんが、将来メンテナンスしようとしたら大変なことになるかもしれませんし…。 なるべく早く「ラベルでループ制御」からは卒業しましょう。

参考URL:
http://www.officetanaka.net/excel/vba/speed/index.htm
naopon2000
質問者

補足

適切なご回答いたみいります。 確かにどんどん追加していくと見づらい面が多々あります。 この機会に挑戦してみたいと思います。 どうもありがとうございました!

その他の回答 (8)

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.9

#2 です。 提示されたコードの不明点が多々ありますが、ループ処理する場合にセルの挿入や削除を行うには、コードの動作が理解できていないと予期しない結果を招く事になります。 また、挿入や削除はそれなりに処理に負担が掛るので、実行速度が低下する要因になります。

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

こんにちは。 私は、#1 のBASICのようなコードがなかなか読めませんでした。何とか、VBEditor で読み直しましたが、基礎的な部分で、VBAをご存知ない方だと思います。ただ、あえていうと、GOTO を使う、とか使わないとかいうのは、今の段階では関係ないです。 問題点があるとすれば、こういう部分にあると思います。 >Cells(2, 2).Activate >Selection.Delete Shift:=xlUp つまり、セルの位置が動いていないということです。これは、初級レベルの問題ですから、できましたら、教本で確かめてください。失礼かもしれませんが、いきなり、掲示板でVBAのコードを出して質問するレベルではないと思います。入門2週目ぐらいのレベルです。今は、記録マクロに頼ってしまったほうが良いかもしれません。 実践向きのコードは、あまり早く手をつけないほうがよいです。混乱してきます。また、私自身のアドバイスとしては、VBAでセル(Cells-Range)を扱うのは、本当にややこしいです。 「こういうつもりのコードではない」という返事もいただきそうな気がします。「番号」が降順になってほしいというリクエストもあろうかとは思いますが、あえて、今は、たたき台のサンプルです。 Sub Sample1()   Dim 番号 As String   Dim FILE1 As String   Dim MyPath As String      MyPath = "C:\テスト\"   i = 1 '初期値   Do While Cells(i + 1, 2).Value <> ""          番号 = Cells(1 + i, 2).Value          If Dir(MyPath & 番号 & "a.jpg") <> "" Then       FILE1 = Dir(MyPath & 番号 & "a.jpg")       Cells(i, 1).Value = FILE1     Else       Cells(i, 3).Value = 番号     End If     i = i + 1   Loop End Sub  

naopon2000
質問者

お礼

適切なご意見ありがとうございます。 いえいえ、今は色々なコードを参照していきたいので勉強になります。 また、いろいろなマクロを参照して見易いマクロ作成を心掛けたいと思います。

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.6

#03です。#01さんの回答の補足を見ていますが、ラベルaが書かれていませんね。Sub TEST()の次になるのでしょうか? だとしても変なロジックに思います。なんかループしそうな… (B2に書かれているのはフォルダ名(番号)ですね。このフォルダにa.jpgがあれば2行目に行挿入して、FILE名を書き込み、If文の後で行削除しているようにみえる。B2が空白じゃなかったら延々と繰り返しませんか) むしろ何をやりたいのか書いてください。 例)B2~Bnセルに書かれているフォルダに*.jpgファイルがあったらファイル名をA列、フォルダ名をB列に書きだしたい。 ただしこの例のような場合は別シートに書きだす方が一般的だと思いますが…

  • uro_tan
  • ベストアンサー率15% (6/40)
回答No.5

1) GoToは使わない方が良いです。 If 番号 = "" Then GoTo B: ↓ If 番号 = "" Then Exit Sub 2) 全箇所共通ですが、Activateは不要です。処理も遅くなります。 Cells(2, 1).Activate Selection.Insert Shift:=xlDown ↓ Cells(2, 1).Insert Shift:=xlDown 3) 「A」とはどこですか?GoToを使うとコードが分かりにくくなります。 GoTo A: ↓ ???

  • zap35
  • ベストアンサー率44% (1383/3079)
回答No.4

一般的なものを3パターン書きます。(もっとありますが) Sub Macro1()  Re = 1  Do While ○○ <> ○▲   処理   Re = Re + 1  Loop End Sub ------------------------------- Sub Macro2()  Re = 1  Do   If ○○ = ○▲ Then    Exit Do   Else    処理    Re = Re + 1   End If  Loop End Sub ------------------------------- Sub Macro3()  For Re = 1 To 10000   If ○○ = ○▲ Then    Exit For   Else    処理   End If  Next Re End Sub プログラミング手法にもいろいろありますが、「プログラムの下から上へGoto文で制御を飛ばすのは好ましくない」と覚えてください。Goto文は On Error Goto文のようにエラーを引っかける場合か、Loopや処理を抜ける場合に限り使用する方が良いと思います。(Exit文がある場合はGoto文より、そちらを優先して使用する) これは後からプログラムをデバッグするために見やすくするためです。下から上へのGoto文を使用するとプログラムが動かないという意味ではありません。

  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.3

Goto文はできるだけ使わない方がいいです。 ある回数だけ処理を繰り返す場合は、 For i = 1 to 10  処理 Next とFor~Nextを使いますが、ループの終了条件が○○=○▲というような場合は、 sub TEST() Do While ○○<>○▲  re = re + 1  処理… Loop End Sub または、 sub TEST() Do Until ○○=○▲  re = re + 1  処理… Loop End Sub と書くのがよいでしょう。

naopon2000
質問者

お礼

どうもご返答ありがとうございます! 上記の処理を試してみます。

  • hana-hana3
  • ベストアンサー率31% (4940/15541)
回答No.2

>早く処理できるのでしょうか? 処理時間の問題ではありません。 近年のプログラミングでは『GOTO文 排除』が普通です。 理由は、読みやすい(理解しやすいのでミスを減らせる)プログラムにできるからです。 エラートラップなどを除いてラベル(Goto)は使っていません。 (エクセル)VBAの速度アップは、構文の組立てではなくて、記録マクロを模倣しない事などいくつもの基本があります。 xxxx.Select Selection.xxxxx xxxxx.Activete などの記述を極力減らすだけでもかなり違って来ます。 Sub TEST() Do While ○○ <> ○▲ re = re + 1 '処理・・・ Loop End Sub

naopon2000
質問者

お礼

なるほど、そうでしたか、GOTO文 排除とは・・・ 確かにgoto使わずにいけそうですね。 もう一度組み直してみます。 ありがとうございます。

  • yukika-37
  • ベストアンサー率39% (26/66)
回答No.1

処理速度以前に可読性に問題があるような…。 もしif文の条件でreの値を評価しているなら、For文とかどうでしょうか。 例えばですが… sub TEST() a: re=re+1 if re=10 THEN GOTO b: 処理・・・ goto a: b: end sub() ↓ sub TEST() For re = 1 To 10 処理・・・ Next end sub() とか。

naopon2000
質問者

補足

早速のご返答ありがとうございます。 質問の出し方が不適切でした。申し訳ありません。 if文の条件でreの値を評価してなく、厳密に記入しますと、 B2から下へ特定の番号が入ってます(数は不定期)。 SUB test() 番号 = Cells(2, 2) If 番号 = "" Then GoTo B: FILE1 = Dir("C:\テスト\" & 番号 & "a.jpg", vbNormal) If FILE1 <> "" Then Cells(2, 1).Activate Selection.Insert Shift:=xlDown Cells(2, 1).Activate Cells(2, 1) = FILE1 Else: Cells(2, 3).Activate Selection.Insert Shift:=xlDown Cells(2, 3) = 番号 End If Cells(2, 2).Activate Selection.Delete Shift:=xlUp GoTo A: B: End Sub の様な感じです。二度手間で申し訳ありません。

関連するQ&A

  • ループ処理の繰り返しについて

    お世話になっております。 単純なことで悩んでおります、どなたかわかるかたお願いいたします。 <% DO UNTIL SQLrs.EOF IF a=0 THEN %> 処理1 <% END IF SQLrs.MOVENEXT LOOP %> <% SQLrs.MOVEFIRST DO UNTIL SQLrs.EOF IF b=0 THEN %> 処理2 <% END IF SQLrs.MOVENEXT LOOP %> 上記のような処理順なのですが、問題は MoveFirstで先頭のレコードにもどらないのか、2回目のループ処理がうまく抽出できません。 原因はわかりますでしょうか?

  • Do loopのマクロ

    以下のマクロの問題点を教えていただきたいのです。 A列を上から順番に調べて、値が10のときだけBに分岐して処理を行い(処理の内容は省略してあります)、またAに戻って、空白のセルが見つかったら処理をやめる、というマクロです。 ところが、これを実行すると空白のセルが見つかってもマクロが止まりません。何が問題でしょうか。 Sub A() Cells(1, 1).Select A: Do Until ActiveCell.Value = "" If ActiveCell.Value = 10 Then GoTo B End If ActiveCell.Offset(1, 0).Select Loop B: ActiveCell.Offset(1, 0).Select GoTo A End Sub

  • 変数とループを使ったマクロについて

    恐縮ですが、ご教示をお願い致します。 comboboxの値を空白のtextboxに貼り付けるものです。 本を片手にマクロを作成していたのですが、上手くいかず困っております。 作成したマクロ Private Sub CommandButton100_Click() '入力値のチェック If ComboBox1 = "" Or ComboBox2 = "" Then GoTo 998 '空白ボックスを検索しデータ入力 If TextBox11 = "" And TextBox12 = "" Then TextBox11 = ComboBox1 TextBox12 = ComboBox2 GoTo 999 End If If TextBox21 = "" And TextBox22 = "" Then TextBox21 = ComboBox1 TextBox22 = ComboBox2 GoTo 999 End If If TextBox31 = "" And TextBox32 = "" Then TextBox31 = ComboBox1 TextBox32 = ComboBox2 GoTo 999 End If ↓ ↓  以下50個あります。 ↓ If TextBox501 = "" And TextBox502 = "" Then TextBox501 = ComboBox1 TextBox502 = ComboBox2 GoTo 999 End If 998 MsgBox "入力値に誤りがあります 999 End Sub とてつもなく長くなってしまいました。 変数をループを使って色々やってみたのですが、どうにもならず。。。 簡単に変数及びループを使用して纏める事は出来る物なのでしょうか? よろしくお願いいたします。

  • EXCELマクロ

    下記は0~9が重複せずに3つ、順番も考慮してシートに出すものです。 いわゆる=PERMUT(10,3)、数学で言えば10P3を力技で求めるもの。 さて、3つ程度のループなら下記のようにifを書いても良いのですが これが多重になればなるほど、ifが増えるので面倒になります。 なにか賢いアルゴリズムあったらご教示ください。 (使用目的は頭の体操、例えばポーカーの役の1回目に出る確率とかです。  本計算とは関係ありませんが、理屈で考えたものを検証したい為です。) Sub test() r = 2 For a = 0 To 9 For b = 0 To 9 If b = a Then GoTo 10 For c = 0 To 9 If c = a Then GoTo 20 If c = b Then GoTo 20 Cells(r, 1) = a Cells(r, 2) = b Cells(r, 3) = c r = r + 1 20 Next 10 Next Next End Sub

  • エクセルVBAで無限ループ

    教えてください。 以下の2つのエクセルマクロはまったく同じことをさせようとしているのですが、test02の方は.Offset(1).Activateが働かないのか、無限ループに陥ってしまいます。 単にActiveCell.という記述をWith~End Withでまとめただけなのになぜこうなるのでしょうか? Sub test01() ActiveSheet.Cells(1, 1).Activate Do While ActiveCell.Value <> "" If Not IsNumeric(ActiveCell.Value) Then ActiveCell.Offset(0, 1).Value = "文字" ElseIf ActiveCell.Value > 0 Then ActiveCell.Offset(0, 1).Value = "正数" ElseIf ActiveCell.Value < 0 Then ActiveCell.Offset(0, 1).Value = "負数" Else ActiveCell.Offset(0, 1).Value = "その他" End If ActiveCell.Offset(1).Activate i = i + 1 Application.StatusBar = i Loop End Sub Sub test02() ActiveSheet.Cells(1, 1).Activate With ActiveCell Do While .Value <> "" If Not IsNumeric(.Value) Then .Offset(0, 1).Value = "文字" ElseIf .Value > 0 Then .Offset(0, 1).Value = "正数" ElseIf ActiveCell.Value < 0 Then .Offset(0, 1).Value = "負数" Else .Offset(0, 1).Value = "その他" End If .Offset(1).Activate i = i + 1 Application.StatusBar = i Loop End With End Sub

  • Do whileでExitせず、ループの最初に戻る方法

    よろしくお願いします。 環境 Excel 2003 Do whileのループ内で、Exitのような記述方法で、ループの最初に戻る方法はありますでしょうか? イメージは以下のような形です。 Sub hoge() r = 0 rr = 5 Do While r < 6 'ここに戻る If r = 3 Then 'ここでDo while の最初に戻る End If Loop End Sub よろしくお願いいたします。

  • マクロでの次の実行マクロへの記述

    下記のマクロを記述しました。 一つのマクロ処理を終わらせて、次のマクロ(例:test)を動かしたいのですが何処に 記述したら良いかわかりません。 教えてください。 Sub Macro1() Dim i As Integer Dim buff As String i = 2 While 1 If Range("B" & i).Value = "" Then End End If buff = Range("B" & i).Value Range("B" & i).Value = Left(buff, 7) + " " + Mid(buff, 8, 5) + " " + Right(buff, 6) i = i + 1 Wend   Call test →ここに仮に記述したのですが、testのマクロに行きません。 End Sub 以上

  • エクセル マクロ ループ ファイル展開

    マクロ ループ処理について質問です。 test エクセルファイルのD1セルから下にファイル名を入れていき、その名前(フルパスで入れています)のファイルを開きつつ、シートを 26-4 に選択していくループ処理をしたいのですが、2週目から Sheets("26-4").Select  でエラーになります。 原因は、test ファイルがアクティブになっているからだと思うのですが、その対策の仕方が、検索してもうまく見つからなかったので、質問しました。 ご回答よろしくお願いします。 エクセル2010 使用しております。 Range("D1").Select i = 1 Do Until ActiveCell.Value = "" Workbooks.Open Filename:=Range("D" & i) '操作事項マクロ Sheets("26-4").Select Windows("test.xlsm").Activate ActiveCell.Offset(1, 0).Select '下にずれる i = i + 1 Loop End Sub

  • エクセルのVBA、ループ処理について

    if文とループ処理をどう組み合わせればいいのかわかりません 以下のコードで、iの数をを増やしていく処理を行いたいのですが、エラーがでてしまいうまくいきません どのように書けばいいのでしょうか 教えてください For i = 2 To 11 If Cells("4,i") > 80 Then Cells("5,i").Value = "A" ElseIf Cells("4,i") > 70 Then Cells("5,i").Value = "B" ElseIf Cells("4,i") > 60 Then Cells("5,i").Value = "C" Else Cells("4,i").Value = "D" End If Next

  • エクセルのHTMLのループ取得でフリーズする

    標題の件で、エクセルのマクロでMSHTMLを用いてあるサイトの1ページ目、2ページ目・・・とループ処理でHTMLを取得する際、3回目以上のループからマクロがフリーズ(フリーズする際のループ回数はランダムです)してしまいまい、フリーズせずに全ページを取得できるようにプログラムを直したいです。 【使用プログラム】※・・・は記載省略 ' ' // ・・・ Sub sample() ・・・ Do While ・・・ ・・・ Call untilReady(htmlDoc) ・・・ Loop End Sub Sub untilReady・・・ ※このSubの中身はサイト"エクセルの神髄"様  (http://excel-ubara.com/excelvba5/EXCELVBA222.html)  の"MSHTML.HTMLDocumentを使った方法です。"記載部の  Sub untilReady~End Subまでとほぼ同じで、  DoEventsとIf Now()~の間に sleep 100 を入れています ・・・End Sub ' ' // 回答者にはお礼しか言うことが出来ませんが、よろしくお願いします。

専門家に質問してみよう