IF mit AND und OR

Getting started ... Alles für einen gelungenen Start.
6 Beiträge • Seite 1 von 1
6 Beiträge Seite 1 von 1

IF mit AND und OR

Beitrag von Manfred K. (ForumUser / 49 / 0 / 0 ) »
Hallo zusammen,

ich habe Schwierigkeiten mit der if-Bedingung:

wie realisiere ich das?

Wenn eine Kostenstelle + Sachkonto oder eine Anlagenummer eingegeben werden

if ( kostl is initial and sachk is initial ) or anlnr is initial.
lv_fehler = 'x'.
endif.

Das Problem ist wenn Kostenstelle + Sachkonto gefüllt ist und Anlagennummer nicht gefüllt ist, springt er mir trotzdem in die Anweisung. -> lv_fehler = 'x'.

Danke schonmal.

gesponsert
Stellenangebote auf ABAPforum.com schalten
kostenfrei für Ausbildungsberufe und Werksstudenten


Re: IF mit AND und OR

Beitrag von wreichelt (Top Expert / 1069 / 32 / 193 ) »
Hallo,

ich bin kein Spezialist für OR AND und das mit Klammern. Aber probiere mal

IF ( kostl IS INITIAL AND sachk IS INITIAL ) OR ( anlnr IS INITIAL ).
lv_fehler = 'X'.
ENDIF.


Gruß Wolfgang

Re: IF mit AND und OR

Beitrag von PeterPaletti (Specialist / 367 / 33 / 102 ) »
Ich würde

Code: Alles auswählen.

IF ( kostl IS INITIAL OR sachk IS INITIAL ) AND ANLNR IS INITIAL. 
 lv_fehler = 'X'. 
ENDIF.
versuchen.

Wenn Kostenstelle + Sachkonto gefüllt sind, ist die 1. Teilbedingung unwahr und also die komplette Bedingung unwahr. -> lv_fehler <> 'X'

Wenn die Anlagennummer gefüllt ist, ist die 2. Teilbedingung unwahr, und also die komplette Bedingung unwahr. -> lv_fehler <> 'X'

Re: IF mit AND und OR

Beitrag von LeMinion (ForumUser / 22 / 1 / 7 ) »
Ist nicht mein Fachgebiet, wenn ich so Dinge wie "Sachkonto" und "Kostenstelle" lese, also könnte ich rein fachlich ev. nicht mitreden, und mir kommt Dein Satz "Wenn eine Kostenstelle + Sachkonto oder eine Anlagenummer eingegeben werden" unvollständig vor – weswegen ich nicht sicher bin, was die Bedingungen sind, von denen Du hier sprichst.
Daher erst mal meine Vermutung, daß alles in Ordnung ist, wenn entweder Sachkonto und Kostenstelle angegeben sind oder die Anlagennummer. Unter dieser Voraussetzung also das Folgende, wenn die also schon falsch ist, ist das sachlicher dahinter genauso falsch. 😉

Positiv formuliert würde die Bedingung also so aussehen, wenn man herausfinden möchte, ob alles in Ordnung ist, also kein Fehler vorliegt:

Code: Alles auswählen.

IF sachk IS NOT INITIAL AND kostl IS NOT INITIAL OR anlnr IS NOT INITIAL.
  error = abap_false.
ELSE.
  error = abap_true.
ENDIF.
Jetzt könntest Du eigentlich einfach sagen, wenn diese positive Bedingung nicht erfüllt ist, dann handelt es sich um einen Fehler, warum also nicht einfach:

Code: Alles auswählen.

IF NOT ( sachk IS NOT INITIAL AND kostl IS NOT INITIAL OR anlnr IS NOT INITIAL ).
  error = abap_true.
ENDIF.
Diese positive Formulierung läßt sich nicht so einfach umkehren ohne das NOT zu verwenden, denn für mich ist zum Beispiel nicht klar, ob es sich auch um einen Fehler handelt, wenn Du eine Anlagennummer und eins oder beide der anderen beiden Felder angegeben hast. Wenn es wirklich ein klassisches entweder-oder ist, dann hieße die positive Formulierung nämlich auch anders:

Code: Alles auswählen.

IF NOT ( 
  sachk IS NOT INITIAL AND kostl IS NOT INITIAL AND anlnr IS INITIAL 
  OR 
  sachk IS INITIAL AND kostl IS INITIAL AND anlnr IS NOT INITIAL 
).
  error = abap_true.
ENDIF.
Hier kommt es zum Fehler, wenn ein Mischfall vorliegt, also z.B. alle drei Felder ausgefüllt sind.

Generell emfpehle ich bei solchen Hirnzwiebeln aber, daß man die Bedingungen einzeln angibt, um auch später den Durchblick zu haben. Kommentare können das nicht immer so gut rüberbringen, vor allem, wenn sie vor einem Coding stehen, daß trotz Kommentar verworren wirkt. 😉

