• 締切済み

GoTo文とかSelect文の処理の仕方に関して

Excel VBAに関しての質問です。 コードを書いていてGoTo文とかSelect Case文を使いますが、 例えば、GoTo文で飛ばされた間のコードは処理時間に影響するのでしょうか? また、Select Case文で該当しなかった命令文は処理時間に影響するのでしょうか?? 以下の命令文があります。 Sub TEST() Dim A As Long For i = 1 To 10 Cells(i, 1) = A A = A + 1 Next i GoTo B For i = 1 To 10 Cells(i, 2) = A A = A + "あ" Next i B: End Sub これ、GoTo文で飛ばさないと、「型がちがうよ!」って怒られてしまいます。 (もちろん、例えとしてで、こんなコードは、いまでは書かなくなりましたが(汗)) ということは、GoTo文で飛ばされたコードはシングルクォーテーションで くくられたことと同じになるんでしょうか? GoTo B 'For i = 1 To 10 'Cells(i, 2) = A 'A = A + "あ" 'Next i B: そもそも私のイメージでは、シングルクォーテーションで囲まれた範囲は、 演算処理とは関係なく無視されるみたいにイメージしていたんですけど、 いくら、シングルクォーテーションで囲んだとしても、その範囲が膨大に大きく多い文字数だと、 やっぱり処理時間に影響するものなのでしょうか?? Select Case文を使うときに、 Select Case 条件式 Case 条件1 すんごく長いコード Case 条件2 すんごく長いコード ・ ・ ・ End Select って、続くとします。 条件に一致していないところは演算処理に影響を及ぼさないのでしょうか?? もちろん、長いコードを書けば、ファイルのサイズは大きくなるでしょうが、演算処理の速さに影響するものなのかな??ってのがとても気になりました。 ご存じの方おりましたら、ご指南くださいませ。 ちなみに、私はまだVBAを勉強し始めてまだ間もない若輩者でして、GoTo文などは、とりあえず「ここ要らないかも」って思ったところに使用するくらいで、高度な使用の仕方はしておりません。 それと、私はExel VBAしかプログラミング言語を知らないので、VBAではこうだけど、別の言語の似た命令だと、影響したり、しなかったり。。。するよ。みたいなお話も聞けたら幸いです。 どうぞ、よろしくお願いいたします。

みんなの回答

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.5

実際にEXCEL VBAで試してみました 一方は sub macro1() Dim i as Long for i=0 to 1000000 goto b A=A+1 (以下A=A+1が合計千行) b: Next End Sub もう一方は sub macro2() Dim i as Long for i=0 to 1000000 Next End Sub 実行結果は Macro1: 1.46874429947099E-02 秒 Macro2: 1.01247155736052E-02 秒 なお、MinGWのgccで同様のコードをコンパイルすると実行時間はほとんど一緒、-O3(最大最適化)するとどちらもゼロになりました。 考察ですが、 ・goto文の間に長い実行文がある場合、ある程度実行時間に差が出る。 ・ただし、その差はわずかであり、DBアクセスやCOMオブジェクトの生成と比べると無視できるレベル と言ったところでしょうか。

SURAGOTAPI
質問者

お礼

実験していただいて恐れいります。 まだまだプログラムの組み方がへたくそで、大きなコードをひとまとまりとして、Select文で選択させて実行するようなものしかつくれなくて、もっと勉強してスマートなコードを書けるようになりたいです! ありがとうございます!

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

一部には、飛び先を毎回探すので遅くなる、という処理系もあります 昔のBasicでラベルを使ったときに、行番号指定より遅くなる、とか、先頭に書いたラベルへは速く、後に書いたラベルへは遅い、とかがありました。 遅くなるのでコメントは入れない、という技もありました。 しかし、現在の多くの処理系では、実行前処理として飛び先を調べておくので、実行速度への影響はほとんどありません。 コメントも前処理段階で無いものとして扱うので、影響はありません。 最初の例で、Goto Bがあるとエラーにならないのも、前処理の結果、A=A+"あ"の行を実行することが無いことが判明したので削除したのでしょう。

