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.