質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.33%

  • VBA

    1906questions

    VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

見やすい If の書き方 (後で見やすいコードの書き方が分からない_1)

解決済

回答 7

投稿

  • 評価
  • クリップ 1
  • VIEW 1,275

kamikazelight

score 126

 見やすい If の書き方

大体パターンは決まっているのですが
見やすい書き方が分かりません...
皆さまはどのように書いているのでしょうか?
教えて頂きたいです。

 悩んでいるパターン

  • AndOrを使う場合改行した方が見やすいのではないのか ?
  • 値を変数に入れてからIfにした方が見やすいのではないのか ?
  • 上記の場合 定数のような感覚で定義した後すぐに値を入れたほうが見やすいのではないのか ?
  • 改行した時 処理内容は一行空けてから書き始めたほうが方が見やすいのではないのか ?
  • 改行した時 二行目は一行目に対してインデントを増やした方が見やすいのではないのか ?
  • 上記の場合 中に書く処理は二行目に対してインデントを増やした方が見やすいのではないのか ?

とりあえず思った通りに書いてみたのですが
しっくりきません...

Option Explicit

Private Function RngResize(ByRef Base As Range, ByRef Target As Range) As Range
'[Target]を[Base]に合わせてリサイズする

    Dim ResizeRng As Range

    Dim BRC As Long
        BRC = Base.Rows.Count
    Dim BCC As Long
        BCC = Base.Columns.Count

    Dim TRC As Long
        TRC = Target.Rows.Count
    Dim TCC As Long
        TCC = Target.Columns.Count

        If BRC <> TRC _
            Or BCC <> TCC Then

                Set ResizeRng = Target.Resize(BRC, BCC)
        End If

    Set RngResize = ResizeRng

End Function


他も突っ込みどころ満載な気がしますが別途質問する予定なので
主に If に関わる部分の書き方のご教授をお願い致します。

 蛇足 ~見やすいコードが書きたい~

最近 作る内容が複雑になってきて過去に作ったコードを再利用出来る様に
したいと思い始めました。
現状 コードがぐちゃぐちゃで探すよりも書き直した方が早いという感じで
再利用が出来ません。
書籍を買って読んだりしていますが
知識が増える度に選択肢の多さに迷い
手が止まります。
最終目標は判断基準の確立と
コードの使いまわしが出来るようにすることです。
宜しくお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 7

checkベストアンサー

+4

この辺りはコーディング量によって洗練されてくるとは思います。VBAのコーディング規約のサンプルがネット上に存在するのであれば参考にすれば良いと思います。いいコーディング規約にはなぜそうするべきかということが書かれています。

・AndやOrを使う場合改行した方が見やすいのではないのか?
→条件が複数ある場合は改行&インデントした方がいいですが条件が2つとかであれば逆に冗長のような気がしますね。

・値を変数に入れてからIfにした方が見やすいのではないのか?
→必ずしもそうではなく、値を使いまわす必要がある時やデバッグ時は変数に入れた方が分かり易いレベルだと思います。

・上記の場合 定数のような感覚で定義した後すぐに値を入れたほうが見やすいのではないのか?
→VBでの文化はちょっと分からないんですがJavaなどでは変数の宣言は使う前がいいと言われてますね。ただ言語によって違いがあると思います。

・改行した時 処理内容は一行空けてから書き始めたほうが方が見やすいのではないのか?
→変に1行空けると間延びした感じになってしまうと思います。1画面内に収まる情報量が多いほうが処理は追いかけやすいと思います。私の場合は改行は処理の塊ごとに入れる方針ですね。

・改行した時 二行目は一行目に対してインデントを増やした方が見やすいのではないのか?
→IFについてだと、インデントはあった方がいいですね。2行目以降が存在する場合は2行目の先頭がそろうように私の場合は書きます。

・上記の場合 中に書く処理は二行目に対してインデントを増やした方が見やすいのではないのか?
→処理は1行目に対してのインデントでいいと思います。

私も今までメンテナンス性を考慮しながらプログラミングしてきましたがなかなか難しい問題ですね。まず考えるのは最低限の規約(例えば","のあとは空白を1つ必ず入れる)等でそれ以外はできるだけ間延びしない感じで処理が読めることを心がけています。一番重要なのは全体を通してその規約が適用されていることだと思います。あっちではこの書き方をしてこっちでは違う書き方をしているようなソースでは後から読んだ時に理解速度が遅くなる気がします。また、使われる環境によっては可読性より短さを求められるものもあるとは思いますが、質問者の意図とは違うと思いますのでそっち方面でないと仮定しての回答でした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 12:38

    詳しい回答をありがとうございました。
    参考になりました。

    キャンセル

