えくせるちゅんちゅん

ことりがエクセルをちゅんちゅんするブログ

VBAのコメントの書き方の試行錯誤

当然のことではあるがプログラミングに於いて、コメントを残すことは非常に重要である。


ここでは私が個人開発をする中で「コメントを残しておいて良かった。」と思った事を、独り言として書き残しておく。


コメントを残して良かったと思う時

なぜこのようにプログラミングしたか

真っ先に挙げるとしたらコレ。

プログラムを読んで理解しようとした時、複数の実装方法がある中でわざわざ回りくどい方法を採用している時、後で読み返すと「なぜこうしたのか分からない」と言った疑問を持つ事が多い。

そんな時「何故?」を書いておくと救われる。


私が全力でプログラミングしている時、脳ではとてつもない情報量が光の速さで処理されている。

とてもじゃないが、頭に浮かんだ情報を全てタイピングするようなことはとても出来ない。

だから、ついついプログラムを書くことを優先してしまって、後で書こうと思っていたコメントも書かないまま休日に入ってしまって、存在そのものを忘れてしまうなんてことが良くある。

当然、未来の自分が読み返した時は解読に苦労している。


特に調子の良い時ほどヤバイコードを書いている気がする。


我に返った時でも良いので、「なぜこのようにプログラミングしたか」を書き残すようにしたい。


違和感

違和感・・・それは天のお告げ。未来視かもしれない。


「なんか気持ち悪い」「もやもやする」という感じで違和感を感じたりする。

このようなときはコメントを残して置くと良い。

というか「コメントを残そうとすること」が重要なのかもしれない。


私は「人は一日に数回は何らかのひらめきをしているはずだ。」と考えている。

「いやいや、そんな事はない。」と思うかもしれないが、それはきっと自覚できていないか、一瞬で忘れてしまっているだけだ。


例えばプログラミング中にふと「もしかして」と思うことがある。

この「もしかして」は、あまりにも弱いため無意識下で「そんなことあるわけない」と反論して、記憶の彼方に追いやられてしまう。天使と悪魔がいたとしたら間違いなく天使の方だろう。お告げだけに。

こんな入力値も有り得るんじゃないかかなぁ
→そんな事あるわけ無いだろ


不思議なもので数分後、数時間後、或いは数日後、自らが否定した「もしかして」が再現したりするのである。そして・・・

→やっぱあったわ

となる。

でも既に考えていたこと自体を忘れているため、その場で思い出すことはできない。

しばらく経ってから、ふと思い出したりするから人の脳は不思議だ。


辛うじて記憶が残っている時なら、「さっき良いことひらめいた気がするのに!」と悶々とすることもある。


以下は私のTwitterの裏事情である。(消そうと思ったが折角書いたので晒しておく)

困ったなぁとツイートすると、優しい誰かがヒントを教えてくれる。

返事を貰えるのはとてもありがたいことだ。

でもその内容にはデジャヴを感じるのである。

よくよく考えてみると、実はその内容は既に思考した事があるのだ。

反射的に「そんなこと知ってるわ」と言いたくなるが、思い出せなかった自分が悪い。

素直に「気が付きませんでした。ありがとうございます。」と答えて万事解決だ。


このように、その場では(無意識化で)切り捨ててしまった違和感でも、少し深読みしたり、浅読みしたり、視点を変えたりすると考慮すべき案件だったりする。

だから、何か気がついたことがあるなら、その場で文章化しておくように意識している。

プログラムで気がついたことなら、どんな下らない内容でも遠慮なくコメントを残しておけば良い。

コメントが不適切だと感じるなら、ツイートするなりネタ帳に書いておくなりでも良いと思う。


きっと文章を残そうとする意識が重要なのだろう。


未解決のバグや副作用

エラーを引き起こしている場所が特定できたとしても、その場で完全に潰しきれないということが良くある。

  • 何故かDoEventsを入れたら乗り切れた。
  • 何故か処理の順番を入れ替えたら上手く行った。
  • こんな入力値だとバグるが、入力されるとは考えられないので対応していない。


でも「良くわからないから」「今は問題ないから」と言って対策を打たないでおくと、後で余裕ができた時に直す事ができない。

だって問題があること自体を覚えていないのだから。


こんなときは「こういう時にバグが出る。//あとでなおす」と書いておくべきなんだと思う。

「//あとで直す」というコメントは典型的な悪いコメントのように言われる事があるが、まず問題があることを把握することが重要なので、書かないよりは書いたほうが絶対に良い。

きっと解消されずに放置されているのが問題なのだ。


そして、未来の自分に叱られないうちに解消できるともっと良い。


実際、私は過去の自分に対してツッコミを入れることが多々ある。


ドキュメント用コメント

現在整備中の愛用ライブラリでは、関数の仕様はバグや副作用なども含めて全てをドキュメントとして整備したいと考えている。

しかしVBAにはドキュメントを作るための記法は存在しない。