Code: Alles auswählen.

DATA(isAccountValid) = xsdbool( sachk IS NOT INITIAL AND kostl IS NOT INITIAL ).
DATA(isAssetNumberValid) = xsdbool( anlnr IS NOT INITIAL ).
Dann formuliert bzw. liest sich das ev. etwas besser, denn Du solltest nie vergessen, daß (Dein) Coding sehr viel häufiger gelesen als geschrieben wird, also lohnt es sich, sich eingehende Gedanken zur Lesbarkeit und Verständlichkeit des Codings zu machen, das ist, solange Du es nicht übertreibst, niemals Zeitverschwendung.

Code: Alles auswählen.

IF isAccountValid = abap_false AND isAssetNumberValid = abap_false.
  error = abap_true.
ENDIF.

Re: IF mit AND und OR

Beitrag von DeathAndPain (Top Expert / 1972 / 264 / 418 ) »
Ich teile LeMinions Auffassung, dass die Anforderung nicht klar ist, also nicht klar ist, was genau Du eigentlich möchtest. Das muss als erstes geklärt werden (auch für Dich selber).
Manfred K. hat geschrieben:Wenn eine Kostenstelle + Sachkonto oder eine Anlagenummer eingegeben werden
Wenn ich Dich richtig verstehe, willst Du demnach Folgendes:
  • Bedingung A: Kostenstelle + Sachkonto eingegeben -> alles in Ordnung. Es darf aber keins von beidem leer sein, also (bei Prüfung, ob die Bedingung nicht erfüllt ist) kostl is initial AND sachk is initial. Hier haben wir also schon den ersten Fehler in Deinem Coding (Du hast stattdessen OR geschrieben).
  • Bedingung B: Anlagennummer eingegeben -> auch alles in Ordnung. Dein anlnr is initial ist also korrekt.
  • Kostenstelle + Sachkonto nicht eingegeben und Anlagennummer auch nicht eingegeben (also A und B zusammen) --> Dann willst Du den Fehler haben. Also muss hier AND kommen. Du hast OR geschrieben. Das ist der zweite Fehler.
Aus Obigem würde sich Deine IF-Klausel in korrigiert wir folgt ergeben:

Code: Alles auswählen.

IF ( kostl IS INITIAL OR sachk IS INITIAL ) AND ANLNR IS INITIAL. 
 lv_fehler = 'X'. 
ENDIF.
An dieser Stelle ein Wort zur Klammerung (auch als Hinweis an wreichelt): Wie in vielen anderen Programmiersprachen ist es auch in ABAP so, dass AND enger bindet als OR (und NOT am allerengsten bindet). Deshalb braucht man Klammern bei AND und OR nur dann, wenn man explizit möchte, dass das OR zuerst ausgeführt wird (was in der Praxis tatsächlich der deutlich seltenere Fall ist, so dass dies auch Sinn ergibt). Diesen Umstand kann man sich zunutze machen und äußere ORs so schreiben: Jede OR-Bedingung in eine eigene Zeile mit OR gleichberechtigt unter IF, denn diese Bedingungen sind alle gleichberechtigt. So hat man jede der alternativen Möglichkeiten, die zur Erfüllung des IF-Statements führen, übersichtlich in einer eigenen Zeile. Innerhalb der einzelnen Bedingungen kann man dann schön seine ANDs schreiben. Da diese von Hause aus stets enger binden als OR, ist eine Klammerung unnötig, was die Lesbarkeit tatsächlich sogar erhöht (die Gliederung in einzelne Zeilen, obwohl technisch irrelevant, erfüllt optisch (kosmetisch) die Funktion der Klammerung). Ein Beispiel folgt sogleich.

Übrigens: Wenn man eine IF-Bedingung negieren möchte, gibt es eine einfache Regel: Man muss alle AND durch OR ersetzen und umgekehrt (ggf. Klammern ergänzen, damit die Bindungen sich nicht ändern) und alle auftretenden NOTs umdrehen (soll heißen: überall ein NOT davor, wo bisher keins steht und jedes NOT streichen, das bisher dagestanden hat). Das lässt sich mathematisch beweisen; habe ich einst an der Uni in "Theoretische Grundlagen der Informatik" gemacht. Wenn man obenstehende IF-Bedingung also so umdrehen wollte, dass sie genau dann auslöst, wenn kein Fehler vorliegt, dann müsste man schreiben:

Code: Alles auswählen.

IF NOT kostl IS INITIAL AND NOT sachk IS INITIAL
OR NOT ANLNR IS INITIAL. 
 lv_fehler = ' '. 
ENDIF.
ABAP erlaubt, das NOT schöner zu stellen und gleichbedeutend zu schreiben:

Code: Alles auswählen.

IF kostl IS NOT INITIAL AND sachk IS NOT INITIAL
OR ANLNR IS NOT INITIAL. 
 lv_fehler = ' '. 
ENDIF.
Inhaltlich ist beides aber gleichwertig und wird beides funktionieren, denn wie eingangs erwähnt bindet NOT am engsten, also noch enger als AND.

Nachdem all dies gesagt ist, sehe ich aber noch ein Problem. Es gibt nämlich noch einen weiteren möglichen Fall, der in diesem Thread noch gar nicht behandelt worden ist: Der Benutzer gibt sowohl Kostenstelle + Sachkonto als auch die Anlagennummer ein. Das ist insofern ein Problem, als die Möglichkeit besteht, dass die beiden Angaben einander widersprechen, also die Anlagennummer nicht zu Kostenstelle + Sachkonto passt. Tendenziell würde ich daher dazu neigen, diesen Fall auch als Fehler zu behandeln. Dann käme man (für den ursprünglichen IF) auf folgenden Ausdruck:

Code: Alles auswählen.

IF kostl IS NOT INITIAL AND sachk IS NOT INITIAL AND ANLNR IS NOT INITIAL.
 lv_fehler = 'X'. 
ENDIF.
Man könnte in diesem Fall aber vor dem Werfen einer Fehlermeldung noch prüfen, ob die eingegebenen Werte doch zusammenpassen (also Kostenstelle + Sachkonto und Anlagennummer auf dasselbe Ziel verweisen). In diesem Fall könnte man dieses Ziel verwenden und schweigend darüber hinweggehen, dass der Anwender mehr eingegeben hat als nötig.

Aber das ist noch nicht das letzte Problem, das ich sehe (das wäre zu einfach 😁 ). Was passiert, wenn der Anwender eine Kostenstelle oder Sachkonto eingegeben hat, aber nicht beides, und zusätzlich eine Anlagennummer? Also

Code: Alles auswählen.

IF NOT ( kostl IS INITIAL EQUIV sachk IS INITIAL ) AND ANLNR IS NOT INITIAL. 
  " Hier käme die Reaktion auf den soeben genannten Fall hin.
ENDIF.
Was wir hier brauchen, sieht man so gut wie nie in realem Code: Ein XOR, also ein OR, das falsch ist, wenn beide Bedingungen zutreffen. In ABAP lässt es sich über NOT EQUIV erreichen. (siehe hier)

Auch für diesen Fall sollte man eine Reaktion vorsehen. Mögliche Optionen:
  • "Dumme" Reaktion, aber leicht zu programmieren: Fehlermeldung, weil der Anwender Fragmente beider Angaben eingegeben hat, anstatt sich für eine der Möglichkeiten Kostenstelle + Sachkonto oder Anlagenummer zu entscheiden.
  • "Smarte" Reaktion, aufwendiger zu programmieren, aber benutzerfreundlicher: Prüfen, ob die Kostenstelle bzw. das Sachkonto, das angegeben wurde, zur gleichfalls angegebenen Anlagennummer passt und wenn ja, die Anlagennummer nutzen und schweigend darüber hinweggehen.

Folgende Benutzer bedankten sich beim Autor DeathAndPain für den Beitrag (Insgesamt 2):
rob_abcwreichelt


Re: IF mit AND und OR

Beitrag von GastX (Specialist / 284 / 4 / 19 ) »
Ergänzung zu DeathAndPain (dessen Ausführungen finde ich topp): die Logikregeln findet man unter "De Morgansche Regeln", falls es wen interessiert.

Seite 1 von 1

Aktuelle Forenbeiträge

IF mit AND und OR
vor 8 Stunden von GastX 6 / 1046
Meine Inbox
vor 13 Stunden von Rabea1103 1 / 125
PCL2 Cluster auslesen
vor 2 Tagen von DeathAndPain 2 / 1037
FUBA 'HR_INFOTYPES_OPERATION'
vor 2 Tagen von Bright4.5 3 / 5964

Newsletter Anmeldung

Keine Beiträge verpassen! Wöchentlich versenden wir lesenwerte Beiträge aus unserer Community.
Die letzte Ausgabe findest du hier.
Details zum Versandverfahren und zu Ihren Widerrufsmöglichkeiten findest du in unserer Datenschutzerklärung.

Aktuelle Forenbeiträge

IF mit AND und OR
vor 8 Stunden von GastX 6 / 1046
Meine Inbox
vor 13 Stunden von Rabea1103 1 / 125
PCL2 Cluster auslesen
vor 2 Tagen von DeathAndPain 2 / 1037
FUBA 'HR_INFOTYPES_OPERATION'
vor 2 Tagen von Bright4.5 3 / 5964