Visual Basic 初級講座 [改訂版]
VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

第11回 論理式

2020/5/2

この記事が対象とする製品・バージョン (バージョンの確認方法)

VB2019 Visual Basic 2019 対象です。
VB2017 Visual Basic 2017 対象です。
VB2015 Visual Basic 2015 対象です。
VB2013 Visual Basic 2013 対象です。
VB2012 Visual Basic 2012 対象です。
VB2010 Visual Basic 2010 対象です。
VB2008 Visual Basic 2008 対象です。
VB2005 Visual Basic 2005 対象です。
VB.NET 2003 Visual Basic.NET 2003 対象外ですがほとんどの説明があてはまるので参考になります。
VB.NET 2002 Visual Basic.NET (2002) 対象外ですがほとんどの説明があてはまるので参考になります。
VB6対応 Visual Basic 6.0 × 対象外です。

 

目次

1.論理式

プログラムでは条件を式で記述することが良くあります。条件を表す式は True または False で評価できる式であり、このような式を論理式と呼びます。

論理式は If 文の条件の式として使用することが多いですが、他にもいろいろなところで使用します。

慣れないうちは条件を論理式で書くことが難しく、自分が判断したい条件を式でどう書けばよいかなかなかわからないものです。

今回は論理式を記述する基本的な知識を説明します。

 

まず、条件式とは最終的に TrueかFalse で評価される式であるということを次のサンプルで理解しましょう。

この例ではIf文に固定で条件式として True を指定しているので必ず処理が実行されます。

VB6 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If True Then
    MsgBox("Trueです。")
End If

逆に False を指定すると絶対に実行されません。

VB6 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If False Then
    MsgBox("Falseです。")
End If

 

テキストボックスに何も入力されていないかを判断する Len(TextBox1.Text) = 0 も結果はTrueかFalseになります。このあたり直感的にわかりにくいようなら少しプログラムで確認してみましょう。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'Trueになります。
Dim b1 As Boolean = (1 + 2 = 3)

'Falseになります。
Dim b2 As Boolean = (1 + 2 = 4)

'Falseになります。ABCは3文字なので。
Dim b3 As Boolean = (Len("ABC") = 0)

'Trueになります。
Dim b4 As Boolean = (Len("") = 0)

'TextBox1の入力内容によってTrueまたはFalseになります。
Dim b5 As Boolean = (Len(TextBox1.Text) = 0)

この例を見るとわかるように = による比較は TrueまたはFalseを返す計算式なのです。= には値を代入するという機能もあるので混乱するかもしれませんが、この2つの機能はまったく別のもので構文によって区別されます。比較の = には値を代入する機能はありません。

b1~b4まではTrueになるかFalseになるかは事前にわかっている式で、学習のために並べて書いてみただけですが、最後の b5 は TextBox1に何か入力されていれば False、何も入力されていなければ True になり、実行するまで結果がわかりません。

この例のb5とIf文を組み合わせても意図通り動作します。

条件式は True または False になる式であれば何でも良いので If とともに = を使うことは必須ではありません。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim b5 As Boolean = (Len(TextBox1.Text) = 0)

If b5 Then
    MsgBox("何か入力してください。")
End If

 

プロパティやメソッドには論理型の戻り値を返すものが多数あります。論理型とは TrueまたはFalseのことですから、If文の条件式として利用できます。

たとえば、CheckBox(読み方:CheckBox = チェックボックス)がチェックされているかどうかは、Checkedプロパティ(読み方:Checked = チェックド)で判断できます。このプロパティはBoolean型でチェックされている場合Trueです。

試しにフォームにCheckBoxを1つ配置して、Buttonのクリックイベントハンドラーに次のプログラムを実行してみてください。ButtonをクリックするとCheckBoxがチェックされているのかどうか判断できます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If CheckBox1.Checked Then
    MsgBox("チェックされています。")
End If

チェックボックスにチェックをつけているときだけメッセージが表示されることを確認できると思います。

If文やBoolean型の理解が不足している初心者の方は余分な「 = True 」をつけて次のように書く傾向があります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If CheckBox1.Checked = True Then
    MsgBox("チェックされています。")
End If

これでも機能は同じでちゃんと動作はします。しかし、Checkedプロパティ自体がBoolean型であるので、 = True は意味のない無駄な記述であることはおわかりいただけるでしょうか。

 