だから、ドキュメントはコメント機能で書いて、何らかの方法で機械的に読み取って生成することになるのだろう。

ドキュメントの仕様は決めていないが、何にせよ機械的に抽出するには何らかのルール決めが必要だ。


そこで、私は二種類のコメントを使い分けることにした。

Rem ドキュメント用コメント
'プログラム用コメント


Remを使用している人は見たことがないが、VBAではどちらの構文も同じようにコメントとして扱われる。(前記事の通り)

そしてRemコメントアウトされた部分は、VBEの機能でコメント解除することができない。

Rem こめんと
' コメント
Rem コメント

Rem こめんと
コメント
Rem コメント

逆に言えば誤ってコメントを解除してしまう恐れがないということ。

だからドキュメントへ使うのは最適なのである。


最近のソースコードを見て分かるように、今はこんな感じのフォーマットで書いている。

またすぐに変わるかもしれない。

Rem @title      タイトル(機能説明)
Rem @name       関数名
Rem @oldname    旧関数名(検索でヒットさせるため)
Rem
Rem @param base_str         引数の解説
Rem @param len              引数の解説
Rem
Rem @return As Variant()    戻り値の解説
Rem
Rem @example     入出力の具体例
Rem
Rem @note       注意書きとか
Rem


つい先日こんなマクロがあると知って、ドキュメントの書き方を変えようか微妙に迷っているところ。

qiita.com


関数の入力例と出力例

プロシージャの処理がある程度の規模になってきたら、処理を抽象化して別の関数に切り出すようなことをする。


別の関数に切り出した直後は、「何がしたいのか」具体的にイメージされているので全く苦なく読めるのだが、数日後その関数の仕様を見た時、何を与えると何を返してくれるのか良くわからないということが良くある。=再利用出来ない。

だからこそ関数には必ず「何をする関数か」「引数に何を与えれば良いのか」コメントを残すのだが、私の語彙力と理解力では読み返した時に一目で理解できることはまず無い

自分で書いたものなのに!だ。

これらを踏まえて、最近では入力例と出力例を全てコメントとして残すようにしている。


この入出力例は、関数の単体テストの実行結果をそのまま貼り付けているだけである。

関数を読んでいる時にその都度テストを流すわけには行かないので、いっそのこと全て書き残しておこうという考えだ。

Rem @title  文字列を指定された回数分連結する
Rem
Rem @name   StringStr
Rem
Rem @param str_count    文字列の個数(0~#)
Rem @param base_str     複製する文字列
Rem @param delimiter    区切り文字
Rem
Rem @return As String   連結された文字列
Rem
Rem @example
Rem     delimiter :=
Rem         str_count := 0
Rem         String ""    >> String ""
Rem         String "a"   >> String ""
Rem         String "abc" >> String ""
Rem
Rem         str_count := 1
Rem         String ""    >> String ""
Rem         String "a"   >> String "a"
Rem         String "abc" >> String "abc"
Rem
Rem         str_count := 3
Rem         String ""    >> String ""
Rem         String "a"   >> String "aaa"
Rem         String "abc" >> String "abcabcabc"
Rem
Rem     delimiter := ","
Rem         str_count := 1
Rem         String "a"   >> String "a"
Rem
Rem         str_count := 3
Rem         String "a"   >> String "a,a,a"
Rem
Public Function StringStr(str_count As Long, _
                            base_str As String, _
                            Optional delimiter As String = "") As String
    If str_count < 1 Then Exit Function

    Dim i As Long
    Dim sArr() As String
    ReDim sArr(1 To str_count)

    For i = 1 To str_count: sArr(i) = base_str: Next

    StringStr = Join(sArr, delimiter)

End Function

プログラム本体よりコメントの方が長いのはご愛嬌

こうすれば関数の役割が一目瞭然だ。


やってみた感想としては、このコメントを残すようにしたのは正解だった。

私の引数・戻り値の解説の語彙力の無さを見事に補完してくれている。

関数を再利用する際の効率が、格段に上がったと実感している。

また、開発中・解読中にテスト漏れに気がついて、取り除かれたバグが数え切れないほどある。


心配があるとすれば、このようなコメントを他所で見たことがないことである。

プロの皆さんはどのように対応しているのかとても気になる。

皆天才ばかりなのだろうか?


まとめ

プログラミング中にコメントを残すことは中々に難しいことだが、後で読み返した時に残しておいて良かったと思うことがとても多いので、できる限り残していきたい。


あと完成した関数をツイートしておくと、後でゴロゴロしている時に読み返す機会ができ不適切なところを直す&コメントを書くことができて良いなと最近感じている。


VBAでの広域コメントアウトの代替案

www.excel-chunchun.com


VBEをカスタマイズしてコメントアウトを効率的に行う

www.excel-chunchun.com

以上


何か御座いましたらコメント欄、またはTwitterからどうぞ♪

それではまた来週♪ ちゅんちゅん(・8・)