• ベストアンサー

「Xor」と「Or」の違い(vba)

こんばんは。 よくわからないので教えてください。 Option Explicit Sub Xorのtest() Dim フルーツ As String フルーツ = "りんご" If フルーツ = "りんご" Xor フルーツ = "イチゴ" Then MsgBox フルーツ End If End Sub '**************************************** Sub Orのtest() Dim フルーツ As String フルーツ = "りんご" If フルーツ = "りんご" Or フルーツ = "イチゴ" Then MsgBox フルーツ End If End Sub 上記のコードなのですが どちらも結果は同じです。 「Xor」と「Or」の違いがよくわからないのですが 何が違うのでしょうか? 調べてみると「Xor」は「排他的理論和」だそうです。 よろしくお願いします。

noname#150256
noname#150256

質問者が選んだベストアンサー

  • ベストアンサー
  • aigaion
  • ベストアンサー率47% (287/608)
回答No.1

or は論理和ですね。 A or B といった場合に、A と B のどちらかが真なら A or B も真となる。 一方排他的論理和の場合は A Xor B といった場合に、A と B の真偽が違えば A Xor B が真となります。 例えば A が 真で B が 偽の場合とその逆ですね。

noname#150256
質問者

お礼

うーん、、、 難しいですね、、、 私の示したコードで表すならどういう風にすればいいでしょうか? ご回答いただいたのにすいません、、、

その他の回答 (6)

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.7

昔々に、機械語やアセンブラでビット演算で重宝したものだが、文字列を扱う、質問のような例で、XORを考える機会は無いと思う。 もっとほかのことで、VBAで勉強した方が良いことが沢山有る。 そんなこと全て終わった、VBAの熟達者やビット演算に関係有る業界でなければ、XORのことは忘れて良いと思う。 GoogleででもXORやORの解説記事をよみ、どんな場合に良く使いかも含めて勉強のこと。 数学・論理を基礎に置くものなので、意味は明確であいまいなところはない。

noname#150256
質問者

お礼

ありがとうございます。

  • s-uzen
  • ベストアンサー率65% (2051/3118)
回答No.6

No2です。 > こういうことですよね? > 「Xorのtest」のほうはどちらも該当するからダメと言うことですよね? まぁ、考え方としてはそういうことになるのですが、厳密に言うと比較対象範囲のビットごとの比較ということになってきますので、文字列の場合は期待するものと結果が異なる場合があるかもしれません。 どのような時に違うかは確認していませんが、文字コードのビットパターンで比較すれば良いだけですが、同じ文字列なら同じビットパターンとなるので、Xorの結果は偽(0)であることは明白であることです。 ただ、文字列比較の場合は、比較演算子とAnd、Orの組み合わせで殆ど対応でき、他人が見ても理解もし易いので、私はXorを文字列比較に使ったことはありません。 昔は諸々の制約などから、シフトや論理演算、その他の組み合わせなどで、プログラムをシンプルにしたり、高速化したりのテクニックを使うこともあったのですが、今はそういうことよりも、如何に分かり易いプログラムにするかのほうが重要と思います。  

noname#150256
質問者

お礼

再度ありがとうございます。 わかり易いものを心がけます。

noname#168404
noname#168404
回答No.5

No.4です。 trueとfalseの厳密な定義は、 false=0 true=0以外 です。(true=1と思いがちですが) また、XOR(排他的論理和)は論理演算(ビット演算)ですが、AND(論理積),OR(論理和)は、AND(かつ),OR(あるいは)と結果的に同じ答えになるため混同して使われることが多いようです。 つまり、質問の例題(?)はXORを理解する上で適切なものと言えません。 XORを実際に使用する時には、ビット演算なので必ずビットに対して意味がなければ、わかりにくくなるだけで使う意味がありません。 そのため、No.4の例でも 「冷蔵庫が欠品」KPN_REIZOUKO=0001 「炊飯器が欠品」KPN_SUIHANKI=0010 「冷蔵庫が発注済み」HCU_REIZOUKO=0001 「炊飯器が発注済み」HCU_SUIHANKI=0010 などとわかりやすい名称を割り当てて使うのが一般的です。 ですから、質問の例題はプログラミングの難しさを説明するには最適でしょうが、絶対にこんな使い方はしません。

noname#150256
質問者

お礼

あまり使わないのですね。ありがとうございます。

noname#168404
noname#168404
回答No.4