Fileクラスの共有メソッドであるExists(読み方:Exists = イグジスツ)はファイルが存在するかどうか調べて、存在する場合Trueを存在しない場合Falseを返します。これを使って、C:\Temp\Test.txtというファイルが存在するか調べるプログラムは次のようになります。

FileクラスはSystem.IO名前空間に属しているので、デフォルトのWindowsフォームアプリケーションだとSystem.IO.Fileと記述するか、Systemだけ省略してIO.Fileと記述する必要があります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If IO.File.Exists("C:\temp\test.txt") Then
    MsgBox("このファイルは存在します。")
End If

 

 

2.比較演算

2-1.比較演算子

= や < 、 > などの演算子は2つの値を比較して、結果を True か False で返します。

これらは比較演算子と呼ばれます。

メモ メモ  -  演算子

+ - など計算を実行する要素のことを「演算子」(えんざんし)と呼びます。英語ではOperator(オペレーター)と呼びます。

一方、演算子によって計算される要素のことを「オペランド」と呼びます。たとえば、 7 + 5 という式ではオペレーターは + で、オペランドは7と5です。学校で習う演算子のほとんどは2つの要素(オペランド)を処理するので2項演算子と呼びます。

数学で階乗の演算子である ! は 5! のように、1つの要素(オペランド)だけで計算するので単項演算子です。(数学では 5! = 5 × 4 × 3 × 2 × 1 = 120 という意味です。)

Visual Basicの世界でも二項演算子と単項演算子があります。また、記号ではなくアルファベットや単語で記述する演算子もあります。

 

計算結果が TrueまたはFalseになるので、条件式として使用できます。

比較演算を行う演算子には次のものがあります。どれも直感的に理解できると思います。

演算 意味
A = B A と B が等しければ True を返します。
A < B A が B より小さければ True を返します。(同じ場合は False です。)
A <= B A が B 以下ならば True を返します。(同じ場合は True です。)
A > B A が B より大きければ True を返します。(同じ場合は False です。)
A >= B A が B 以上ならば True を返します。(同じ場合は True です。)
A <> B A と B が異なるならば True を返します。

※これ以外にもIs, IsNot, Likeという比較演算子があります。

 

例によって勉強用以外に意味のないプログラムですが使用例を示します。

VB6 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If 5 = 5 Then
    '表示されます。
    MsgBox("A")
End If

If 2 + 3 = 5 Then
    '表示されます。
    MsgBox("B")
End If

If 3 < 100 - 1 Then
    '表示されます。
    MsgBox("C")
End If

If 5 <> 5 Then
    '表示されません
    MsgBox("D")
End If

この例はどれも固定の数値同士の比較なので実行する前から結果がわかっている点で意味のないプログラムです。

実用的な例になると固定値ではなく変数やメソッド・プロパティなどを使うことになります。

いくつか例を示します。

VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'TextBox1に入力されている文字数が 0 であるか判断する。
If Len(TextBox1.Text) = 0 Then
    MsgBox("何か入力してください。")
End If

'時間が20時以降であるか判断する。
If Now.Hour >= 20 Then
    MsgBox("8時を過ぎていますね。もう寝ましょう。")
End If

'マウスのボタンの数が5であるか判断する。
If SystemInformation.MouseButtons = 5 Then
    MsgBox("5ボタンのマウスを使っていますね!")
End If

 

2-2.インスタンスの比較

値ではなくクラスのインスタンスが同一であるかどうか比較する Is演算子(読み方:Is = イズ)とIsNot演算子(読み方:IsNot = イズノット)があります。

次の例では変数 t は TextBox1を指しているので、t Is TextBox1 が Trueになります。

 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim t As TextBox = TextBox1

If t Is TextBox1 Then
    '実行されます。
    t.Text = "私はTextBox1です。"
End If

この例はほとんど意味がないのですが、オブジェクト指向を活用してプログラムしているIsが役に立ってくる場合があります。

次の例はButton1_Clickイベントですが、Handles句にButton1.ClickとButton2.Clickの2つが指定されていることに注目してください。

このように記述すると、Button1をクリックしてもButton2をクリックしてもこのイベントハンドラーが実行されます。(この例を試すには自分でHandles句を記述するか、プロパティウィンドウを使います。)