+2

結局のところ書き方なんて趣味のようなものなので、自分が見やすければそれでよいし、他人が書いたもので最初見づらいと思ってても、ずっと見てると慣れてくるもんです。
(コーディング規約があるような現場は別です)
しかし提示のコードのように変数宣言のあとの処理にインデントなど無闇にインデントを設けるのはいただけません。
インデントはループやSelect Caseなどに使用しないと可読性が悪化します。
また条件文なんかは先頭をあわせると前後の行で比較がしやすくなりますが、VBAの場合、勝手に間を詰めてしまうので多言語に比べて効果は薄いかもしれません(変数名の長さが前後で違う場合に効果が薄い)。
今回のような短い変数名かつ少ない条件文では一行につなげてしまった方がよいかもしれませんね。
などを踏まえて私が書くとしたらこうなりますというのを載せておきます。

Option Explicit

Private Function RngResize(ByRef Base As Range, ByRef Target As Range) As Range
'[Target]を[Base]に合わせてリサイズする

    Dim ResizeRng As Range
    Dim BRC As Long
    Dim BCC As Long
    Dim TRC As Long
    Dim TCC As Long

    ' Base
    BRC = Base.Rows.Count
    BCC = Base.Columns.Count

    ' Target
    TRC = Target.Rows.Count
    TCC = Target.Columns.Count

    If BRC <> TRC Or _
       BCC <> TCC Then
        Set ResizeRng = Target.Resize(BRC, BCC)
    End If

    Set RngResize = ResizeRng

End Function

再利用について。
コードの再利用ができるシーンというのはなかなかないと思います。
あったとしてもおおまかな作りを真似して作り直すとかになるはずです。
コード自体の再利用はできるに越したことはないですが、それよりも自分自身の経験を蓄積して、「この処理は過去のあの処理に似てるから真似て作れるな」とか引き出しの数が増えるとよいかと思います。
それには何よりもコーディング量が重要です。
プログラムを始めたばかり(かどうかはわかりませんが)であれば、まずは再利用を気にせず、ガンガン書いていったほうがよいと私は思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 12:29

    >自分が見やすければそれでよいし、

    貴方のコードは私から見て自分のコードよりも見易いです!

    今の所自分一人やっていますが
    これからもそうである保証がないので
    「大体の人から見て見易い」
    を目指したいです。

    キャンセル

+1

再利用がしにくいというのはif文の書き方によるものではなく、プログラムの構造設計がなされてないからです。
画面層とデータ層などの境界線により構造を分け、共通化を図っていけば再利用し易くなります。
※例えば、データ層ではコントロールを直接参照するのではなく、パラメータで受け取るなどによって画面層との分離ができます。

追記

ifの場合はelseifが可能な場合を単独のif文よりend ifが少なく少しコンパクトになります。
また、単独の項目で判定可能なら、select case を利用するとスッキリします。
それでも条件が複雑なら、関数化して集約したステータスを返却するようにして、その返却値で分岐するなどすれば、制御自体が見やすくなります。

if文が視野の範囲内で完結していないと、理解もし辛いです。
ページスクロールしないと全体が見れないようなコードかどうかを処理分割の目安にしています。
制御がなく単純編集みたいなものは考えることは必要ないので、気にしませんが。

_を使用するのはスクロールしないと駄目なくらい横に長くなった時だけですね。
全体が見えることを優先し、行数が増えるのは極力避けます。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 11:34

    ごめんなさい。
    それは分かっているつもりなのですが
    別質問にて内容を書く予定です。

    蛇足は最終目標なので...

    キャンセル

  • 2018/07/19 11:41

    追記しました

    キャンセル

  • 2018/07/19 11:56

    if の条件が複雑になるときは無理に詰め込まずに関数にすればいいのですね!
    自分が書いたコードを見てみたら無意識にやってるとこがありました。
    これからは そういう方法もあることを意識して やってみます。

    キャンセル

+1

