Autor Thema: Verschachtelte @If-Abfragen  (Gelesen 4810 mal)

Offline buzi

  • Aktives Mitglied
  • ***
  • Beiträge: 171
Verschachtelte @If-Abfragen
« am: 30.09.15 - 11:30:40 »
Hallo zusammen,

ich habe eine Frage wie man verschachtelte If-Abfragen in Formelsprache am besten formuliert. Es geht darum, dass ein Preis in Abhängigkeit der Mitgliedschaft (ja/nein) und der ausgewählten Kategorie berechnet wird. Zunächst wird anhand des Namens das Kunden-Dokument gefunden, um herauszufinden ob er Mitglied ist oder nicht (das funktioniert nach meinen Tests). Aber die If-Fragen laufen immer bis zum Ende durch also am Schluß steht "n.b.8" im Preis-Feld.

Die Formel meines Preis-Felds sieht bislang so aus:

key := @If(iTeFirma="";iTeNachname + " " + iTeVorname;iTeFirma +" "+ iTeNachname +" " + iTeVorname);
values := @DbLookup ( "":"Nocache"; "":""; "vwKunden "; key; "iTeMitgliedVon" );
isMitglied := @IsMember("Verband B"; values);

@If(iTeKategorie!="" & @Contains(iTeKategorie;"1.") & isMitglied ; "10 € / 1. Jahr"; "n.b.1");
@If(iTeKategorie!="" & @Contains(iTeKategorie;"1.") & !isMitglied ; "20 € / 1. Jahr"; "n.b.2");

@If(iTeKategorie!="" & @Contains(iTeKategorie;"2.") & isMitglied ; "20 € / 1. Jahr"; "n.b.3");
@If(iTeKategorie!="" & @Contains(iTeKategorie;"2.") & !isMitglied ; "30 € / 1. Jahr"; "n.b.4");

@If(iTeKategorie!="" & @Contains(iTeKategorie;"3.") & isMitglied ; "40 € / 1. Jahr"; "n.b.5");
@If(iTeKategorie!="" & @Contains(iTeKategorie;"3.") & !isMitglied ; "50 € / 1. Jahr"; "n.b.6");

@If(iTeKategorie!="" & @Contains(iTeKategorie;"4.") & isMitglied ; "60 € / 1. Jahr"; "n.b.7");
@If(iTeKategorie!="" & @Contains(iTeKategorie;"4.") & !isMitglied ; "70 € / 1. Jahr"; "n.b.8");

Hinweis: Wenn ich nur die erste If-Zeile stehen lasse, und im Kategorie-Feld "1." auswähle, klappt es - dann steht "10 € / Jahr" im Preis-Feld. Aber sobald die anderen IF-Zeilen dazu kommen geht es schief.

Kann man das in Formelsprache überhaupt elegant lösen oder braucht man Lotus Script dafür?

Offline tks

  • Senior Mitglied
  • ****
  • Beiträge: 425
  • Geschlecht: Männlich
  • ...für'n Fuss
Re: Verschachtelte @If-Abfragen
« Antwort #1 am: 30.09.15 - 11:41:51 »
Auszug aus der Designer-Hilfe:

@If( condition1 ; action1 ; condition2 ; action2 ; ... ; condition99 ; action99 ; else_action )

Also nicht für jede Bedinung ein @If, sonder alles in eines.
Thomas

*********************************
Domino 8.5.3FP6 unter W2K12
Notes 8.5.3 unter Win7
sequrIQ (watchdog & crypt)
*********************************

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Verschachtelte @If-Abfragen
« Antwort #2 am: 30.09.15 - 12:35:03 »
Ich würde das ganze erst einmal etwas entzerren und ggf. @Return verwenden.

Annahme: Du gibst kein Ergebnis, wenn iTeKategorie leer ist

@If (iTeKategorie = ""; @Return (""); "");

Dann hast Du Kategorien, von denen Du nur den Zahlenwert zur Berechnung verwenden willst. Den würde ich mir einmalig in eine Variable rechnen

_k := @If (@Contains (iTeKategorie; "1."); "1" ; @Contains (iTeKategorie; "2."); "2"; @Contains (iTeKategorie; "3."); "3"; @Contains (iTeKategorie; "3."); "3"; @Contains (iTeKategorie; "4."); "4"; "");