イベントハンドラーの引数senderはイベントを発生させたオブジェクト(コントロール)を指すのですが、Button1なのかButton2なのかわかりません。Isの出番です。

 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click

    If sender Is Button1 Then
        MsgBox("Button1がクリックされました。")
    Else
        MsgBox("Button2がクリックされました。")
    End If

    CType(sender, Button).BackColor = Color.Red

End Sub

もっともこの例も良い例ではなく、この内容ならばButton1とButton2のイベントハンドラーは分けて書くべきです。1つのイベントハンドラーで複数のボタンを処理するなんてわかりにくいですよね。

Button1とButton2で共通の処理がある場合はイベントハンドラーを一緒にするのではなく、共通の処理をメソッド化して呼び出すようにするのが普通です。メソッドを作成する方法は別の機会に説明します。

 

IsとNothingを組み合わせると変数が初期化されているかどうか判断できます。初期化されていない変数のメソッドやプロパティを呼び出すとNullReferenceExceptionでエラーになるので、初期化されているか不明であればこれでIf文を使って確認することができます。

次の例はさいころをシミュレーションする例で、ボタンをクリックするたびに1~6の数字をランダムに表示します。

RandomクラスのNextメソッドを使うと簡単に実現できます。Next(1, 7)の意味は1以上で7より下の数値をランダムに生成するという意味でつまり1から6です。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim saikoro As Random

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    If saikoro Is Nothing Then
        saikoro = New Random
    End If

    MsgBox(saikoro.Next(1, 7))

End Sub

この例ではRandomクラスのインスタンスは1度作ればよいので、変数saikoroがNothingだったらNewを使用してコンストラクターを呼び出すが、そうでなければコンストラクターは呼び出さないという動きになります。

変数saikoroを宣言するときにAs Randomではなく、As New Randomとすると、ボタンクリック時にNothingであるかどうか確認する必要はなくなりますが、使わないかもしれないサイコロが必ずNewされることになり無駄です。実際のところRandomクラスのインスタンスを無駄に1つ作成するくらいは問題ならないのですが、インスタンスを作成するのが非効率なクラスもあり、使用することが確定した段階でインスタンスを作成するのが性能に優れている場合があります。

IsNot はすべてこの逆です。

sender IsNot Button1 はsenderがButton1ではなかったらという意味になりますし、saikoro IsNot Nothing はサイコロがNothingでなかったらという意味になります。

 

発展 発展学習  -  型の比較 TypeOf x Is TextBox

発展学習では意欲的な方のために現段階では特に理解する必要はない項目を解説します。

特殊な構文TypeOfとIsを組み合わせると変数の型を判断することができます。型を判断してどのような良いことがあるかは初級講座の現段階では説明できないので紹介するにとどめておきます。

 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If TypeOf sender Is Button Then
    MsgBox("senderはButtonです。")
End If

2-3.文字列の比較

文字列など他の型でも同じように比較演算子を使用できます。文字列の比較は詳しく見ていくといろいろ理解する必要があるため、詳しくは別の機会に説明します。

簡単に説明するとデフォルトの設定では英語の大文字と小文字は別の文字とみなされ、日本語のひらがなとカタカナも別の文字とみなされます。

VB6 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If "あざらし" <> "アザラシ" Then
    '表示されます。
    MsgBox("ひらがなとカタカナは等しくないです。")
End If

If "VB" <> "vb" Then
    '表示されます。
    MsgBox("英語の大文字と小文字も等しくないです。")
End If

 

このデフォルトの動作を変えるOption Compare Text(読み方:Option = オプション、Compare = コンペア、Text = テキスト)という宣言があります。

プログラムの冒頭に Option Compare Text と記述すれば上述の例は反対の結果になります。メッセージは表示されなくなります。

既定の設定を明示するには Option Compare Binary (読み方:Binary = バイナリー)と記述しますが、記述を省略すればBinaryと同じなので通常はわざわざOption Compare Binaryを記述することはありません。

Option Compareの宣言 英語の大文字と小文字 ひらがなとカタカナ
Option Compare Text 同じと判断します。 同じと判断します。
Option Compare Binary 異なるものと判断します。 異なるものと判断します。