SURAGOTAPI
質問者

お礼

勉強不足ですみません。 「実行前処理」ってのをやってくれるのですね。 それと、Basic時代のお話ありがとうございました! 勉強になりました! 先の質問でのお礼文にもありましたが、 まだまだVBAプログラミングに精進している身で、 自身の注釈コメントがハンパないんですw でも、シングルクォーテーションでくくられた自身の試行錯誤記録みたいなものが、 処理に関しては影響しないことがわかりました! ありがとうございました!

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

インタープリタ・コンパイラの実際のMSの作成者が答えないと十分は判ら無いが、ソースの上でのステップで飛ばすところは実行されないと考えるほか無い。そんなことはコンパイラの仕組みでも勉強した時に考えた良いでしょう。また今はコンピュターの実行速度が速くなっているので余り考える意味はあまり無い。 コンパイラにかかって機械語になると、原形ソースの順序などずたずたに変えられる可能性もある。 知りたい欲望がもたげてくるのはわかるが、そんなことを聞いて回っても答えてくれる人にこんな質問コーナーでは出会わないと考えたほうが良かろう。

SURAGOTAPI
質問者

お礼

少しヒントを得たかっただけなんです。 私はまだ、若輩者で私が作ったコードにも無駄が多数あると思います。 そのコードに何通りかのやり方を考えて、Select Case文で分けて、Timer関数で時間を計ったときに、 Select文の該当しない部分にも演算計測がされていたらイヤだな~なんて思い、 こんな質問をしてしまいました。 興味深いご回答ありがとうございました!

  • inadomez
  • ベストアンサー率40% (9/22)
回答No.2

GoToやSelect Caseで実行されなかった命令は処理の速さに影響しません。 なぜなら実行されていないからです。 シングルクォーテーションでコメントにした行も同様です。 また大量のデータ扱う処理や余程無駄の多い処理でない限り、 今のPCのスペックでは処理時間の遅い・速いをなかなか認識できないと思います。 もし処理速度が気になるようでしたら、 オブジェクトアクセス(シートやセルへの書き込みや読み取りなど)を極力減らすことや、 ループ構造を無駄の少ないように見直してみると良いと思いますよ。

SURAGOTAPI
質問者

お礼

やっぱりExcel VBAの処理速度はシートとのやり取りですよね。 できるだけ配列にぶちこんで、結果を出力する際の体裁などは、 なるべく最後にしています。 書式設定もその値を配列にぶちこんで、最後に配列の値からシートに換算する方法でやるようにしました! ご回答ありがとうございます!

回答No.1

Basicでは、シングルクォートで始まる行は、コメントとして、コンパイル対象になりません。 したがって、「無いのと同じ」で、当然演算時間なんかありません。 gotoで飛ばしただけのコードでは、実際に実行はされなくても、コンパイルしますので、コードが生成されます(最適化処理により、削られる可能性はあるけど)。もちろん実行しないので、時間はかかりませんが。 で、該当しないcase節ですが、当然実行しないので演算処理に影響は出ないはずです。逆にそれが影響しちゃったら、困るでしょう? 現在の制御構文が充実している手続き型言語では、goto文は使わないほうが望ましいとされています。goto文を多用すると、処理の流れが掴みにくく、バグの原因になるし、後々ソースコードを読むときにも、理解を妨げるからです。

SURAGOTAPI
質問者

お礼

ご回答ありがとうございます。 プログラミング自体に慣れていなくて、 やっぱり文字数とかも演算速度に関係あるんだろうか?なんて思っていましたが、 すっきりしました。 なにせまだ日が浅いもので、コメント注釈なんかもフェルマーが言った「足りない余白」は気にならないくらい打ち込んでいるものでしてw 特に、 >逆にそれが影響しちゃったら、困るでしょう? のあたり、「そうですよねー!」って安心しちゃいました! ありがとうございました!

関連するQ&A

  • エクセルの select case文

    Dim i For i = 1 To 5 Select Case Cells(i, "A") Case "午前" Range("w1").Select Selection.Copy  Cells(i, "C").Select ActiveSheet.Paste Case "午後" Range("x1").Select Selection.Copy Cells(i, "d").Select ActiveSheet.Paste  End Select Next i Dim j For j = 1 To 5 Select Case Cells(j, "A") Case "関東" Range("y1").Select Selection.Copy  Cells(j, "e").Select ActiveSheet.Paste Case "関西" Range("z1").Select Selection.Copy Cells(i, "F").Select ActiveSheet.Paste  End Select Next i 毎回皆様にはお世話になっています。 あるセルを参照してその入力結果により 違うセルを貼り付けるマクロを組みました。 参照するセルが複数個(この例だと2セル)あるので それぞれに変数を宣言してfor nextで まわしています。 この内容を変数ひとつだけで すっきりと記述することは可能でしょうか? 参照するセルや判別する内容が増えると 記述が膨大になって マクロが 見にくくなるので 良い方法がありましたら 御教授ねがいます。

  • GOTO文がない言語・・・

    僕は最近プログラミングにハマっています。 僕が最初にプログラミングに触れたのは、DSi wereの「プチコン」というゲームを作れるソフトを残高が余っているのが理由で、興味半分でインストールした時でした。 それからプログラミングにどんどんのめり込んでいって、今は自分のホームページに Javascriptを埋め込んでみたり、Androidアプリの開発に挑戦したりしています。 そのプログラミングを楽しむ日々で、いつも疑問に思うことがあります。 「なぜプチコンの『Smile Basic』言語以外に、『GOTO文』と『ラベル』をつけることができる言語が少ないのか」 単純な上の文から実行していくプログラムのソースに、 @◯◯(◯は任意で設定できる)を書き込んでおいて、 あとの命令に『GOTO文』を記述して、同時にラベル名を指定することで、 指定したラベルの部分まで戻って、そのラベル以下の命令を繰り返し実行したり、 処理を飛ばしたりすることができます。 ところが、他の実際にアプリ開発などに使われている言語には、 『ラベル』も『GOTO文』もあまり見かけません。 どうして、簡易的な言語『Smile Basic』にあった『GOTO文』が、 他の言語にはあまり使われていないのでしょうか????

  • 下記エクセルVBAコード:改良 表

    下記エクセルVBAコードの中で Case "a" Case "b" Case "c" などの情報を処理していますが、その”a”、"b"、"c"の代わりに、$A$50~$A$52の表の中(ここにaとか入っている)のデータを用いて処理できるようにするには、どのようにコードを変更すべきでしょうか。よろしくお願いします。 Sub test01() d = Range("A65536").End(xlUp).Row j = 1 For i = 1 To d Select Case Cells(i, "a") Case "a" Case "b" Case "c" '---XXX Case Else Worksheets("Sheet2").Cells(j, "A") = Cells(i, "A") Worksheets("Sheet2").Cells(j, "B") = Cells(i, "b") 列や行やシートが変わっても、類推で変えられるでしょう。 '---YYY j = j + 1 End Select Next i End Sub

  • VBA Select Caseについて

    エクセルVBAでLike演算子とSelectCase構文を組み合わせたいのですが、以下ではエラーになってしまいます。 どう修正すればいいのでしょうか? ABCを含む文字列、DEFを含む文字列、その他、についての処理の分岐方法です。 Private Sub Worksheet_Change(ByVal Target As Range) Select Case Target.Value Case Like "*ABC*" `処理A Case Like "*DEF*" `処理B Case Else `処理C End Select End Sub

  • VBA: Select Caseを短くしたい

    Excel2003 の VBA でクラスモジュールを作成しています。 Select Case文で Caseが多い場合にコードを短くするテクニックがありませんか。 Select Case i   Case 1     str = "momo"   Case 2     str = "sakura"       ・       ・       ・   Case 100     str = "tsubaki" End Select のようなコードです。 配列に入れることも考えましたが、 str(1) = "momo" str(2) = "sakura"      ・      ・      ・ str(100) = "tsubaki" となって、コードを短くする効果は僅かです。 クラスモジュールなので、ワークシートにデータを入れておくテクニックは使えません。 また、外部ファイル(*.txt など)も管理の面から使いたくありません。 クラスモジュール内だけで完結させるテクニックがないでしょうか。

  • Select Case組み合わせ条件について

    例えば、「Aの値」&「Bの値」で処理をする場合には Select Case "A"&"B" Case "11" '(A=1&B=1の場合) で処理できると思うのですが、「B=1~5」として組み合わせることは可能でしょうか? 現在、下記のようにSelect文の中にSelectを組み合わせていますが、 どうにか上記のようにひとつのSelect文で処理できないかな~と思っています。 Select Case "A" Case 1 Select Case "B" Case 1 To 5 ご存知の方がいらっしゃいましたら、ぜひご回答の程お願いいたします。

  • select case文について

    VB6.0のSelect Case文について質問です。 現在、ある文字列(mojiretu)の中から特定の文字を検索して その文字が文字列(mojiretu)の中に存在したらチェックボックスにチェックという一連の処理を行いたいのですがうまくいきません>< このSelect Case文のどこを直すべきでしょうか? select case mojiretu case instr(mojiretu,"abc") chk1.value=1 case instr(mojiretu,"def") chk2.value=1 case else chk3.value=1 end select

  • SQLのSelect文をfor nextしたい

    Select from where文で A1~A〇(〇は可変)セルに記入されているものを検索対象にしたく、 構文を無視して希望したい完成形を大雑把に書くと aaa = Range("A1").End(xlDown).Row SQL = Select * from TBL  for i = 1 to aaa where Fld = cells(i,1) next i こうなるのですが、当然動くはずもなく。 ORやINでも予め検索する個数が固定されていないとダメなような気がするのですが どのように文を書くとよろしいのでしょうか?

  • VBAのGotoについて

    VBA実行後A1セルにカーソルを移動するため Application.Goto Range("A1") End Sub という方法と Application.Goto Reference:=Range("A1") End Sub という方法があると思うのですがどのような違いがあるのですか? 機能的には全く同じだと思うので処理的な違いですか? またその他にも同様の動作をさせるコマンドはありますか? よろしくお願いします。

  • Select Case について

    Sub dummy() Dim Dummy As Worksheet Dim SheetName As String Dim i As Integer Dim GEN As Long Dim OTA As Long With Sheets("入力") '3行目~22行目まで For i = 3 To 22 SheetName = Sheets("入力").Range("D3").Value On Error Resume Next Set Dummy = Sheets(SheetName) 'もしシートがあれば・・・ If Err.Number = 0 Then Select Case .Cells(i, 14).Value Case "TK-001" OTA = Sheets("TK-001").Range("B65536").End(xlUp).Row + 1 Sheets("TK-001").Range("B" & OTA).Value = .Cells(i, "H").Value Sheets("TK-001").Range("I" & OTA).Value = .Cells(i, "I").Value Sheets("TK-001").Range("F" & OTA).Value = .Cells(i, "K").Value Sheets("TK-001").Range("G" & OTA).Value = .Cells(i, "L").Value Sheets("TK-001").Range("J" & OTA).Value = .Cells(i, "M").Value End Select 'シートが無ければ・・・ Else '原紙をコピーする Sheets("原紙").Copy BEFORE:=Sheets(1) 'シートの名前を市場コードにする Sheets(1).Name = SheetName End If Next End With On Error GoTo 0 End Sub 上記の通りマクロを組みましたが、以下の事を行うのに悩んでいます。 (1)Select Case が100通りあるのですが、全てCaseを入れるのではなく  もっと簡単な方法はありますか?  ※『リスト』シートを作っており、B1~B100までcaseになるコードが入力されています。  例:   B    1  TK-001    2  TK-002    3  TK-003        ・        ・        ・   100   TK-100 というシートを作っています。 (2)今のマクロではどんな値でもシートがなければシートを作ってしまう状態ですが、  もし『リスト』シートの中に値があればシートを作る、無ければ作らないというマクロは可能ですか  

専門家に質問してみよう