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

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

新規登録して質問してみよう
ただいま回答率
85.35%
VBA

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

Q&A

解決済

7回答

11716閲覧

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

kamikazelight

総合スコア305

VBA

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

1グッド

1クリップ

投稿2018/07/19 02:03

見やすい If の書き方

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

悩んでいるパターン

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

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

VBA

1Option Explicit 2 3Private Function RngResize(ByRef Base As Range, ByRef Target As Range) As Range 4'[Target]を[Base]に合わせてリサイズする 5 6 Dim ResizeRng As Range 7 8 Dim BRC As Long 9 BRC = Base.Rows.Count 10 Dim BCC As Long 11 BCC = Base.Columns.Count 12 13 Dim TRC As Long 14 TRC = Target.Rows.Count 15 Dim TCC As Long 16 TCC = Target.Columns.Count 17 18 If BRC <> TRC _ 19 Or BCC <> TCC Then 20 21 Set ResizeRng = Target.Resize(BRC, BCC) 22 End If 23 24 Set RngResize = ResizeRng 25 26End Function

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

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

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

T-Imai👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答7

0

ベストアンサー

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

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

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

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

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

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

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

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

投稿2018/07/19 02:36

unz.hori

総合スコア1057

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/19 03:38

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

0

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

VBA

1Option Explicit 2 3Private Function RngResize(ByRef Base As Range, ByRef Target As Range) As Range 4'[Target]を[Base]に合わせてリサイズする 5 6 Dim ResizeRng As Range 7 Dim BRC As Long 8 Dim BCC As Long 9 Dim TRC As Long 10 Dim TCC As Long 11 12 ' Base 13 BRC = Base.Rows.Count 14 BCC = Base.Columns.Count 15 16 ' Target 17 TRC = Target.Rows.Count 18 TCC = Target.Columns.Count 19 20 If BRC <> TRC Or _ 21 BCC <> TCC Then 22 Set ResizeRng = Target.Resize(BRC, BCC) 23 End If 24 25 Set RngResize = ResizeRng 26 27End Function

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

投稿2018/07/19 02:44

ttyp03

総合スコア17000

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/19 03:29

>自分が見やすければそれでよいし、 貴方のコードは私から見て自分のコードよりも見易いです! 今の所自分一人やっていますが これからもそうである保証がないので 「大体の人から見て見易い」 を目指したいです。
guest

0

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

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

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

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

投稿2018/07/20 05:16

ExcelVBAer

総合スコア1175

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/20 06:48

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

0

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

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

Select Caseは本来

vba

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

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

vba

1Private Function RngResize(ByRef Base As Range, ByRef Target As Range) As Range 2'[Target]を[Base]に合わせてリサイズする 3 4 Select Case True 5 Case Base.Rows.Count <> Target.Rows.Count, _ 6 Base.Columns.Count <> Target.Columns.Count 7 8 Set RngResize = Target.Resize(Base.Rows.Count, Base.Columns.Count) 9 10 Case Else 11 Set RngResize = Target 12 13 End Select 14 15End Function

投稿2018/07/19 14:21

imihito

総合スコア2166

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/20 04:45

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

0

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

投稿2018/07/19 02:27

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/19 02:44

条件を外出しをするというのは 条件の部分を`Boolean型`の値を返す関数にするという意味でしょうか? 今回の例題の場合は ```vba Function SameRngSize(ByVal Rng1 As Range, ByVal Rng2 As Range) As Bookean '[Rng1]と[Rng2]のサイズが同じならば[True]を返す ' ~処理~ End Function ``` という関数を作って`if`で使うということでいいのでしょうか?
退会済みユーザー

退会済みユーザー

2018/07/19 03:38 編集

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

2018/07/20 06:59

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

0

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

追記

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

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

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

投稿2018/07/19 02:17

編集2018/07/19 02:55
sazi

総合スコア25327

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/19 02:34

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

2018/07/19 02:41

追記しました
kamikazelight

2018/07/19 02:56

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

0

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

If (BRC <> TRC) Or_ (BCC <> TCC) Then とか int hogehoge[]={ 1, 2, 3, 4, 5, 6, 7, 8 }; こんなかんじですね

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

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

投稿2018/07/19 02:37

y_waiwai

総合スコア88040

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/19 02:52

>次の行を見ないと式が続くかどうかわからない、ってのは地味にストレスになります なるほど... 前の行からの続きかわかるように書いていたのですが 確かに普通に読むなら次の行に続いているのか分かった方がいいですね。 まだ書いている途中の事しか考えられてないみたいです。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問