プロジェクトのプロパティでOption Compareを指定することもできます。ここで指定するとプロジェクト全体で設定値が有効になり、個別に「Option Compare Text」を記述する必要をなくせます。

 

Option Compare Textは、プログラムへの影響が大きいため初心者の方は使用しないことをお勧めします。中級者以上の方は慎重に検討したうえで使用有無を判断してください。Option Compare Textのわかりにくいところは、既定値ではないという点とほとんど人がこの設定を変更しないという点です。プログラマーの多くはプログラムを見たときに、Option Compareの設定値を確認しません。Option Compareは既定値まま(つまり、Binary)であると思い込んでいます。確認もせず思い込んでいるほうが悪いといわれればそうかもしれないのですが、とにかく混乱が発生するのです。混乱は誰にとっても望まれるものではないですよね。避けられるのであれば避けたいです。避けるためにはOption Compare を Text にするべきではないのです。

それに、Option Compare Textはそんなに便利でもありません。混乱させてまで使う理由はないように思います。

 

Option Compare Binary、つまり既定の状態で英語の大文字と小文字を同じとみなしたい場合、比較演算子では実現できませんので、メソッドを使用します。

たとえば、Stringクラスの共有メソッド Equals(読み方:Equals = イクォールズ)は文字列を比較して等しければ True を、等しくなければ False を返すメソッドです。論理型を返すメソッドなので条件式に使用できます。このメソッドは第3引数で比較方法を指定することができて、StringComparison.InvariantCultureIgnoreCase (読み方:StringComparison = ストリングコンパリゾン、InvariantCultureIgnoreCase = インヴァリアントカルチャーイグノアケース)を指定すると、大文字と小文字を同じものとみなして比較します。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If String.Equals("VB", "vb", StringComparison.InvariantCultureIgnoreCase) Then
    '表示されます。
    MsgBox("英語の大文字と小文字は等しいとみなします。")
End If

ひらがな・カタカナについては日本固有の文化のため、もう少し面倒なプログラムが必要になります。次のプログラムでは「あざらし」と「アザラシ」を同じと判断できます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim culture As Globalization.CultureInfo = Globalization.CultureInfo.InvariantCulture
Dim kanaOption As Globalization.CompareOptions = Globalization.CompareOptions.IgnoreKanaType

If String.Compare("あざらし", "アザラシ", culture, kanaOption) = 0 Then
    '表示されます。
    MsgBox("日本語のひらがなとカタカナは等しいとみなします。")
End If

このプログラムは、今回説明したい比較の仕組みとは別にStringクラスのCompareメソッドを使用して独自の判断を行っているものです。今回のテーマとは異なるので例を紹介するにとどめ、詳細は割愛します。比較オプションに日本語を意識したIgnoreKanaType(読み方:IgnoreKanaType = イグノアカナタイプ)という日本語処理用の値が用意されているのはありがたいですね。英語以外で専用のオプションがあるのは日本語だけです。

 

2-4.文字列のパターンマッチング

文字列の場合、単に等しいか等しくないかだけではなく、特定のパターンにマッチするかを調べたいときがあります。この機能をパターンマッチングと呼びます。

文字列がIPアドレスの形式になっているか、yyyy-MM-ddの形式になっているか、書籍のISBNの形式になっているかなどです。

Like演算子 (読み方:Like 演算子)を使うと簡単にパターンマッチングできます。

 

ためしに、文字列の末尾が「.vb」で終わっているかをパターンマッチングで調べてみましょう。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If TextBox1.Text Like "*.vb" Then
    MsgBox("vbファイルですね!")
End If

Likeを使ってパターンマッチングするときは * などの記号に特別な意味があります。

特別な意味のある記号 特別な意味 Trueになる例
? 何か1文字(数字でも漢字でもなんでもOK) "ABC" Like "A?C"
* 0個以上の何かの文字(数字でも漢字でもなんでもOK) "ABCDE" Like "A*E"
# 1文字の数字 "AB-123" Like "AB-###"
[ ] [ ] 内のどれか1文字 "12" Like "[0-2][0-9]"
[! ] [! ] 内のどれか1文字以外の1文字 "12" Like "[!3-9][0-9]"

ファイルの検索処理などで便利です。 特に * はよく使います。