補足的な説明をさせて頂きます。 昔は、メモリ容量(&ディスク容量)がさほどなかったため、それを節約するためなどにビットでの情報保持が用いられていました。 つまり、0,1(false/true)の1ビットに有/無などの意味を持たせて使っていました。 最近ではメモリ容量も大きくなり、それに伴いビット操作はあまり使われなくなってきました。 たとえば、欠品した時に(1,true)として 1(0001).冷蔵庫が欠品で1 2(0010).炊飯器が欠品で1 4(0100).電子レンジが欠品で1 8(1000).掃除機が欠品で1 (左の数字は「10進数(2進数)」です) また、上記とは別に発注した時に(1,true)として 1(0001).冷蔵庫が発注済みで1 2(0010).炊飯器が発注済みで1 4(0100).電子レンジが発注済みで1 8(1000).掃除機が発注済みで1 (左の数字は「10進数(2進数)」です) この時に、欠品で未発注の商品を調べるとします。 例: 冷蔵庫と炊飯器と電子レンジが欠品の場合 (0111) となります。 炊飯器が発注済みの場合 (0010) となります。 欠品で未発注の商品を調べたい時にXORを使用します。 (0111)xor(0010)=(0101) この結果から、冷蔵庫と電子レンジを発注しなければいけないことがわかります。(掃除機は在庫あり、炊飯器は発注済み) これに「仕入れ停止」などを付けて、さらに条件を絞り込んだりもします。 もっと単純に、発注したら欠品を0にすればいいと思うでしょうが、欠品の有無を他の処理でも認識する必要がある場合には、そう簡単にはできません。(欠品の状態(期間)を明確に定義する必要がありますが) しかし、すでに昔の技術(?)であるため、今ではXORなどのビット操作を使わないことがよりわかりやすいプログラムと言えるでしょう。

noname#150256
質問者

お礼

ビットと絡んでるんですね。 ありがとうございます。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 サンプルのコードはあまりよくありませんね。 >「Xor」は「排他的理論和」だそうです。 これって、英語にはこれに似たような表現があるようですが、日本語には、このような表現がありませんから、これを知らないと翻訳などさせると、必ず間違いが出ます。 例えば、 Non fruit is not both of an apple or a strawberry on a plate. (and ではない) × お皿の上に(あるものは)、両方のりんごかイチゴでないものは、フルーツではない。   ↓ ○ お皿の上に(あるものは)、両方のりんごとイチゴでないものは、フルーツではない。 日本語と英語では、and と or が逆転してしまいます。 XOR 排他的論理和を図式化すると、 ------------------    A    B  判定    ------------------   True True  False  True False True  False True  True  False False False それをコードにすると、  '------------------------------------------- Sub Test1_XOR()   Dim a As String, b As String   a = "りんご"   b = "イチゴ"   If a = "りんご" Xor b = "イチゴ" Then     MsgBox "それらは、いずれかがフルーツである。", vbInformation   Else     MsgBox "それらは、どちらもフルーツではない。", vbExclamation   End If End Sub Sub Test2_XOR()   Dim a As String, b As String   a = "りんご"   b = "イチゴ"   If a <> "りんご" Xor b = "イチゴ" Then     MsgBox "それらは、いずれかがフルーツである。", vbInformation   Else     MsgBox "それらは、どちらもフルーツではない。", vbExclamation   End If End Sub Sub Test3_XOR()   Dim a As String, b As String   a = "りんご"   b = "イチゴ"   If a = "りんご" Xor b <> "イチゴ" Then     MsgBox "それらは、いずれかがフルーツである。", vbInformation   Else     MsgBox "それらは、どちらもフルーツではない。", vbExclamation   End If End Sub Sub Test4_XOR()   Dim a As String, b As String   a = "りんご"   b = "イチゴ"   If a <> "りんご" Xor b <> "イチゴ" Then     MsgBox "それらは、いずれかがフルーツである。", vbInformation   Else     MsgBox "それらは、どちらもフルーツではない。", vbExclamation   End If End Sub '------------------------------------------- Sub Test1_OR()   '比較   Dim a As String, b As String   a = "りんご"   b = "イチゴ"   If a = "りんご" Or b = "イチゴ" Then     MsgBox "それらは、いずれかがフルーツである。", vbInformation   Else     MsgBox "それらは、どちらもフルーツではない。", vbExclamation   End If End Sub '------------------------------------------- 実際にコードで書くと、間違えそうな気がしますので、なかなか書きません。論理演算という方法は、数学的な足し算で、 確かに、判定が、逆転するので、分かりやすいのですが、実際にコードを書くときは、混乱します。