Möglicherweise beginnt die Kategorie mit der Zahl, dann wäre es einfacher so

_k := @Left (iTeKategorie; 1)

oder

_k := @Left (iTeKategorie; ".")

Für die Mitgliedschaft würde ich mir auch noch einen Wert ermitteln

_m := @If (isMitglied; "1"; "0");

Danach kannst Du diese Werte zusammenfassen und damit wesentlich einfacher rechnen

_km := _k + _m;

@If (_km = "11"; "10 €"; _km = "10"; "20 €"; ...


da Nichtmitglieder anscheinend immer 10 € mehr bezahlen, ließe sich das auch noch anders in die Formel einbauen, indem am Ende nur einmalig die 10 € aufgeschlagen werden, falls kein Mitglied.

Die "schöne" Formulierung solcher Mehrfachbedingung ist prinzipiell nicht von der Sprache abhängig, auch in Script kann man das krautig schreiben.



Offline thkn777

  • Aktives Mitglied
  • ***
  • Beiträge: 176
Re: Verschachtelte @If-Abfragen
« Antwort #3 am: 01.10.15 - 13:20:28 »
Mi­ni­mal­in­va­siv an Deinem ursprünglichen Code geändert:

Code
x := @If(iTeKategorie!="" & @Contains(iTeKategorie;"1.") & isMitglied ; "10 € / 1. Jahr"; "n.b.");
x := @If(x="n.b." & iTeKategorie!="" & @Contains(iTeKategorie;"1.") & !isMitglied ; "20 € / 1. Jahr"; x);
x := @If(x="n.b." & iTeKategorie!="" & @Contains(iTeKategorie;"2.") & isMitglied ; "20 € / 1. Jahr"; x);
...
x := @If(x="n.b." & iTeKategorie!="" & @Contains(iTeKategorie;"4.") & !isMitglied ; "70 € / 1. Jahr"; x);
x

Das ist zwar nicht "verschachtelt" in dem Sinne, geht die Möglichkeiten aber - so wie von Dir geplant - der Reihe nach durch. Die einzelnen Abfragen schleppen "n.b." als (Zwischen-)Wert für x solange mit, bis ein Wert ermittelt werden kann. Oder bis zum bitteren Ende.

Ansonsten das, was tks vorschlug: einfach so machen, wie in der Designer-Hilfe steht, ich finde das jetzt nicht wirklich schlimm:

Code
@If(
	iTeKategorie!="" & @Contains(iTeKategorie;"1.") & isMitglied ; "10 € / 1. Jahr"; 
	iTeKategorie!="" & @Contains(iTeKategorie;"1.") & !isMitglied ; "20 € / 1. Jahr";
	iTeKategorie!="" & @Contains(iTeKategorie;"2.") & isMitglied ; "20 € / 1. Jahr";
	...
	iTeKategorie!="" & @Contains(iTeKategorie;"4.") & !isMitglied ; "70 € / 1. Jahr";
	"n.b."
);

Was genau Du unter elegant verstehst, weiß ich nicht. Gute Planung und ein sinnvolles Vorgehen beim Prüfen und Ermitteln derartiger Werte ist aber eine gute Idee und kommt nicht nur der Lesbarkeit des Codes sondern auch der Performance zugute. Ideen dazu hat ja schon Peter geäußert.

Ich wünsche viel Erfolg.

Offline Bastel123

  • Senior Mitglied
  • ****
  • Beiträge: 355
  • Geschlecht: Männlich
Re: Verschachtelte @If-Abfragen
« Antwort #4 am: 01.10.15 - 13:34:14 »
Noch ein Hinweis:

X:= @If(iTeKategorie!="" & @Contains(iTeKategorie;"1.") & isMitglied ; "10 € / 1. Jahr"; "n.b.1");
X:= @If(iTeKategorie!="" & @Contains(iTeKategorie;"1.") & !isMitglied ; "20 € / 1. Jahr"; "n.b.2");
etc.

geht durch alle @IF-Formeln, d.h ich kann den Wert auch "überschreiben", der letzte hat gewonnen.

X:= @If(
      iTeKategorie!="" & @Contains(iTeKategorie;"1.") & isMitglied ; "10 € / 1. Jahr"; "n.b.1";
      iTeKategorie!="" & @Contains(iTeKategorie;"1.") & !isMitglied ; "20 € / 1. Jahr"; "n.b.2");
      "n.b.?"
      )