メモ メモ  -  Unicode 第2面以降の文字には注意
Microsoftのドキュメントには ? は任意の1文字と書いてありますが、Unicode第2面以降の文字はここでは2文字扱いになりますので注意してください。絵文字やかなり難しい漢字がこれに該当します。
Like演算子は簡易的なパターンマッチングと考えることにして、どのような文字でも対象にしたい場合は、正規表現を使ったほうが良さそうです。

Like 演算子 (Visual Basic)
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/language-reference/operators/like-operator

 

Like演算子によるパターンマッチングは簡単で便利ですが、機能が少ないことと、VB独自の機能であることから最近(2020年4月現在)はあまり見かけません。正規表現(せいきひょうげん)という機能は、かなり複雑なパターンマッチングが記述でき、機能も豊富でプログラム言語を問わずに使用できることが多いためこちらの方が好まれています。

参考に拡張子が .vb であるか正規表現で判断する例を紹介します。いろいろな書き方がありますのでこれは一例です。

VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim regex As New System.Text.RegularExpressions.Regex("\.vb$")

If regex.IsMatch(TextBox1.Text) Then
    MsgBox("vbファイルですね!")
End If

 

なお、文字列が「.vb」で終わっているかという簡単な判定ならばパターンマッチングを使わないでEndsWithメソッド(読み方:EndsWith = エンズウィズ)でも判断できます。EndsWithメソッドはその名の通り「文字列の末尾が指定したものになっているか」を調べるメソッドです。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If TextBox1.Text.EndsWith(".vb") Then
    MsgBox("vbファイルですね!")
End If

 

 

3.論理演算

3-1.かつ・または

「AでありかつB」や「AまたはB」のような条件は論理演算子を使った式で表現できます。

それには、AndAlso(読み方:アンドアルソー)とOrElse(読み方:オアエルス)を活用します。

AndAlsoは「かつ」を表し、OrElseは「または」を表します。

たとえば、TextBox1に入力されているのが Apple または Banana の場合のみメッセージを表示するには、次のようにします。

VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If TextBox1.Text = "Apple" OrElse TextBox1.Text = "Banana" Then
    MsgBox("AppleまたはBananaが入力されています。")
End If

次の例では、C:\temp\test.txtファイルが存在し、かつ、最終更新日が1年以上前であれば、このファイルを削除します。

VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim fileName As String = "C:\temp\test.txt"

If IO.File.Exists(fileName) AndAlso IO.File.GetLastWriteTime(fileName) <= Now.AddYears(-1) Then
    IO.File.Delete(fileName)
End If

ファイルの最終更新日を取得するにはFileクラスのGetLastWriteTimeメソッド(読み方:ゲットラストライトライム)を使用します。現在の日付は Now(ナウ)で取得できます。1年前の日付はNowに -1 年をたしたものですので、Now.AddYears(-1)です。

Now.AddYears(-1)より日付が小さいということは、1年以上前であるという意味になります。

AndAlsoやOrElseがでてくると、プログラムの1行が長くなって見にくくなるので、その直後で改行しても良いことになっています。たとえば、上の例は改行を追加して次のように書くこともできます。

VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim fileName As String = "C:\temp\test.txt"

If IO.File.Exists(fileName) AndAlso
   
IO.File.GetLastWriteTime(fileName) <= Now.AddYears(-1) Then
   
    IO.File.Delete(fileName)

End If

VB2008以前はプログラムを改行するには必ず改行記号 _ を使う必要がありますので、AndAlsoの後ろに _ を追加して「AndAlso _」と書くことで改行できます。

改行記号 _ を使うと AndAlsoやOrElseの前で改行することもできます。

VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

Dim fileName As String = "C:\temp\test.txt"

If IO.File.Exists(fileName) _
    AndAlso IO.File.GetLastWriteTime(fileName) <= Now.AddYears(-1) Then

    IO.File.Delete(fileName)

End If

私は条件式で改行するとIfの中身と区別しにくくなるのであまり改行は好みではありませんが、条件がたくさんある場合は、改行することが多いです。

 

3-2.3つ以上の条件

成人かどうか判断するプログラムを考えて見ましょう。

話を単純にするために日本・イギリスの2カ国だけで考えます。

日本では20歳以上なら成人です。イギリスでは18歳以上が成人です。

