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

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

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

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

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

意見交換

クローズ

12回答

4301閲覧

一見不要に思える例外処理を記述する必要があるのか

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

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

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

1グッド

3クリップ

投稿2023/09/01 01:35

編集2023/09/01 04:09

1

3

テーマ、知りたいこと

例えば下記のようなコードで、

変数exampleはIntegerなので整数
①10より小さい
②10
③11
④11より大きい

このようにexampleに入る全てのパターンを記述している場合、例外処理としてCase Elseは記述する必要はありますか?

Dim Txtbox_FontSize as Integer Dim example as Integer Select Case example Case Is < 10 Txtbox_FontSize = 25 Case 10 Txtbox_FontSize = 25 Case 11 Txtbox_FontSize = 26 Case Is > 11 Txtbox_FontSize = 27 End Select

背景、状況

学習に使用している書籍には「Case Else節は記述しなくても構いませんが、引数「対象式」の予測していない値の処理を行うためにも、記述することを心がけてください」と説明されているのですが、明らかに全てのパターンを網羅している場合にもCase Elseを記述した方がいいのか疑問に感じました。
Case Elseといった例外処理に限らずとも、記述してもしなくてもいい構文は数多くあると思うのですが、皆様はどのようにされてますか?また何故そうしているのかという考え方もお聞きしたいです。

menma...👍を押しています

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

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

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

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

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

回答12

#1

maisumakun

総合スコア145956

投稿2023/09/01 01:46

明らかに全てのパターンを網羅している場合にもCase Elseを記述した方がいいのか疑問に感じました。

ブール値や列挙型のような、入る値が厳密に限られたものであれば、Elseに来ないことが明らか、という例はありますが(そのような場合、プログラミング言語やツールによっては余計なelseがあると検知される)、そうでない場合はむしろ最後まで条件を書くほうが冗長かもしれません。

絶対に重複していない自信があるなら、最後1つをElseで処理させてしまうのも一案です。

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

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

#2

sk.exe

総合スコア938

投稿2023/09/01 02:14

「予測していない値の処理」というのは、「全てのパターンを網羅しているつもりでも、実際には見落とされている(かも知れない)ケース」への備えとして推奨されています。

変数exampleはIntegerなので整数
①10より小さい
②10
③11
④11より大きい

この場合の④は「①、②、③のどれでもない」と同義ですので、

Case Is > 11

vba

1Case Else

としても結果は同じです。

いずれの場合もパターンに漏れはありませんが、強いて違いを挙げるなら、比較演算処理の最大発生回数が異なります。

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

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

#3

fana

総合スコア11980

投稿2023/09/01 03:03

編集2023/09/01 03:12

いくつかの条件が提示されてから→これで全パターンを網羅している,ということを把握するのには
ほんのわずかでも頭を働かせる必要があると思うのですが,そこを

明らか

という言葉で終わらせてしまって良いものか否か?
…みたいな点をどう考えるか次第…かなぁ? …みたいな.

  • 「そんなの,どう考えても 明らか だろ」と考えるならば
    必要のないコードをわざわざ記述する理由はどこにも無いと言えるでしょう.
    例えば,
    自身にとって絶対的に明らかであって,このコードも自身でしか使わないというならば不要.
    コードを他者が見る可能性があるけども「こんなの誰にとっても」明らかだと考えるならば不要.

  • 逆に,「常識的に考えて 明らか としか言えない……と思うのだけども……」といった感じに,なにやらちょっとでも心配な気がするようならば,
    備えとして書いておくとか,
    あるいは,既に他の方々が述べられているような,網羅していることがより明確になる形の書き方にしておけばよいのではないでしょうか.


皆様はどのようにされてますか?また何故そうしているのかという考え方もお聞きしたいです。

私の場合,自分自身の頭の悪さを十分心得ており,
「今現在の自分にとっては明らかだとしても,忘れた頃にコードを読む将来の自分がどうなのかはわからない」みたいな不安に怯えながらコードを書くことが多いので,
なるべく/少しでも そういった点で安全そうな(?)方向で書くようにしています.
今回のケースであれば,例えば最後の条件「④11より大きい」を「その他の場合(Case Else)」として実装し,何ならそこに「11より大きい場合」とかいう注釈すら添えるかもしれません.

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

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

#4

yambejp

総合スコア116629

投稿2023/09/01 03:32

編集2023/09/01 03:43

今回の命題だと
10以下は
Txtbox_FontSize = 25
ですね。10と10未満を分ける必要は感じません。

11まではTxtbox_FontSizeを設定していますが
それ以上になるとTxtbox_FontSizeではなくsyamei_FontSizeが対象になっています。

そうなるとあとから変数を評価するときに未定義エラーになる可能性があるので注意が必要でしょう。

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

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

#5

maisumakun

総合スコア145956

投稿2023/09/01 03:40

