Почему здесь «И» работает, а «ИЛИ» нет? - PullRequest
1 голос
/ 09 мая 2019

В моей ситуации использование ИЛИ не работает, я должен использовать И, и я не уверен, почему.

Sub blah()
    If LCase(Environ("username")) <> "me" Or LCase(Environ("username")) <> "some other user" Then '''DOESN'T WORK
        Stop
    ElseIf LCase(Environ("username")) <> "me" And LCase(Environ("username")) <> "some other user" Then  '''WORKS
        Stop
    End If
End Sub

Ответы [ 4 ]

7 голосов
/ 09 мая 2019

Ваш пример сложен для понимания, но вы, вероятно, просто смущены характером операторов.

Подумайте о таблицах истинности; результат операции Or равен True, если хотя бы один из операндов равен True:

True Or True   => True
True Or False  => True
False Or True  => True
False Or False => False

Аналогично, результат операции And равен True, если оба операнда равны True:

True And True   => True
True And False  => False
False And True  => False
False And False => False

Если это помогает, вы можете визуализировать Or как + (сложение) и And как * (умножение), где False означает 0 и True означает "не ноль ":

1 Or 1 => 1 + 1 => True
1 Or 0 => 1 + 0 => True
0 Or 1 => 0 + 1 => True
0 Or 0 => 0 + 0 => False

1 And 1 => 1 * 1 => True
1 And 0 => 1 * 0 => False
0 And 1 => 0 * 1 => False
0 And 0 => 0 * 0 => False
0 голосов
/ 10 мая 2019

Это можно объяснить с помощью законов Деморгана . Если мы возьмем:

If LCase(Environ("username")) <> "me" Or LCase(Environ("username")) <> "some other user" Then

тогда мы можем переписать это, заменив <> на =, а затем отрицая каждый член на Not:

If Not(LCase(Environ("username")) = "me") Or Not(LCase(Environ("username")) = "some other user") Then

Используя законы Деморгана, мы можем применить единое отрицание ко всему выражению, если поменяем оператор Or на оператор And:

If Not(LCase(Environ("username")) = "me" And LCase(Environ("username")) = "some other user") Then

Невозможно, чтобы LCase(Environ("username") одновременно равнялся двум различным значениям, и поэтому условие And будет ложным. Применение оператора Not означает, что все выражение всегда будет иметь значение True независимо от значения «username»


Для исправленной версии, использующей And вместо Or, следующие шаги:

If LCase(Environ("username")) <> "me" And LCase(Environ("username")) <> "some other user" Then

Измените <> на = и примените Not операторов:

If Not(LCase(Environ("username")) = "me") And Not(LCase(Environ("username")) = "some other user") Then

Применить законы Деморгана:

If Not(LCase(Environ("username")) = "me" Or LCase(Environ("username")) = "some other user") Then

Теперь, если имя пользователя - "я" или имя пользователя - "какой-то другой пользователь", тогда условие Or будет иметь значение True, а оператор Not изменит его на False, как требуется.

Если в качестве имени пользователя используется любое другое значение, тогда условие Or будет иметь значение False, а оператор Not изменит его на True, как требуется

0 голосов
/ 09 мая 2019

Давайте разберемся.Я должен предположить, что "me" это ваше собственное имя пользователя.Результат этого теста: False, True, True

Debug.Print LCase(Environ("username")) <> "me"
Debug.Print LCase(Environ("username")) <> "some other user"
Debug.Print LCase(Environ("username")) <> "me" Or LCase(Environ("username")) <> "some other user"

Это ожидаемое поведение для меня.

0 голосов
/ 09 мая 2019

VBA Or не работает, потому что когда Environ("username") равно me , это не какой-то другой пользователь и наоборот.

Вы хотите убедиться, что это не одна из возможностей, поэтому вам нужно And.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...