まずフォームにComboBoxを配置し、日本かイギリスを選択できるようにしましょう。名前はデフォルトのComboBox1とします。

プロパティウィンドウでComboBoxのItemsプロパティ欄に表示される ... ボタンをクリックすると選択肢を入力できます。1行目に「日本」を、2行目に「イギリス」を入力してください。

これでユーザーは日本・イギリスを選択できるようになりますが、手入力で他の値も入力できてしまうので、これを防ぐために ComboBoxのDropDownStyleプロパティをDropDownList にしておいてください。こうしておくと、手入力はできなくなります。

次に年齢のためにNumericUpDownコントロールを1つ配置してください。これも名前はデフォルトのNumericUpDown1とします。これは数値を入力するコントロールです。デフォルトではフォントが小さくで使いにくいでお好みで調整してよいです。

後は判断処理を実行するためのボタン Button1 があれば準備完了です。なければ配置してください。

Button1のクリックイベントにその人が成人かどうか判断するプログラムを書いてみましょう。たとえば、次のようになります。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If ComboBox1.Text = "日本" AndAlso NumericUpDown1.Value >= 20 Then
    MsgBox("成人です。")
ElseIf ComboBox1.Text = "イギリス" AndAlso NumericUpDown1.Value >= 18 Then
    MsgBox("成人です。")
Else
    MsgBox("未成年です。")
End If

これで問題なく動きますが、今は論理演算の勉強をしているので、少しこだわってみましょう。

20歳以上なら日本でもイギリスでも成人なので、日本かどうかを確認する必要はありません。そこで次のように書き換えることができます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If ComboBox1.Text = "イギリス" AndAlso NumericUpDown1.Value >= 18 OrElse NumericUpDown1.Value >= 20 Then
    MsgBox("成人です。")
Else
    MsgBox("未成年です。")
End If

このプログラムは正常に動作します。しかし、読みにくくて要するにどういう条件なのかぱっと見よくわからいですね。

1つの式の中で論理演算子が2つになるとたちまちわかりにくくなります。

かっこをつけると少しはわかりやすくなります。

2つ以上の演算子を使う論理演算は少しでも可読性を向上させるためにかっこをつけることをお勧めします。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If (ComboBox1.Text = "イギリス" AndAlso NumericUpDown1.Value >= 18) OrElse NumericUpDown1.Value >= 20 Then
    MsgBox("成人です。")
Else
    MsgBox("未成年です。")
End If

計算式の途中をかっこで囲むとその部分は先に計算されますので、式によっては結果が変わってしまいます。

AndAlsoとOrElseはもともとAndAlsoの方が先に計算されるルールなので、この例の場合は、同じ結果になります。

このOrElseよりAndAlsoの方が先に評価されるという性質は覚えて置いてください。

今回のように、 A AndAlso B OrElse C という記述は、C が Trueの場合は、AとBが False でも全体として Trueになります。

 

私はプログラムをしていて条件が3つ以上になるとうんざりします。初級講座ではまだ説明していないテクニックを使って、できるだけ条件式をシンプルにすることもできますが、それでも3つ以上の条件を記述するときがときどきあります。改行やカッコ、それにコメントを使って、どういう条件なのか理解しやすいように工夫しておきましょう。

 

3-3.否定(・・・ではない)

Not(読み方:ノット)を使って、「・・・ではない」という条件を表現することもできます。

NotはTrueをFalseに、FalseをTrueに反転するだけのシンプルな演算子です。

 VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

'Trueになります。
Dim b1 As Boolean = Not False

'Falseになります。
Dim b2 As Boolean = Not b1

'Falseになります。
Dim b3 As Boolean = Not (1 + 1 = 2)

 

OSの判定機能で試してみましょう。

RuntimeInformationクラスのIsOSPlatformメソッド(読み方:RuntimeInformation = ランタイムインフォメーション、IsOSPlatform = イズオーエスプラットフォーム)は、実行されているOSがWindowsかLinuxかMac OSXかを判断できます。

このメソッドはかなり新しいメソッドで.NET Frameworkの場合 4.7.1以上でないと使用できないので、アイコンはVB2015以上としましたが、 Not 自体はVB1(1989年発売)から使えると思います。

※Visual Studio 2013以前でも実行できるかもしれませんが裏が取れなかったためアイコンは2015以上としています。

 