noname#150256
質問者

お礼

難しいですね、、、 ありがとうございます。

  • s-uzen
  • ベストアンサー率65% (2051/3118)
回答No.2

下記の論理演算の意味が理解できればすぐ分かると思います。 真理値表の1と0は、比較結果が真(比較結果が等しい)と偽(比較結果が異なる)と解釈してもらえば分かり易いと思います。 論理演算 http://www.asahi-net.or.jp/~AX2S-KMTN/ref/logicope.html 例えばAとBを比較式とした時に、A Or B と A Xor B の場合 論理和(Or)は、比較結果のAまたはBのいずれかが真ならTrue条件に一致なのに対して、 排他的論理和(Xor)は、比較結果の一方だけが真の場合にTrue条件に一致となります。 AとBが真(同じ)であったり、AもBも偽(異なる)場合は偽となり、True条件にならないということです。 質問の例の場合のそれぞれの比較式の結果から、 Xorの場合は、1 Xor 0 と異なるので、結果は真(1)となり「りんご」と表示、 Orの場合は、1 Or 0 と一方が真(1)なので、結果は真(1)となり、同じく「りんご」が表示されるということです。  

noname#150256
質問者

お礼

ご回答ありがとうございます。少しわかってきました。 Sub Xorのtest() Dim フルーツ1 As String Dim フルーツ2 As String フルーツ1 = "りんご" フルーツ2 = "イチゴ" If フルーツ1 = "りんご" Xor フルーツ2 = "イチゴ" Then MsgBox フルーツ1 End If End Sub Sub Orのtest() Dim フルーツ1 As String Dim フルーツ2 As String フルーツ1 = "りんご" フルーツ2 = "イチゴ" If フルーツ1 = "りんご" Or フルーツ2 = "イチゴ" Then MsgBox フルーツ1 End If End Sub こういうことですよね? 「Xorのtest」のほうはどちらも該当するからダメと言うことですよね?

