質問: if not c is nothing then ~延々処理が続く~ end if 質問というか相談というか vbaで下記のようなコードをよく見ますし、私自身もこれで書いてます。 for i= 1 to 10 set c=range.find(”いろは") if not c is nothing then ~ 処理が続く ~ end if next i cが見つからなかったら、さっさと次の i に進む場合の処理です。ifの字下げがず~~っと延々続き、最後のnext iの直前でend if です。 ・exit for はあるのに 途中next iは出来ない ・goto 使って書くと「スパゲティプログラムだ」とか言われる 正直言って、上記コードとgotoスパゲティで可読性に差異があるとは思えません。何でもかんでもgotoはダメていう風潮がおかしいように思えます。 みなさんどうやって書いてますか?
回答: こんにちは。 >goto 使って書くと「スパゲティプログラムだ」とか言われる どっちかというと、今は、ネットの中で、某vba系の専門掲示板で、他人のコードを罵る時に使う用語ですね。goto を使ったから、スパゲティーと短絡して使うのに、その言った本人は、エラー処理ひとつ施していない隙だらけのコードだということが多いのです。「スパゲティプログラム」は、◯◯の一つ覚えの用語だと思います。 >for i= 1 to 10 >set c=range.find(”いろは") >if not c is nothing then >~ >処理が続く >~ > >end if >next i これって、よく見るとおっしゃっていますが、ひとつ例外に、いわゆる「ブルートフォースアタック(総当り制)」のコードがありますね。それは、goto 以外に抜け出せる方法がありませんね。「深いネストはするな」という禁を犯しているのだから、goto 以前のものがあります。(何に使うかはご存知だと思いますし、それをとやかく言う人はいないでしょう。) これを書き換え、再帰を使うと良いとか言う人もいるのでしょうけれども、そういうのは、知識だけで実際にやったことがない人の話だと思います。「スパゲティ」とか知らない人に、比べさせれば、再帰などを使った方法は、遅くてダメ出しされるのは目に見えています。特殊な例ですが。 ご質問で、実際の私は、内容にもよりますが、 private flg as boolean sub main() on error goto errhandler for i= 1 to 10 call subrutine(findtxt) if flg then exit for next i exit sub errhandler: 処理 end sub 'ここの中身はテンプレート化してあります。 private sub subrutine(byval findtxt) または、public '処理 end sub としているはずで、モジュールレベルの変数を、flg とし、サブルーチンの中に置いて、目的がかなったら、flgは、trueになって、ループから抜け出すようにします。 サブルーチン側では、end ステートメントを使用することさえもあります。(テンプレート化しているのは、findメソッド、regexpの正規表現、sortメソッド、dictionary とsortlists などがあります。[mz-tools 3.0]を使用) goto は、構造化プログラムが登場した時に、排除するように言われてきたものです。古い時代の人は、gotoに逃げたくなるのを抑えるために、「goto」を使うなって、肝に命じてきたのです。しかし、結局、goto は、なくならなかったのは、一つには、errhandlerを使った、エラートラップのせいもあります。だから、goto を書かないでerr.raise (513~)で飛ばす方法がありますが、あまり使う人はいません。 ところで、 「スパゲティプログラム」という話に振られると、私は自信がありません。 読みやすさ(可読性)の対極になるものでしょうけれども、誰に対して言っているものか、ということです。私の大事にしている本の中に、アスキーの『quickbasicプログラミング道場』(1991年)という本があります。 ---引用 ・本道場で推奨するプログラミングスタイル (p25~) 1.変数・定数・プロシージャーの命名法 (変数の型のサフィックスは使うな) 2.インデントを付けるべし 3.メインプロシージャは短くすべし 4.プロシージャは短くすべし 5.長いブロックはプロシージャーにすべし 6.汎用性のあるプロシージャーを作るべし 7.定数は活用すべし 8.gotoは乱用(濫用)すべからず。● 従来のbasicを使ってきた人の中には、goto文を多用する人がいるようだ。goto文はそのときは便利なように思うが、あとになってリストを眺めてみると、どこに飛んでいるか分からなくなることが多い。......わけがわからない最低の"スパゲティプログラム"になってしまう。 【例】goto文をdoループに置き換える ----引用終わり 現代でも通用するというよりも、その言葉が生まれた時代背景がありますから、必ずしも、gotoが問題だということではなさそうです。goto を使わないということにこだわると、逆に墓穴を掘ることになります。 それと、do ループにするというのは、do ~ loopの間に緊張感(?)は生まれるけれども、無限ループを生み出しやすくなるのです。その頃はそれで良かったかもしれませんが、もうescでは止まりません。今は必ずしも認められるものではありません。 それと、記録マクロを、そのままvbaプロシージャーに用いるのは、絶対にダメなのですよね。本当のスパゲティプログラムになってしまいます。ベタ書きになってしまうからで、一度、そういうコードを直してくれと言われましたが、怒りを抑えて、丁重にお断りました。