bricht nach der ersten gültigen Formel ab, d. h. der erste gewinnt.

Da stolpert man schon mal drüber  >:(

Sebastian
Gruß Sebastian
-----------------------------------------------------
Kaum macht man's richtig, schon funktioniert's.

Offline thkn777

  • Aktives Mitglied
  • ***
  • Beiträge: 176
Re: Verschachtelte @If-Abfragen
« Antwort #5 am: 01.10.15 - 14:55:21 »
Noch ein Hinweis:

X:= @If(iTeKategorie!="" & @Contains(iTeKategorie;"1.") & isMitglied ; "10 € / 1. Jahr"; "n.b.1");
X:= @If(iTeKategorie!="" & @Contains(iTeKategorie;"1.") & !isMitglied ; "20 € / 1. Jahr"; "n.b.2");
etc.

geht durch alle @IF-Formeln, d.h ich kann den Wert auch "überschreiben", der letzte hat gewonnen.

Stimmt. Genau DAS ist ja das ursprüngliche Problem von buzi, das man durch das einfache Voranstellen von "X:=" in jeder Zeile auch nicht lösen kann.

Zitat
X:= @If(
      iTeKategorie!="" & @Contains(iTeKategorie;"1.") & isMitglied ; "10 € / 1. Jahr"; "n.b.1";
      iTeKategorie!="" & @Contains(iTeKategorie;"1.") & !isMitglied ; "20 € / 1. Jahr"; "n.b.2");
      "n.b.?"
      )

