電子書籍の厳選無料作品が豊富!

VBAを始めて1年ほどになります。
プログラム(マクロ?)を本格的に勉強したのは、これが初めてです。

いろいろ作ってきて毎度共通の悩みがあります。
ソースなんですが、なんというか、「美しくない」のです。

作っている時は良いのですが、数日経って修正が必要になった時などに、ソースを見るのが嫌で嫌でたまりません。
変数が少ないのかと変数だらけにしたら、それはそれで何をやっているか分からなくなってきましたし、変数を日本語にすれば分かりやすいかと試してみれば、日本語ってどうも黒い四角にしか見えなくてパッと見が分かりづらかったりと、どうもうまくいきません。

プログラムは人が読むことを前提に見やすく書くべしと聞きますが、自分でも見難いソースしか書けない自分が嫌になってきます(^_^;

プロの方はいったいどういうところに気をつけて、読みやすいソースを書かれているのでしょうか?
美しいソースとはどういうものなんでしょうか?

一般論、個人的なこだわり、いろいろあるとは思いますが、よろしくお願いいたします。

A 回答 (10件)

この問題はプログラムを書く人間には永遠の課題だと思います。


2節に分けてみます。

☆一般論
・コメントを”適度”にしっかり書く
・サブルーチン(関数とかメソッドとか)を”適度”に使用する
・容易な変数名は”なるべく”使用しない
・スパゲティコードにはしない
・命名規則を”なるべく”遵守する
等々ですかね。
曖昧な部分”適度”や”なるべく”の部分は経験です。

例えば・・・
変数名でi,t,x,y,zは、慣例的にintegerを示している場合が多いです。
特にx,y,z等は座標を示したり、多次元配列を示す場合があります。
また、ColやRow等も慣例的に特定のオブジェクトを示している場合があります。

他の人も書いてますがgoto文はスパゲティコードの代名詞であり、嫌われる傾向にあります。
VBAの場合on error goto文くらいでしょうか許容されるのは。
ただgotoを使わなければイイという訳でもありません。
構造化プログラミングも多重継承しだすとわけわからなくなったり、グロスコープが適切ではなかったりと色々あります。
これらに関してはgoogle先生が詳しいです。
http://ja.wikipedia.org/wiki/スパゲティプログラム


☆VBAに関して
VBAと言うことで、一番使われるExcelやAccessだと想定します。
VBAはVB6以前までの言語構造を踏襲しています。
#VisualBasic for Applicationの略ですし^^

VB自体あまり美しく書ける言語だとはあまり思えません。
職業プログラマーでもVB6以前ではあまり使用する人が少ないですが、、コツとしてはクラスモジュールを使用するとイイかと思います。
継承などはできませんが部品化するという用途には使えます。

VBAのクラスモジュールの参考サイト
http://codezine.jp/article/detail/499
http://www.excellenceweb.net/vba/class/what_vba_ …

☆結論
私としては経験でしかないと思います。
職業プログラマーとしては10年、学生時代の趣味でやっていた頃も含めれば15年以上になりますが、未だに満足していません。
がんばってください^^;
    • good
    • 0
この回答へのお礼

なるほど。プロの方でも追い求め続けているものなわけですから、僕程度のレベルの人間は焦らずに地味にがんばるしかなさそうですね。

スパゲティコードというのを初めて聞いたのですが、調べてみると僕が書いたソースはまさにそれでした。
知ってはいましたが見て見ぬふりしていたのがクラスモジュールでした(^_^;
継承とかクラスという言葉すら理解していないのですが、商品化の用途にも使えるとまで聞いてしまっては勉強しないわけにはいきません。
教えていただいたサイトを読んで、じっくり勉強していきたいと思います。
ご回答ありがとうございました。

お礼日時:2009/12/08 11:14

>>9に追記です。



命名規則ですがVBAの参考例を以下に書いておきます。
・サブルーチン名など
' intHogeをHogeHogeに設定する
Sub SetHogeHoge(intHoge as Integer)

' HogeHogeを取得する
Function GetHogeHoge() As Integer

' HogeHogeを実行する
Sub HogeHoge()

・変数名など
Dim i as Integer, t as Integer ' ループカウンター等
Dim objFS as Object ' ファイルストリームオブジェクト
Dim objCol as Column ' カラムオブジェクト
Dim intTopCell as Integer ' セルの一番上を示す数値
Dim strTableName as String ' テーブル名
Dim strSheetName as String ' シート名
Dim strUserNames(0 to 5) ' ユーザ名配列
    • good
    • 0
この回答へのお礼

分かりやすい例を教えていただいてありがとうございます。
こういうのを見せていただけると、本当に助かります。
自然にこういう形に書いていけるように慣れていきたいと思います。
ありがとうございました。

お礼日時:2009/12/08 11:15

>No.7


Goto 原則禁止

開発言語が、VBAで
むしろ今まで GOTO を使用しておらず、
初級レベルから中級レベルにあがろうともがいている
のであれば使ってみる事をお勧めします。

VBA は JAVA のように、GOTOの代わりとなる
Exception や Throw が充実している訳では無いです
そんな言語で
たとえば、今まで GOTO を使用してはいけないと言われ
flgNG = False
Do

If Then

Else
flgNG = True
End If


If flgNG = False And Then

Else
flgNG = True
End If


If flgNG = False And Then

Else
flgNG = True
End If
Loop While (flgNG)

こんな書き方をしているとしたら、そちらの方が
GOTO を記述するより、よっぽど問題です
これ、やってる事は、GOTO を可読性悪く書いてるだけ
可読性が悪くなるという理由で GOTOを使わない事に矛盾
してますよね

完成したソースを見て、GOTOを使えばよりスマートに
記述できる部分をじっくり見直します

その部分を GOTO に直すのではなく、別関数にする事
を第一に考えて見直して見てください
あとは、慣れです
    • good
    • 0
この回答へのお礼

別関数を作るということに慣れてしまったせいか、Gotoはかなり気を遣わないといけないので、どうも使いづらくなってしまいました。
僕の場合は適度に使うというよりも、最小限にとどめないとそれこそ読めなくなりそうなので、おっしゃるとおり別関数にすることを考えていきたいと思います。
ご回答ありがとうございました。

お礼日時:2009/12/08 11:13

必要なことはすでに書かれているのでVBAに特化したもので。


あと、ソースを晒せばもっと良い提案ができると思いますよ。

・Option Explicit をマクロ最上段に書く
 変数の宣言を強制するステートメントです。
 変数の宣言を強制することで、入力ミスを防ぐことができます。デバッグも楽になります。

・変数の名前付けルールを決めて宣言する
 例えばですが・・・
  ユーザーが独自に作ったことを明示する: my
  用途を表す名称: Flag
  データ型: Integer
 の場合は
  Dim myFlag As Integer
 と宣言すると整数型以外の使い方ができなくなるためデバックしやすくなると思います。
 バリアント型は極力使わないほうが良いでしょう。

・インデントの対応
 If 文などで、If文が影響する範囲のコードを字下げすることで、コードの単位がわかりやすくなると思います。
 エディタのほうが勝手にやってくれるはずですが・・・

・コードを書く前にコメントで「何の目的で何をやって何を得るか」を書く
 どこから呼び出されるかとか、具体的なデータイメージも書いておくと、後でよくわからなくなって一から書くときも調べるのが楽です。

・Goto 原則禁止
 便利なことは多いですが、特にループの用途で Goto を使わないほうが可読性が高まります。

・同じ処理、似た処理は Sub や Function でまとめる
 VBA は高速性より簡潔性を求める書き方のほうが良いです。
    • good
    • 0
この回答へのお礼

名前付けのルールはいつも頭を悩ませるところでした。
長すぎても使いづらいし、短すぎても分かりにくいですし。
示していただいて例は大変わかりやすかったです。
自分でつけるのもそうですが、人がどういう風につけているのかが分かったので助かりました。
今まで人が書いたソースを読んでいても、変数なのか関数なのか自分の知らないメソッドやステートメントなのかの区別がつきにくかったもので・・・。
ご回答ありがとうございました。

お礼日時:2009/11/23 17:59

自分で個人的な工夫を凝らしてもうまくなることはないと思います。


うまくなるコツは、他人の書いたコードを大量に読んで解析することかなと思います。
下手な人のコードを読んでもダメなので、
短いコードではなく、ある程度の規模のソフトの一部を読むのが良いと思います。オープンソースのコードをネットから拾ってきてはどうでしょうか。
うまいコードほど、誰が読んでも理解でき、なおかつ仕様変更に強い仕組みが色々と施されています。
コード上の工夫は過去の人々がやり尽くしているので、自分で編み出そうとはしないことです。まずは真似ることです。
ある程度の量を読みなれると、下手なコードを見た瞬間に違和感がおこるようになります。
今の時点の自分の感覚でわかりやすいかどうかは判定しないことですね。
何度も書きますが、たくさん書くよりもたくさん読んだ人の方がうまくなります。
オープンソースのコードで過去のバージョンも手に入れば、比較して、何がまずくてどう変えたか追跡してみてください。

ちなみにプログラムで変数を日本語というのはあり得ません。
    • good
    • 0
この回答へのお礼

書くよりも読むというのは目からウロコです。
自分のソースに取り入れるために読むことはあっても、綺麗に書くための分析で読んだことはありませんでした。
どういうのが上手いのか分からないので、なんとなくでも綺麗だなと感じるソースを探していこうと思います。
ご回答ありがとうございました。

お礼日時:2009/11/23 17:53

それは最初でちゃんとした処理の流れを決めず、


行き当たりばったりでコーディングしているからです。

 
あ、ここでは判断にフラグをつけよう、
変数は、myFlagにして、っと。。

おっと、E列とF列にこの項目を入れておいた方がコードが書きやすいな、
ということで、コードを加筆・修正したり、、、


こんなことをやってるといくら変数を分かり易いものにしようが、コメント付けよううが、コードは見栄えのよいものにはなりません。

コードを書く前の段階に時間を掛けるのです。
そこに時間を掛けた分、コードは書きやすくなるし、また分かり易く、可読性の高いものになります。

適当な設計で闇雲にコードを書き出しては質問者のようになってしまいます。
 
次からは時間が掛かるかもしれませんが、コードを書く前に、仕様書、フローチャートを書いてみたらどうでしょう。
格段に違いが出ると思います。
 
以上です。
 
    • good
    • 0
この回答へのお礼

確かに!
加筆はよくやります(^_^;
最初に処理の流れを決めてはいるんですが、実力不足のせいか足りなかったりするんですね。
作ってる途中で「こういう機能もほしい」と思うこともあるので、最初の計画段階でもう少し掘り下げていく必要があると思いました。
仕様書などは書いたことがないので勉強してみます。
ご回答ありがとうございました。

お礼日時:2009/11/23 17:51

皆さんと意見の違いはないのですが、


ここに挙がってないことでは、
・処理が簡潔であること
・流れによどみがないこと
も重要かと思います。

あと、中級者以上が気をつけないといけないのが
・テクニックにおぼれない
ということ。
色々な技術を覚えると使いたくなるのですが、
本当にそれが必要か?とかは考える必要がありますね。

持論になりますが、
美しいソースは処理も美しいと思います。
    • good
    • 0
この回答へのお礼

「テクニックにおぼれない」というのは身にしみて解ります。
使いたくなるのもそうですが、使わなければいけないような感覚にもなるんですよね。
それができるのが上級者だみたいな感じで。
本当に上手くて綺麗なソースをかける人というのは、取捨選択がきっちりできる人なのかもしれません。
ご回答ありがとうございました。

お礼日時:2009/11/23 17:47

どのあたりが美しくないと感じるのか不明ですが



たとえばの例ですが
意味のわかる変数名、関数名をつける
Function GetXXXXName() とか
Dim FileCnt as long とか

機能ごとに処理を分ける 下に書いたGetXXXXCntが
If文の中に全部書いてあったら自分は読みたくないかも。

IF文が長くなるならEnd IfはどこのIfのEndか
コメントに書く
  If x = TRUE Then 'XXXXの取得とセルへの書き込み
    ' ○○がどうなっているときは××を取得する
    y = GetXXXXCnt
  Else
    ' それ以外はアレをやる
    Cells(1,1) = CalcXXXX(y)
  End If 'XXXXの取得とセルへの書き込みの終了


何がしたいからこういう関数にまとめたかを書く

'XXXXを取得したいから△△をループしてXXXXを取得する
Function GetXXXXCnt() as Long
  
  For i = 1 to 10000
   If GetZZZZ(i) = xx Then
     Exit For
   End If
   
   For j = 1 to 100
     'なにか
   Next j
  Next i

  GetXXXXCnt = GetZZZZ(i)
End Function
    • good
    • 0
この回答へのお礼

なるほど。コメントの書き方も考えないといけないですね。
僕はどうしても適当になってしまって、書いても書かなくても分かりづらくなるもんですから、困っていたところです。
こんなにも見やすさが変わるもんなんですね(^_^;
参考にさせていただいて精進いたします。
ご回答ありがとうございました。

お礼日時:2009/11/23 17:44

・コメントをつける


・変数名は内容を想像できるものにする
・ブロックごとの字下げを適切に行う
・入れ子を深くしすぎない
・ひとつの関数にひとつの機能
    • good
    • 0
この回答へのお礼

これらの基本をやってるつもりなんですが、見直してみるとやはりできていいないんですよね。
もう一度、基本から見直す必要がありそうです。
ご回答ありがとうございました。

お礼日時:2009/11/23 17:38

俺はプロじゃないけど、こだわりはある。



一回何か自分で課題決めて途中まで作ってみて、そのソースを丸ごとさらして見てよ。(質問文のように「変数が」とか言葉で説明せずに)
そのソースを見て問題点を分析してもらったほうが、
俺がアドバイス出来なくても、何もなしで一般論で語るより、他の回答者もアドバイスしやすいと思うよ。

#スコープは小さく。
    • good
    • 0
この回答へのお礼

すみません。ちょっと手頃なソースがなかったので、無茶を承知で質問してしまいました(^_^;
「スコープは小さく」、これだけでも助かります。
ご回答ありがとうございました。

お礼日時:2009/11/23 17:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!