Linuxで実行されているかどうか調べるには次のようにします。

VB2015 VB2017 VB2019

Dim linux = Runtime.InteropServices.OSPlatform.Linux

If Runtime.InteropServices.RuntimeInformation.IsOSPlatform(linux) Then
    'Linux用の処理をここに記述する。
End If

これにNotをつけると判断が逆転します。つまり、linuxでないことを判断できるようになります。

VB2015 VB2017 VB2019

Dim linux = Runtime.InteropServices.OSPlatform.Linux

If Not Runtime.InteropServices.RuntimeInformation.IsOSPlatform(linux) Then
    'Linuxではない場合の処理をここに記述する。
End If

もっとも、この場合IsOSPlatformメソッドはFalseを返すので、 比較演算子を使っても同じ判断ができます。

VB2015 VB2017 VB2019

Dim linux = Runtime.InteropServices.OSPlatform.Linux

If Runtime.InteropServices.RuntimeInformation.IsOSPlatform(linux) = False Then
    'Linuxではない場合の処理をここに記述する。
End If

次のような書き方もできます。

VB2015 VB2017 VB2019

Dim linux = Runtime.InteropServices.OSPlatform.Linux

If Runtime.InteropServices.RuntimeInformation.IsOSPlatform(linux) <> True Then
    'Linuxではない場合の処理をここに記述する。
End If

 

If文以外の場所でもTrue/Falseを反転させる処理を書くときに Not は便利です。

たとえば、CheckBox1がチェックされていたらチェックをはずす、チェックされていなければチェックをつけるというプログラムは、CheckBox1のCheckedプロパティの値を反転させるという処理と同じ意味なので、Notを使うとこのように簡単に書けます。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

 
CheckBox1.Checked = Not CheckBox1.Checked

 

3-4.ショートサーキット

みなさんを混乱させてしまうので、言いたくないのですが、知っておかないと困るときがあるのでこの機会に説明すべきことがあります。

AndAlso、OrElseのほかに、And、Or という論理演算子もあります。(読み方:And = アンド、Or = オア)

でも、使わないでください。

計算結果は、AndAlso,OrElseと同じなのですが、計算する方法に違いがあり、思わぬバグとなってしまうことがあります。

例として次のプログラムを考えます。

このプログラムはTextBox1に入力されている1行目はHelloだったらメッセージを表示するというものです。

TextBoxを複数行入力可能にするにはMultiLineプロパティをTrueにして、大きめに配置します。

VB.NET 2002 VB.NET 2003 VB2005 VB2008 VB2010 VB2012 VB2013 VB2015 VB2017 VB2019

If TextBox1.Lines.Count > 0 AndAlso TextBox1.Lines(0) = "Hello" Then
    MsgBox("1行目は Hello です。")
End If

このプログラムでは、まだ初級講座では説明していない配列という技術を使っていますが、今はAndAlsoとAndの説明をしたいので、説明は割愛します。

このプログラムでは、If文の1つ目の条件で、TextBoxの行数が0より大きいか判断しています。2つ目の条件で1行目が"Hello"であるかを判断しています。

この2つ目の条件は1行目が存在することが前提になっており、存在しないとエラーです。(1行目を取得して、それが"Hello"であるかを調べるロジックなので、1行目がそもそも存在しないとエラーというわけです。)

AndAlsoは1つ目の条件がFalseだった場合、2つ目の条件を評価しません。なぜなら両方Trueじゃないと条件が成立しない式になっているので、1つ目の条件がFalseである時点で、この条件が成立する可能性がないからです。だから、1行目が存在しない場合でもエラーになります。

このように、TrueかFalseか確定した時点でそれ以上、条件の式を計算しない方式をショートサーキット(短絡評価)と呼びます。AndAlsoとOrElseはショートサーキットで計算を行います。

 

一方、Andの方はTrueかFalseか確定しても、まだ評価していない式が残っていればとりあえず全部評価します。そうすると、この例の場合、TextBox1に何も入力されていない場合、2つ目の条件を評価しようとしてエラーになってしまうのです。

 

ちょっと難しい説明だったかもしれません。私のショートサーキットの説明は下手なように思います。やはり混乱させてしまったでしょうか。

結論は簡単なんです。And、Orは条件の式としては使わないでください。絶対に。