関連するQ&A

  • 【1】と【2】のvbaは同じ意味ですか?

    【1】 Option Explicit Sub test1() Call test2("aaa") End Sub Sub test2(MyStr As String) MsgBox MyStr End Sub 【2】 Option Explicit Dim MyStr As String Sub test1() MyStr = "aaa" Call test2 End Sub Sub test2() MsgBox MyStr End Sub 結果は同じですが、中身が違います。 今後コードを作っていく上で どちらの方式の方が良いのでしょうか?

  • VBA:カウンターの i の値が開放されなくて困っています。

    以下のコードを実行する度に、カウンター i の値がリセット(開放)されずに積算されて困っています。なぜか教えて下さい。宜しくお願い致します。 以下のコードは、簡単に言えばcsvファイルをカウンター i で数えています。したがって、少なくともCSVファイルを一つ作成して実行して下さい。 Option Explicit Dim FiName As String, FoName As String Dim EachFiName As String Dim i As Integer Sub Test() MsgBox i '二回目にこのコードを実行するとiが積算されます。 FiName = Application.GetOpenFilename If FiName = "False" Then Exit Sub Else If Right(FiName, 3) <> "csv" Then MsgBox "Chose a CSV file." Exit Sub End If End If FoName = Left(FiName, InStrRev(FiName, "\", -1, vbTextCompare)) EachFiName = Dir(FoName & "*.csv") Do While EachFiName <> "" i = i + 1 EachFiName = Dir() Loop End Sub

  • 変数の宣言(s As String)で良い理由

    vbaについてしつもんです。 標準モジュールで Option Explicit Dim s As String Sub test1() Call test2("qqq") End Sub Sub test2(s As String) MsgBox s End Sub としたのですが、もしかしてDim s As Stringって必要ないのでしょうか? あってもなくても動きます。 (s As String)があるからDim s As Stringは不要なのですか? だとしたら、(s As String)に dim や publicをつけなくて良い理由を教えてください。

  • 「1から5の間なら」とするには?

    「1から5の間なら」とするには? エクセルvbaです。 Sub test1() Dim i As Integer i = 1 If i = 1 Or i = 2 Or i = 3 Or i = 4 Or i = 5 Then MsgBox "1-5までのどれかです" End If End Sub は、最大でも5なので手入力でできますが、 これが1から100までならor演算子で繋ぐのは大変なので Sub test2() Dim i As Integer i = 1 If i = [1-5] Then MsgBox "1-5までのどれかです" End If End Sub みたいなことをやりたいのですが、うまくいきません。 デバッグしてもエラーにもなりません。 自分でコードを書いといて聞くのもおかしいですがtest2の意味と、表題の方法を教えてください。 よろしくお願いします。

  • VBA 加算演算時のトラブル

    事務処理用に準備したVBA処理の数値合計チェックにて本来イコールとなるべきところ、ノットイコールと判定されてしまいます。当該部分を抜き出し、わかりやすくしたものが下記のロジックですが、ここで、test2,test4は結果がイコールとなるものの、test3の場合、ノットイコールとなってしまいます。どなたか、原因につき教えていただけませんか? Dim aaa As Double Dim bbb As Double sub test2() bbb = 16.67 + 16.67 aaa = 33.34 If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End Sub Sub test3() bbb = 16.67 + 16.67 + 16.67 aaa = 50.01 If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End Sub Sub test4() bbb = 16.67 + 16.67 + 16.67 + 16.67 aaa = 66.68 If bbb = aaa Then MsgBox "OK" Else MsgBox "NE" End If End sub

  • VBA 変数にアスタリスクが含んでるかどうか

    変数にアスタリスクが含んでるかどうかをIFステートメントで取得するには? Sub test() Dim mystr As String mystr = "*/" If mystr Like "*" Then MsgBox "mystrはアスタリスクを含んでます。" End If End Sub このようなことをしたい場合、 mystr = "*/" でも mystr = "/" でも、結局は*が、どの文字でも含まれると認識してしまいます。 変数にアスタリスクが含まれてるかどうかを判定する方法を教えてください。

  • グローバル変数などについて

    Option Explicit Dim str1 As String '・・・(1) Sub テスト() Dim str2 As String '・・・(2) str1 = "テスト1" str2 = "テスト2" MsgBox str1 MsgBox str2 End Sub (1)はグローバル変数と言うとの事ですが (2)は何変数と言うのでしょうか? ローカル変数ですか? また、(1)がdimではなく、 Public str1 As String となった場合でも、 プロシージャーの外にあれば、グローバル変数と言うのでしょうか?

  • 以下のVBAについて

    Option Compare Database Option Explicit Private Sub バックアップ開始_Click() Dim strBaseName As String Dim strFileName As String If IsNull(Me.バックアップ日付) = True Or Len(Me.バックアップ日付) = 0 Then MsgBox "バックアップ日付をyyyymmdd形式で入力してください。", vbOKOnly + vbCritical, "" Me.バックアップ日付.SetFocus Exit Sub End If strBaseName = "C:\Data\在庫管理.mdb" strFileName = "C:\Backup\" & Format(Me.日付, "yyyymmdd") & "StockData.mdb" If Dir(strFileName) <> "" Then If MsgBox(strFileName & Chr(13) & "は存在します。" & Chr(13) & _ "上書しますか?", vbYesNo + vbQuestion, "") = vbNo Then Exit Sub End If End If On Error GoTo LBL_ERROR FileCopy strBaseName, strFileName MsgBox "バックアップが完了しました。", vbInformation, "" LBL_EXIT: Exit Sub LBL_ERROR: Resume LBL_EXIT End Sub 上記のVBAでバックアップを行いたいのですが、フォルダ等も設定しているの実行されません。上記の文に間違いがあるのでしょうか? ソフトはAccessです。

  • 変数に特定の文字が含まれているなら(VBA)

    以前に質問した http://oshiete1.goo.ne.jp/qa4407128.html とは違うのですが 変数"あいうえお"に "あ"が含まれているなら "含まれています"と表示したいです。 Sub test() Dim strmoji As String strmoji = "あいうえお" If Find(strmoji) Like "*あ*" Then MsgBox "含まれています" End If End Sub 部分的に考えてみたのですが 「Sub、Function、または Property が定義されていません。(Error 35)」 が出てしまいます。 ご教授よろしくお願い致します。

  • 数値かどうかを取得したい IsNumberではダメ

    Sub Macro2() Dim mystr As String mystr = "1" If IsDate(mystr) = False Then MsgBox "NO" End If End Sub これなら日付型かどうかを取得できるのに、 Sub Macro1() Dim mystr As String mystr = "1" If IsNumber(mystr) = False Then MsgBox "NO" End If End Sub だと、IsNumberがコンパイルエラーになります。 変数に入っている値が数値として評価できるかを取得する方法を教えてください。

専門家に質問してみよう