bricht nach der ersten gültigen Formel ab, d. h. der erste gewinnt.
Da stolpert man schon mal drüber  >:(
Sebastian

Ich kann mir nicht vorstellen, wie diese Formel überhaupt sinnvoll funktionieren soll.

Zusammenfassung:  ???

Offline Andrew Harder

  • Senior Mitglied
  • ****
  • Beiträge: 295
  • Geschlecht: Männlich
Re: Verschachtelte @If-Abfragen
« Antwort #6 am: 01.10.15 - 16:02:36 »
Man kann auch einfach doppelte Abfragen vermeiden, das spart Platz und ist damit lesbarer.

Also so etwa in der Art:
Code
@If (iTeKategorie = ""; @Return (""); "");
	
@If(isMitglied = @True;
	@If(
		@Contains(iTeKategorie;"1."); "10 € / 1. Jahr";
		@Contains(iTeKategorie;"2."); "20 € / 1. Jahr";
		@Contains(iTeKategorie;"3."); "40 € / 1. Jahr";
		@Contains(iTeKategorie;"4."); "60 € / 1. Jahr";
		"value for member not found")
	;
	@If(
		@Contains(iTeKategorie;"1."); "20 € / 1. Jahr";
		@Contains(iTeKategorie;"2."); "30 € / 1. Jahr";
		@Contains(iTeKategorie;"3."); "50 € / 1. Jahr";
		@Contains(iTeKategorie;"4."); "70 € / 1. Jahr";
		"value for non-member not found")
)





Andy

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.885
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Verschachtelte @If-Abfragen
« Antwort #7 am: 01.10.15 - 17:58:22 »
also ich persönlich würde ja mit Zahlen arbeiten und dann den Text ganz am Ende ergänzen. Wenn die Logik so ist, wie sie sich darstellt, dann wäre mein Code:
Code
_isMitglied := @IsMember("Verband B"; values);

REM "Abbrechen, wenn Kategorie leer";
@If( iTeKategorie = "" ; @Return( "" ) ; "" );
_nr := @TextToNumber( @Left( iTeKategorie ; "." ) );

REM "Abbrechen, wenn die am Anfang der Kategorie keine Zahl steht";
@If( @IsError( _nr ) ; @Return( "" ) ; "" );

REM "Rechnung: Kategorie * 10 + 10 € für Nichtmitglieder";
_amount := _nr * 10 + @If( _isMitglied ; 0 ; 10 );

REM "Text zurückgeben";
@Text( _amount ) + " € / 1. Jahr"


So ganz nebenbei würde ich den Betrag komplett als Zahl in einem eigenen Feld speichern, und den Text dann einfach auf das Feld beziehen... wer weiß, wann man den Betrag mal irgendwo braucht (Fiktive Anforderung: "Kannst Du uns zeigen, wie viel Euro das insgesamt sind?" )
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Verschachtelte @If-Abfragen
« Antwort #8 am: 02.10.15 - 09:07:36 »
Hallo Torsten,

das passt fast, nur ist die Beziehung zwischen Kategorienummer und Betrag nicht so linear. Mit einer kleinen Ergänzung geht das aber. Und um pingelig zu sein, könnte man die ersten beiden Zeilen weglassen, da _nr auch bei leerer Kategorie keine Zahl wird

_isMitglied := @IsMember("Verband B"; values);

REM "Abbrechen, wenn Kategorie leer";
@If( iTeKategorie = "" ; @Return( "" ) ; "" );
_nr := @TextToNumber( @Left( iTeKategorie ; "." ) );

REM "Abbrechen, wenn am Anfang der Kategorie keine Zahl steht";
@If( @IsError( _nr ) ; @Return( "" ) ; "" );

REM "Preis der Kategorie";
_preis := @Select (_nr; 10; 20; 40; 60; -1);
@If (_preis < 0; @Return (""); "");


REM "Rechnung: _preis + 10 € für Nichtmitglieder";
_amount := _preis + @If( _isMitglied ; 0 ; 10 );

REM "Text zurückgeben";
@Text( _amount ) + " € / 1. Jahr"

« Letzte Änderung: 02.10.15 - 09:09:35 von Peter Klett »

Offline buzi

  • Aktives Mitglied
  • ***
  • Beiträge: 171
Re: Verschachtelte @If-Abfragen
« Antwort #9 am: 07.10.15 - 12:17:33 »
Hallo zusammen,

danke für die zahlreichen Ideen und Hilfestellungen. Die Lösung von Torsten optimiert von Peter finde ich am "elegantesten"! Mit elegant meinte ich wenig Zeilen, keine redundante Formulierung und wenig Fehleranfälligkeit. Allerdings funktioniert bei mir die Funktion @TextToNumber nicht, sie gibt immer leer zurück. Wenn ich debugge, kann die iTeKategorie = "1. XXXX" sein, @Left macht's noch richtig, bringt die 1 zurück, aber @TextToNumber bringt "" zurück. Wen ich die Beschreibung von @TextToNumber richtig verstehe, müsste es in dem Fall ja sogar ohne @Left gehen aber das tut auch nicht...
« Letzte Änderung: 07.10.15 - 12:19:46 von buzi »

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Verschachtelte @If-Abfragen
« Antwort #10 am: 07.10.15 - 12:38:34 »
Also dieser Testagent funktioniert (mit Berechnung, um zu sehen, dass es wirklich als Zahl interpretiert wird

_kat := "2. XXX";
_nr := @TextToNumber (@Left (_kat; "."));
@Prompt ([Ok]; ""; @Text (_nr * 10));

Sind alle Klammern korrekt gesetzt?

Evtl. noch ein @Text mit einfügen, um sicherzustellen, dass in der Kategorie auch wirklich Text steht (wüsste aber nicht, was es sonst sein sollte)

_nr := @TextToNumber (@Text (@Left (iTeKategorie; ".")));

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.885
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Verschachtelte @If-Abfragen
« Antwort #11 am: 07.10.15 - 13:25:32 »
ACHTUNG: Hast Du wirklich "@TextToNumber" verwendet, oder die ähnlich klingende Funktion "@ToNumber" ? Bei @ToNumber hatte ich auch schon solche Phänomene...
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline buzi

  • Aktives Mitglied
  • ***
  • Beiträge: 171
Re: Verschachtelte @If-Abfragen
« Antwort #12 am: 08.10.15 - 11:36:51 »
Also nach nochmal vielen Versuchen habe ich eine Lösung gefunden die funktioniert. Und zwar indem ich die @Left und @TextToNumber Aufrufe nicht verschachtle sondern jeweils in einer Variablen zuweise und dann weiter verwende. DANKE an alle Helfer!!!

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz