- ベストアンサー
ExcelのVBAでGoToの代わりに…
お世話になっています よく、gotoは悪名高いとか、使わないほうが良いとか言われていますが、何故なのでしょう?? 使わないようにしようと思っても、別の方法がわからず使ってしまっています。 例えば、「aaa」というシートがあるかどうか調べ、なければ作成するとした場合、 Dim myWS As Object For Each myWS In Worksheets If myWS.Name = "aaa" Then GoTo 1 Next Worksheets.Add ActiveSheet.Name = "aaa" 1 次の処理 というように書いていますが、これをgotoを使わないで…となるとどのように書いたら良いのでしょうか?
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 こんなんでも出来るよということで。。。 -------------------------------------------- Sub Test() On Error Resume Next Sheets("aaa").Select If Err.Number > 0 Then Err.Clear Worksheets.Add ActiveSheet.Name = "aaa" End If End Sub ------------------------------------------ それから質問者のコードの変数myWSの宣言ですが、今回のような場合にはちゃんと型宣言もすべきです。 Dim myWS As Object → Dim myWS As Worksheet 以上です。
その他の回答 (5)
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 確かに、あるレベルぐらいまでは、コーディングの際に、Goto は、なるべく使わない方法で考えるべきだと思います。しかし、Excelの場合、他人とチームを組むということもあまりないし、まして、自分のコードをどのように書いたところで、半年も経てば他人のコードのように化してしまうわけで、あまり、それに縛られる必要はないと思います。 あえて言うと、いくつかのVBのルールがありますが、それををそのまま、短絡的にVBAに持ち込むことは出来ません。 気になる人は、マイクロソフトが提示したVBAの『最適化』をMSDNライブラリで、チェックしておいたほうがよいと思います。簡単に言うと、VBAのルールは、可読性を犠牲にしてでも、文字数を減らす方向にあるということです。 ですから、私は、実際のVBAコードと、掲示板に書くマクロとでは、その書法には違いがある時があります。 ちなみに、私の場合は、記録マクロのような定番ですが、以下のように書きます。 全体の流れを失わないで済みます。 '--------------------------------------------------- Sub Test() Dim myWS As Worksheet On Error GoTo ErrHandler 'エラーを吐くものなら何でも可 Set myWS = Worksheets("aaa") 'Next_Procedure '次のコード Set myWS = Nothing Exit Sub ErrHandler: Worksheets.Add ActiveSheet.Name = "aaa" Resume End Sub '--------------------------------------------------- 例えば、オブジェクトを作らないなら、 Set myWS = Worksheets("aaa") これでも可。#5のtaocat さんの Select でも可 Application.Goto Worksheets("aaa").Range("A1")
お礼
今回、gotoを使わなくても方法があると分かり、感動しました。 まだまだ勉強中の身であり、なるべくgotoを使わずにいろいろな方法を考えたいと思います。 確かに半年前のコードは自分でももうわかりません。 (今より知識がないため、より一層難解です) エラーコードを最後にまとめておくと流れが見やすいですね。 参考にしたいと思います。ありがとうございました!!
- zap35
- ベストアンサー率44% (1383/3079)
構造化プログラミングがはやった頃は「GOTO文を使うな」とか「上から下へ飛ぶときにしか使うな」と良く言われました。(1970年代後半ころ) 下から上へGOTO文で飛ばすと、プログラムのロジックが追いにくくなる → デバッグしにくい。ループしやすい。→ プログラム品質が落ちる という理由からです。 質問のループを抜けるGOTO文はまだ許される範囲だと思いますが、構造化プログラミングではこのような場合はフラグを使用するのが一般的です。でも行数が増えるとか、余分な変数が必要になるという理由で好まない人も多いと思います。 (コード自体は#01さん、#03さんも書かれているので記載しません) なお構造化プログラミングではEnd IfのないIf文も嫌われますね。
お礼
たしかに、gotoで飛ばされると、デバッグしにくいですね! 行数が増えたり、変数が増えるのもスマートでない気もしますが、フラグを使う処理を利用して行こうと思います。 End Ifも合ったほうがいいとは初耳でした。 どうも、作ったプログラムが他のPCで上手く動かなかったりするので、なるべく基本に忠実に作ろうと思います。 ありがとうございました!
こんばんは。 その程度の使い方であればいいと思いますよ。 多用すると処理が繁雑になるというか分かりにくくなるので、多用はするなと言うことだと思います。 とりあえずGotoを使わないとすれば、フラグを立てて判断するくらいでしょうか。 Dim myWS As Object Dim flg As Boolean flg = False For Each myWS In Worksheets If myWS.Name = "aaa" Then flg = True Next If flg = False Then Worksheets.Add ActiveSheet.Name = "aaa" End If 次の処理
お礼
ありがとうございます gotoが良くない、というより使い方に気をつけろということなのですね~。 参考になりました!
構造化プログラミングと言った話の流れからのようですが、 残念ながら私は詳しくないです。 構造化プログラミング-Wikipedia http://ja.wikipedia.org/wiki/構造化プログラミング Gotoを「むやみに使いすぎると」【何のプログラムだか把握できなくなる】から、気をつけよう、ということのようです 参考までに以下の文章を読んでみるとどーなるか判るかと http://www.algolab.co.jp/~lum/pcnyumon/hosoku06.htm
お礼
なるほど、こういった背景があったのですね。 スパゲッティーテキスト、たしかに読む気が起こりません(笑) ありがとうございました。
- TAK_999
- ベストアンサー率43% (42/96)
こんな感じではどうでしょうか? Dim myWS As Object Dim bExistFlg As Boolean bExistFlg=False For Each myWS In Worksheets If myWS.Name = "aaa" Then bExistFlg=True Exit For Next If Not bExistFlg Then WorkSheets.Add ActiveSheet.Name = "aaa" End If フラグを多用することもソースコードを難解にする要因ではありますが、 多少はしょうがないと思います。
お礼
ありがとうございます フラグを使えばいいのですね。 行は増えても、コードが上に戻るよりは良いということでしょうか。 参考になりました!
お礼
!!!なるほど~!!!! エラーを逆手に取るわけですね!!なんか感動しました。 これなら変数も増えず(むしろ減り)シンプルですね! エラーをこういう風に使ったことはないので、今後活用できるよう調べてみます。 型宣言もするようにしてみます! ありがとうございました。