if の条件を関数として外出しすることで、読みやすい if 文を作ることができます。
命名さえしっかりできていれば、かなり脳みそ使わなくて良いコードになるかと。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 11:44

    条件を外出しをするというのは
    条件の部分を`Boolean型`の値を返す関数にするという意味でしょうか?

    今回の例題の場合は
    ```vba
    Function SameRngSize(ByVal Rng1 As Range, ByVal Rng2 As Range) As Bookean
    '[Rng1]と[Rng2]のサイズが同じならば[True]を返す

    ' ~処理~

    End Function

    ```
    という関数を作って`if`で使うということでいいのでしょうか?

    キャンセル

  • 2018/07/19 12:35 編集

    そうですね。
    VBA は使用しないので、記述が正しいか判断できませんが、php 等であれば
    if(is_same_rng_size($hoge_rng, $fuga_rng)){}
    みたいに、命名/使用します。
    これなら、何の範囲と何の範囲が、どうなのか?が見ただけでわかるかと。

    変数も関数も命名に頭を使います。

    キャンセル

  • 2018/07/20 15:59

    返答ありがとうございます。
    命名はとっても苦手です
    命名サイトの[codic]など使ってましたが
    そもそも 日本語での命名の時点で残念な感じなので効果がありませんでした。
    大分 苦しんでいます....

    キャンセル

+1

基本的なアプローチは出ていますので、
人によって是非が分かれる、ややトリッキーな書き方の例を。

If  Or の代わりにSelect Case Trueを使った書き方です。

Select Caseは本来

Select Case 比較する式
    Case 条件式1, 条件式2
        処理

と書きますが、比較する式Trueを指定することで条件式1、2に対するOrElse相当の判定とすることができます。

Private Function RngResize(ByRef Base As Range, ByRef Target As Range) As Range
'[Target]を[Base]に合わせてリサイズする

    Select Case True
        Case Base.Rows.Count <> Target.Rows.Count, _
             Base.Columns.Count <> Target.Columns.Count

            Set RngResize = Target.Resize(Base.Rows.Count, Base.Columns.Count)

        Case Else
            Set RngResize = Target

    End Select

End Function

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/20 13:45

    ありがとうございます。教えて頂いた方法は
    分岐が多い場合に使わせて頂きます。

    キャンセル

+1

提示の関数は、Nothing が返ってしまうバグがあるんだけど、
気付いてるのだろうか?(imihitoさんのコードを見れば分かったと思うけど。。。)

たぶん、Ifについて聞きたい為に作った関数だとは思うけど、
もし実際に使っているのであれば、
If分岐はいらないんじゃないかと思う。

余計な気を回して、むしろバグを生むのは、
あまり得策じゃないよね。。。
まぁ経験を積めば色々と分かるようになるよ。

手厚くしなきゃいけない部分と、
手を抜いてもいい部分とかね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/20 15:48

    そうですね。
    この場合だと無理にIf にせずともそのままResizeを使ってしまえばいいですね...

    指摘の通り これだと Else の処理が入っておらず リサイズの必要がないときにNothingが帰ってしまいますね
    もともと使っていたときは Function ではなく Sub で Byref を利用してそのまま Targetを書き換える
    コードだったのを慌てて変えたので忘れてしまいました。
    ちょくちょく 本当に使ってるコードでも同じミスをしている気がするので
    気を付けます。

    キャンセル

-1

日頃心がけてるのは、
式が複数の行になるときは、演算子を行頭に置かない、
カッコを多用して、極力優先順位の曖昧さをなくす、
配列などのときは、データの区切りのコンマを行頭に置かない、
というとこらへんでしょうか。

        If (BRC <> TRC) Or_
            (BCC <> TCC) Then

とか

int hogehoge[]={ 
    1,  2,  3,  4,
    5,  6,  7,  8
};

こんなかんじですね        

次の行を見ないと式が続くかどうかわからない、ってのは地味にストレスになります

#いろんな事情で常にこの通りにできるとは限りませんが

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/19 11:52

    >次の行を見ないと式が続くかどうかわからない、ってのは地味にストレスになります
    なるほど...
    前の行からの続きかわかるように書いていたのですが
    確かに普通に読むなら次の行に続いているのか分かった方がいいですね。

    まだ書いている途中の事しか考えられてないみたいです。
    ありがとうございました。

    キャンセル

同じタグがついた質問を見る

  • VBA

    1906questions

    VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。