「整数のつもりが小数が来たなど、型の違う値が投入されてしまった」とか「NaNやSQLのNULLなど、不等号が何も成立しないような値」など、イレギュラーケースはちょくちょくありますね。

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

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

#6

ikedas

総合スコア4443

投稿2023/09/01 04:47

編集2023/09/01 04:48

ご質問の例だと、変数exampleはInteger型なので0や負の値も取りうるわけですよね。 例ではたしかにそれも「網羅」はされていますが、コードを書く際にそのようなパターンを想定しているでしょうか。---今回は想定しているのかもしれませんが、単にすべてのパターンを網羅した (とみなせる) だけではそのことは保証されていないようにも思います。

そうしたことを考えると、Case Else以外の各Caseでは処理対象として想定されるパターンをできる限り明示しておき (たとえば①は「1以上10未満」)、Case Elseは想定外のパターン (0や負や未知の何か) を想定した処理に使うというのもありなのかと思います。

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

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

#7

yambejp

総合スコア116629

投稿2023/09/01 05:08

#4

Txtbox_FontSizeではなくsyamei_FontSize

Txtbox_FontSizeとsyamei_FontSizeの使い分けは不要でしたか・・・

であれば

Txtbox_FontSize = 25
とデフォで設定しておいて、
11のときTxtbox_FontSize = 26
12位上のときTxtbox_FontSize = 27
という条件は2つでよいでしょう

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

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

#8

pecmm

総合スコア660

投稿2023/09/01 08:46

よっぽど使い捨てのコードでなければ、私はcase elseに該当する箇所で

  • 値をデバッグログに出力
  • 「想定しない値:〇〇」という旨のメッセージと共にException類を発生させて強制終了

のように書きます。(※言語によって書けない場合など対応は変わると思いますが……)


すでに散々言われていますが「全てのパターンを網羅している」というのは
「最初にコードを書いた瞬間」かつ「型レベルで絶対に漏れがないことを断言できる時」に限られる、と思っておいた方が色々と安全です。

また、想定していない値が来たにも関わらず適当な値で代用して処理を継続、というのはあまり良くないです。
そこ以前の処理で想定してない値が発生してしまった場合の発覚を遅らせる(問題の原因をたどりづらくする)、
別の箇所のコード修正時の考慮漏れ・修正ミスに気づきにくくなる、等のリスクにつながります。

この方針の「Exception類で強制終了」というのは
あくまでデバッグやテスト時に問題が発覚しやすくするためであり
実運用前に同値・境界値に関するテスト等しっかりとして、エンドユーザにこのような例外は見せるつもりはない前提です。

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

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

#9

xebme

総合スコア1090

投稿2023/09/01 21:05

コードの保守

#8 のご指摘のようにコードは常に変化します。自分がコードを修正するとしても時間がたてば忘れてしまいます。他人がコードを修正することも。将来コードにcaseが追加、削除されてバグが書き込まれることはおおいにありえます。

失敗させる

バグに気付かせるため、到達不能なCase Elseを記述しておき、失敗コードを記述します。

vba

1Case Else 2 Txtbox_FontSize = -1 ' 到達不能

他の言語だと、assert falseを記述するか、例外を投げる、のが常套手段です。
また、到達不能文を記述しないと構文エラーになることがありますが、そのような場合も失敗させます。

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

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

#10

退会済みユーザー

退会済みユーザー

総合スコア0

投稿2023/09/03 23:08

皆様、貴重なご意見をありがとうございました。

やはりCase Elseは不要ではなく、教科書通り「予測していない」場合に備えておくためのものだと認識できました。
今後は想定外の値に飛んだ、というメッセージを表示するコードを記述しておこうと思います。
ありがとうございました。

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

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

#11

take88

総合スコア1458

投稿2023/09/08 23:47

編集2023/09/08 23:50

書籍に書いてあることを文字通りに理解すればいいと思うんですが、数値型で全てのパターンを網羅している場合、Case Elseは必要ありません。あくまで「予測していない値の処理を行うため」にCase Elseを書きます。

言い換えると、評価式によって返されるデータ型の取りうる範囲全てのケースを網羅していればCase Elseは論理的には必要ない、と言えると思います。

しかし、そこに、プログラマーの間違いや、プログラムの修正による影響などで、不具合が生じる可能性が高い(つまりバグが混入しやすい)ということを、経験的に知っているので、その間違いを未然に防ぐという意味で、Case Else を書く、というノウハウが広く認知されているわけですね。

(防げるとも限らないんですけどね・・・)

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

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

#12

退会済みユーザー

退会済みユーザー

総合スコア0

投稿2023/09/19 03:54

不要でしょう。全てのパターンを網羅しているのなら例外に飛ぶはずがない、無駄に容量を食うだけ。

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

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

最新の回答から1ヶ月経過したため この意見交換はクローズされました

意見をやりとりしたい話題がある場合は質問してみましょう!

質問する

関連した質問