Microsoft Excel

Herbers Excel/VBA-Archiv

OR-Zweig wird unnötig durchlaufen


Betrifft: OR-Zweig wird unnötig durchlaufen
von: Burkhard
Geschrieben am: 12.12.2018 10:16:06

Hallo miteinander,

ich habe hier eine ziemlich simple if-Abfrage und wundere mich, dass Excel den OR-Zweig durchläuft (und damit die Funktion getType), obwohl die erste Bedingung erfüllt ist (und eine weitere Prüfung damit überflüssig).

If arUsedNames(i, 0) <> "Name" Or (arUsedNames(i, 0) = "Name" And getType() = "XYZ") Then

Ist das Excel-(oder VBA-)Standard? Dann wäre es kein guter ...

  

Betrifft: Häaa. Was wäre denn ein guter Standard? (owT)
von: EtoPHG
Geschrieben am: 12.12.2018 10:32:23




  

Betrifft: AW: OR-Zweig wird unnötig durchlaufen
von: Torsten
Geschrieben am: 12.12.2018 10:32:27

Hallo,

das OR muss in Klammern, wenn mit AND verbunden:

If (arUsedNames(i, 0) <> "Name" Or (arUsedNames(i, 0) = "Name" And getType() = "XYZ" Then



  

Betrifft: AW: OR-Zweig wird unnötig durchlaufen
von: PeterK
Geschrieben am: 12.12.2018 10:39:57

Hallo

Um den zweiten Teil des Ausdrucks nicht auszuwerten verwende "orElse" (analog dazu "andAlso")


  

Betrifft: Irrtum
von: PeterK
Geschrieben am: 12.12.2018 11:49:31

Hallo

Hab mich leider geirrt! "OrElse" ist ein VB Operator und NICHT in VBA verfügbar


  

Betrifft: AW: OR-Zweig wird unnötig durchlaufen
von: Daniel
Geschrieben am: 12.12.2018 11:04:51

HI
naja, ist halt so, dass in VBA boolsche Ausdrücke immer vollständig berechnet werden.
Ansonsten müsste VBA ja zuerst einmal den Ausdruck analysieren um zu ermitteln, bei welchen ersten Teilergebnissen auf die Berechnung weiterer Teilergebnisse verzichtet werden kann.
Aber das ist wahrscheinlich aufwendiger, als gleich den ganzen Ausdruck zu berechnen.

wenn du vermeiden willst, dass getType berechnet wird, wenn die erste Bedingung erfüllt ist, dann musst du hierzu die Bedingungsprüfung in mehrere Teilprüfungen aufteilen:

If arUsedNames(i, 0) <> "Name" Then
    hier der Code
ElseIf getType() = "XYZ" Then
    hier der Code
End if
den Code der Ausgeführt werden soll, müsstest du dann aber wiederholen.
um diese Wiederholung von Quelltext zu vermeiden, könntst du:
den Code in ein Untermakro auslagern, welches dann nur aufgerufen werden muss,

oder mit einer zwsichenvariable arbeiten:
Dim Check as boolean

If arUsedNames(i, 0) <> "Name" Then
    Check = true
ElseIf getType() = "XYZ" Then
    Check = true
else
    Check = False
End if

If Check Then
    hier dein Code
end if
Gruß Daniel


  

Betrifft: VBA kann keine Short Circuit Evaluation
von: Zwenn
Geschrieben am: 12.12.2018 11:17:57

Hallo Burkhard,

es gibt Programmiersprachen, die können eine logische Auswertung auf Wunsch abbrechen, wenn das Ergebnis (scheinbar) feststeht. Das bedeutet für den Oder-Operator, sobald eine Bedingung erfüllt ist, ist das Ergebnis des Gesamtausdrucks wahr. Dieses Vorgehen nennt sich Short Circuit Evaluation. VBA beherrscht dieses Vorehen jedoch nicht. Der folgende Link verweist auf einen Foren Thread aus Oktober 2016. Ich habe es jetzt zwar nicht geprüft, kann mir aber nicht vostellen, dass eine so grundlegende Sache inzwischen geändert wurde:
http://social.msdn.microsoft.com/Forums/office/en-US/80bda3d6-7577-4570-8e28-0c62d44fd2cf/does-vba-support-shortcircuit-operators?forum=accessdev

Deshalb werden alle Teilausdrücke ausgewertet und wenn einer davon "nicht funktioniert", kann es zu einem Verhalten kommen, dass man so nicht erwartet hat.

Viele Grüße,

Zwenn


  

Betrifft: AW: VBA kann keine Short Circuit Evaluation
von: Burkhard
Geschrieben am: 12.12.2018 12:03:54

vielen Dank für eure zahlreichen Beiträge!

@ EtoPHG
Ein "guter" Standard wäre, nach der erfolgreichen Auswertung des ersten Ausdrucks den Rest der Zeile zu ignorieren und sofort in den if-Zweig zu gehen; der OR-Zweig kann ja am Ergebnis nichts mehr ändern. So ist das, wie Zwenn anmerkt, in anderen Programmiersprachen (z.B. in C und C++) durchaus üblich, nicht aber in VBA.
@Torsten
Hier fehlt doch irgendwie etwas, klammermäßig? Aber selbst wenn ich die erste Bedingung in Klammern schreibe

If (arUsedNames(i, 0) <> "Name") Or (arUsedNames(i, 0) = "Name" And getType() = "XYZ") Then
ändert sich nichts - der Or-Zweig wird durchlaufen. VBA kann das einfach nicht anders.
@PeterK
Bei OrElse oder Or Else bekomme ich einen Syntaxfehler
@Daniel
OK, ist halt so. Aber nicht zwingend und quasi als Naturgesetz - C und C++ machen das vor.
So bzw. so ähnlich habe ich das inzwischen auch gelöst.
@Zwenn
"VBA beherrscht dieses Vorgehen jedoch nicht." Schade. Aber: again what learned!

Grüße
Burkhard


  

Betrifft: C++ üblich? Nein muss forciert werden! (owT)
von: EtoPHG
Geschrieben am: 12.12.2018 13:42:32




  

Betrifft: In C++ unterstützt! (owT)
von: Sulprobil
Geschrieben am: 14.12.2018 03:12:05

https://stackoverflow.com/questions/5211961/how-does-c-handle-short-circuit-evaluation


  

Betrifft: Die Klammerung des 1.Ausdrucks ist ohnehin ...
von: Luc:-?
Geschrieben am: 12.12.2018 16:06:19

…überflüssig, Burkhard,
nur die des And-Verbunds nicht, weil sonst nicht klar ist, ob wie gezeigt oder eher wie folgt gerechnet wdn soll:
If (arUsedNames(i, 0) <> "Name" Or arUsedNames(i, 0) = "Name") And getType() = "XYZ" Then
Gruß, Luc :-?

„Die Intelligenzmenge ist auf diesem Planeten eine Konstante, die Bevölkerung nimmt aber zu!“ Auch deshalb informieren mit …


  

Betrifft: AW: OR-Zweig wird unnötig durchlaufen
von: Sulprobil
Geschrieben am: 14.12.2018 03:19:57

Hallo Burkhard,
Das ist leider so.
Muss schon so etwas wie
If ... Then
...
ElseIf ... Then
...
End If
als "short circuit" für Or programmieren.
Viele Grüße,
Bernd P