Das Notes Forum
Domino 9 und frühere Versionen => ND7: Entwicklung => Thema gestartet von: Marie am 15.10.10 - 21:52:51
-
Hallo Leute,
ich habe eine Ansicht mit 5 Spalten. In einer Maske lese ich in 5 verschiedenen Feldern die Summen mit folgender Formel jeweils aus:
@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";4))
Jetzt möchte ich in einem weiteren Feld eine durchschnittsergebnis mit diesen werten berechnen.
Kann mir jemand helfen, da die felder sich irgendwie nicht berechnen lassen...
Vielen Dank schonmal
-
Meinst Du den Durchschnitt der 5 Summen?
FIELD Summe1 := @Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";1));
FIELD Summe2 := @Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";2));
FIELD Summe3 := @Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";3));
FIELD Summe4 := @Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";4));
FIELD Summe5 := @Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";5));
(Summe1 + Summe2 + Summe3 + Summe4 + Summe5) / 5
Die ersten 5 Zeilen kannst Du weglassen, wenn die schon in den Feldformeln enthalten sind.
-
Peter, meinst Du wirklich, dass jemand mit Notes-Programmierung beauftragt ist, der nicht mal in der Lage, das arithmetische Mittel zu berechnen. Ich weigere mich, das zu glauben.
Wenn ich allerdings
... sich irgendwie nicht berechnen lassen ...
lese (was ich schon einmal als vollkommen ungeeignet für Fragen in Foren angemahnt habe), dann ahne ich schlimmes.
Aber vielleicht geht es ja doch um mehr? Den Median, das geometrische Mittel oder das harmonische? Oder das quadratische Mittel?
Aber das kann nur Marie klären.
Peter, an Deinem Konstrukt noch eine Kritik im Sinne aller, die diesen Thread vielleicht irgendwann einmal entdecken: Es fehlt die Prüfung, ob die Bildung von Summe1 .. Summe5 überhaupt eine Zahl ergeben (kann ja auch in die Hose gehen, nicht wahr?). Der gute Programmierer schaut auch in einer Einbahnstrasse nach links *und* nach rechts, daher muss er hier auf @IsNumber prüfen. Gerade Anfängern sollte das helfen, bevor sie irgendwann einmal böse auf die Nase fallen.
@Marie: Stelle bitte durchdachte Fragen. Die korrekte Antwort auf Deine Frage
In einer Maske lese ich in 5 verschiedenen Feldern die Summen mit folgender Formel jeweils aus:
@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";4))
lautet:
@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";4))
Es ist nicht einzusehen, dass freiwillige Helfer wie Peter und viele andere (ich schliesse mich da ein!) erst lange nachdenken müssen, um Dein Problem bzw. das Deines Arbeitgebers zu ergründen.
Bernhard
PS: Und kommt nicht wieder mit sowas wie
... Einige in diesem Forum reden ja immer nur und scheinen sich als Edle Ritter zu verstehen, die die Welt der Foren "säubern" wollen...
Wir wollen helfen, aber dazu braucht es auch jeweils den Gegenpart.
-
@Bernhard
Ich gebe Dir völlig Recht mit der Fehlerprüfung. In Forumeinträgen lasse ich die i.d.R. weg, damit die nicht von dem wesentlichen Inhalt ablenken. Eigentlich setze ich voraus, dass das dann jeder selber hinzufügt (ist vielleicht eine falsche Annahme).
Normalerweise mache ich das so:
_tmp := @MeineFormel;
@If (@IsError (_tmp); Alternativwert; _tmp)
@Marie
Falls Du den Durchschnitt der Spaltenwerte pro Dokument errechnen willst, solltest Du eine sechste Spalte einfügen, Wert 1. @Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";6)) ist dann die Anzahl Dokumente, damit müsstest Du dann alles ausrechnen können.
Aus Performancegründen würde ich diese Formel aber nicht in jedes Feld schreiben (sonst holst Du Dir fünf mal die Anzahl der Dokumente), sondern die Felder als berechnet beim Anlegen einstellen und nur eines der Felder berechnen und darin alle anderen Felder wie in meinem ersten Post setzen.
Ach ja, und das mit den edlen Rittern war wirklich nicht in Ordnung ...
-
Hallo Peter,
vielen Dank schonmal für deine Antwort.
Also ich erkläre es die Sache nochmal anders, da ich schon etwas weiter gekommen bin.
Ich habe eine Spalte: Auftragssumme,
eine mit den gesamten Kosten
und eine mit den gesamten Stückzahlen
und eine mit den Listenpreisen.
Ich möchte jetzt im header der Datenbank eine eingefügte Maske haben, in den der Durchschnittspreis, die gesamt verkauften Anlagen, der durchschnittliche Rabatt und der durchschnittliche Deckungsbeitrag (C1) berechnet und angezeigt wird.
Durchschnittspreis ist klar: gesamt Summe / gesamt Stückzahl
Die gesamten verkauften Anlagen sind die Summen aus den Spalten 7 bis 12.
Diese errechnet ich mit folgender Formel:
_temp :=(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";7)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";8)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";9)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";10))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";11)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";12)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";13))));
@If (@IsError (_tmp); Alternativwert; _tmp);
Wenn ich jetzt einen neuen Auftrag anlege, dann zeigt das Feld, wenn ich Deine Fehlerüberprüfung mit in der Formel habe nichts an, und wenn ich diese rausnehme, dann bekomme ich eine Fehlermeldung:
Feld "Value_1" Die datentypen der zwei Vergleichsergebnisse sind nicht kompatibel.
Das gleiche passiert auch mit den Feldern, in denen ich den Durchschnittspreis, den C1 und den Rabatt berechne!
Ich bin sicher für Euch ist das Problem wahrscheinlich lächerlich, aber ich bin kein Experte und bastel mir hier nur meine Eigene Datenbank zusammen, wobei ich doch öfters an meine Grenzen stoße.
Dennoch möchte ich diese Problem auch lösen...
Vielen Dank schonmal...
-
Von welchem Typ sind denn die Felder, die Du in den Spalten anzeigst?
Wie lautet die komplette Formel im Feld "Value_1"?
Bernhard
-
Noch was: In Deiner Formel steht
temp :=
Unten kommt aber
@If (@IsError (_tmp); Alternativwert; _tmp);
Das würde natürlich gar nicht zusammen passen.
Bernhard
-
mit Temp / Tmp hatte ich mich nur verschrieben.
Die Spalten und auch die Felder sind alle vom Typ Zahl.
Die gesamte Formel im Feld lautet:
_temp :=(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";7)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";8)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";9)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";10))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";11)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";12)))+(@Sum(@DbColumn("" : "NoCache"; ""; "auftragsdetails";13))));
@If (@IsError (_tmp); Alternativwert; _tmp)
-
Ich dachte, Du hattest Dich verschrieben - aber _temp und _tmp stehen doch immer noch in der Formel.
Kürze mal die Formel für _temp: Erstmal nur eine Spalte nehmen. Fehler? Nein? Nächstes @Sum anhängen und so weiter.
Bernhard
-
...wenn ich nur eine Spalte reinnehme, dann bleibt das Feld immernoch leer. Funktioniert aber ohne die Fehlerüberprüfung.
Sobald ich mehrere Spalten nehme, gibt es ohne Fehlerüberprüfung die Fehlermeldung...
Temp und Tmp habe ich jetzt korriegiert...
Das Gleiche...
-
Ich habe das mal nachgebaut. Ich bekomme nur eine Fehlermeldung, wenn ich entweder
- auf eine Ansicht ziele, die es nicht gibt
- auf eine falsche Spalte ziele
- oder keine Zahlen in den Spalten habe.
Lautet die Fehlermeldung wortwörtlich so, wie Du sie gepostet hast?
Stellst Du sicher, dass in Deinen Spalten nur Zahlen auftreten können? Beispiel:
@If (!@IsNumber (Feldname); 0; Feldname)
Sowie eine Nichtzahl in der Spalte steht, fällst Du auf die Nase.
Kannst Du die leere DB mit einem Test-Dokument hier veröffentlichen? Wenn ja, dann pass auf, dass die DB nicht verschlüsselt ist und die ACL passt.
Bernhard
-
Hallo Bernhard,
ich glaube, daß ich nicht weiß, wie das funktioniert.
Aber es funktioniert ja alles beim ersten mal, nur wenn ich einen neuen Auftrag anlege, dann geht es nicht mehr. zumindest ohne die Fehlerüberprüfung.
-
...in den Spalten für die Anzahl, sind entweder nullen oder 1-10 als Zahlen hinterlegt.
Die verschiedenen Spalten für verschiedene verkaufte Produkttypen...
-
wo kann ich denn diese Formal:
@If (!@IsNumber (Feldname); 0; Feldname)
hinterlegen. In den jeweiligen Feldern?
-
Die Formel gehört in die einzelnen Spalten. Sie muss noch wie folgt ergänzt werden (damit bist dann auch ganz auf der sicheren Seite, dass die Spalten stimmen):
@If (!@IsNumber (DeinFeld); 0; DeinFeld = ""; 0; DeinFeld)
Wie ist es mit einer Antwort auf meine Frage nach der exakten Fehlermeldung?
Bernhard
-
Hallo Bernhard,
jetzt habe ich es.
Die Formeln funktionieren, allerdings nach wie vor nur, wenn ich ohne die Fehlerüberprüfung arbeite.
Der Fehler lag an der Eingabemaske, mit der ich neue Aufträge hinzugefügt habe. Bei der waren diese Felder nicht als Zahl sondern als Text eingestellt.
Trotzdem vielen Dank...
Gruß Marie
-
Genau deswegen habe ich immer wieder auf dem Feldtyp herumgehackt ;)
Und das mit der Absicherung gegen @Error solltest Du unbedingt noch zum Laufen kriegen, wenn Du Dir für die zukünftige Arbeit mit der DB Ärger ersparen willst. Auch die Spaltenformeln solltest Du entsprechend meines Vorschlags mit der erforderlichen Sicherheit versehen (das ist eigentlich sogar primär, denn solange die Spaltenwerte abgesichert sind, braucht man die @Error-Prüfung nicht mehr. Aber doppelte Sicherheit schadet nie).
Bernhard
-
OK, ich werde versuchen das hinzubekommen... Danke schonmal...
Ach so, die Fehlermeldung war so, wie ich sie beschrieben habe...
Noch etwas, die Felder aktualisieren sich erst, wenn ich die Maske schließe und neu öffne. Gibt es da eine andere Möglichkeit?
Wahrscheinlich eher nicht, oder?
Gruß Marie
-
...ich habe bei der Spalte aber ein Feld hinterlegt, wie kann ich dann noch die Formel eintragen?
War übrigens gut, daß du ständig auf dem Feldtypen herumgehakt hast, denn so bin ich auch nur datauf gekommen...
-
UUUUP...
Also, er ändert alle einträge in der Spalte auf 0????
-
Wenn alles 0 wird, dann kann das nur zwei Gründe haben:
- Entweder, Du hast die Formel falsch umgesetzt, oder
- da stehen doch keine Zahlen drin. Was aber nicht sein kann, wenn Deine Summenformel funktioniert.
Wegen der Aktualisierung:
Doch, das geht. Ich hoffe, Du hast Deine Mittelwert-Felder angelegt als "Berechnet zur Anzeige" (denn diese Werte zu speichern, wäre ja totaler Schwachsinn, sie stellen ja nur eine Momentaufnahme dar).
Trage in den Maskeneigenschaften ein, dass sich "Felder automatisch aktualisieren".
HTH,
Bernhard
-
Hallo Bernhard,
sorry, aber ich musste nochmal weg...
Also, ich habe in der Spalte für die Auftragssumme jetzt folgende Formel:
auftragssumme;
@If (@IsNumber (Value); 0; Value_3 = ""; 0; Value_3),
Die Werte sind jetzt alle auf 0 ?!?
Warum ist denn diese Überprüfung so wichtig?
Gruß Marie
-
Marie, der Fehler müsste Dir nun eigentlich selber auffallen:
@If (@IsNumber (Value); 0; Value_3 = ""; 0; Value_3)
@If (@IsNumber (Value_3); 0; Value_3 = ""; 0; Value_3)
Warum diese Prüfung so wichtig ist, sollte Dir aus dem bisherigen Threadverlauf auch klar sein. Das zu verstehen, ist nun wirklich Dein Part.
Bernhard
-
Wie heißt denn das Feld für die Auftragssumme? auftragssumme oder Value_3?
auftragssumme;
@If (@IsNumber (Value); 0; Value_3 = ""; 0; Value_3),
Wenn es auftragssumme heißt, warum prüfst Du danach Value_3? Und falls es Value_3 heißt, was ist dann mit auftragssumme in der ersten Zeile gemeint?
Ich übersetze mal Deine Formel ins Deutsche
Zeige in der Spalte den Wert des Feldes auftragssumme
Wenn Value eine Zahl ist, zeige 0
sonst wenn Value_3 leer ist, zeige 0
sonst zeige Value_3
Was Du brauchst ist aber folgendes
Wenn die Auftragssumme KEINE Zahl ist, zeige 0
sonst wenn die Auftragssumme leer ist, zeige 0
sonst zeige die Auftragssumme
Um es richtig zu machen, kannst Du die erste Zeile komplett streichen, denn die wird von der zweiten ungültig gemacht.
Unter der Annahme, dass das Feld auftragssumme heißt, wäre also die korrekte Formel
@If (!@IsNumber (auftragssumme); 0; auftragssumme= ""; 0; auftragssumme),
Falls das Feld doch Value_3 heißen sollte, hast Du zwei Fehler in der ersten Bedingung der zweiten Zeile.
1. Du prüfst Value anstelle von Value_3
2. Du schreibst 0, wenn Value (korrekt Value_3) eine Zahl ist. Korrekt ist aber, eine 0 zu schreiben, wenn Value_3 KEINE Zahl ist. Wichtig ist das Ausrufezeichen vor dem @, das dreht die Bedingung um
Dass alle Werte 0 sind, liegt wohl daran, dass das Feld tatsächlich auftragssumme heißt. Die Bedingungen werden dann so übersetzt:
Value ist keine Zahl -> nächste Bedingung
Value_3 ist leer -> Ja -> 0 schreiben
Du fragst, wozu diese Überprüfung wichtig ist. Man kann sich darüber streiten, wo und wieoft eine solche Überprüfung eingebaut sein muss. In Deinem Fall sehe ich drei Möglichkeiten:
1. Beim Speichern des Dokuments
2. In der Ansicht
3. In der Berechnung der Summen
M.E. genügt es an einer Stelle, und dann nehme ich immer die erste. Wenn ich nicht zulasse, dass Dokumente mit falschen Feldwerten gespeichert werden, kann auch in Ansichten und Folgeberechnungen nichts falsch laufen. Auf der anderen Seite schadet es nicht, an allen Stellen, an denen Fehler auftreten können, diese sauber abzufangen. Da sollte man abwägen, welche Folgeschäden eintreten können. Wird in einem Dokument Quatsch angezeigt, ist das sicherlich vertretbarer, als wenn eine gesamte Verarbeitungskette (z.B. ein periodischer Reorganisationsagent) unterbrochen wird. Da könnte man sicher lange drüber philosophieren.
-
Danke, Peter. Das Marie es geschafft hat, dass "!" wegzulassen, habe ich echt nicht gesehen. Mit der in der Programmierung erforderlichen Genauigkeit scheint sie es nicht so zu haben.
Was die "Philosophie" angeht: Ich baue die Sicherheitsmechanismen auf jeden Fall immer (auch) an der Stelle ein, an der sie jeweils gebraucht werden. In diesem Falle: Änderungen an der Maske, Agents, die Dokumente ggf. erneut modifizieren etc. - was weiss ich, was da noch kommt. Mein Ergebnis muss jeweils *an dieser Stelle* funktionieren.
Bernhard
-
@Bernhard:
Mit den Sicherheitsmechanismen (zumindest von der Art, wie sie hier bisher diskutiert wurden), gewinnst Du aber nur eine technische Sicherheit.
Maries Anwendung ist ein gutes Beispiel dafür, wie eine technische Sicherheit eine fachliche Unsicherheit bedeuten kann. Annahme: In der Anwendung werden Aufträge dokumentiert, die Auftragssumme wird als Zahl im Dokument hinterlegt.
Beim Speichern des Dokuments den Wertebereich der Auftragssumme zu prüfen, ist ohne jeden Zweifel. Im manuell gespeicherten Dokument kann also nur ein richtiger Wert stehen.
Aus optischen Gründen könnte zugelassen sein, die Auftragssumme leer zu lassen (also nicht zwingend mit 0 angeben, falls keine Auftragssumme vorhanden ist, vielleicht im Falle einer kostenlosen Nachbesserung oder einer Werbeaktion).
Jetzt kommen wir zu der Ansicht, aus der später die Summen gerechnet werden. Ist die Auftragssumme leer, muss sie zweifelsfrei in 0 umgewandelt werden (selbstverständlich sind solche Ansichten immer versteckt, so dass optische Gründe hier niemals ziehen können). Aber was passiert, wenn durch spätere Einflüsse (Agenten, Importe aus anderen Systemen, kaputt reparierte Masken usw.) Auftragssummen im falschen Format auftauchen (z.B. "20TEUR")? In der bisher angegebenen Sicherheitsformel werden die zu 0 umgewandelt.
Die Summenberechnung klappt dann auch problemlos, weil in der Ansicht nur saubere Zahlen stehen. Auch die Abrechnung der Aufträge läuft später sauber durch, weil alle Zahlen technisch korrekt sind, aber sie sind fachlich falsch. In meinem Beispiel ist das Programm zwar störungsfrei durchgelaufen, auf dem Konto fehlen aber 20.000 Euro (das täte mir mehr weh, als ein "type mismatch" oder ein "Falscher Datentyp: Zahl erwartet"). Ohne den Sicherheitsmechanismus in der Ansicht hätte es in der Abrechnung einen Fehler gegeben, der dazu hätte führen müssen, dass die Auftragsdokumente manuell überprüft und korrigiert werden.
-
Insbesondere der letzte Abschnitt stimmt schon - ich gehe da mit Dir, Peter. Jetzt wird es aber zu komplex in Angesicht einer Anwendung, die wir eigentlich überhaupt nicht kennen.
Für derart wichtige (weil monetäre u.ä.) Auswertungen habe ich übrigens immer Routinen, die vorher einen "Blick" auf die Integrität der vorhandenen Daten werfen. *Derzeit* habe ich das nirgendwo in Kombination im Einsatz (also Anzeige eines Fehlers, beispielsweise in (eh kaum auffällig) oder durch Ansichten und dann die Möglichkeit, eine Analyse zu starten), d.h., bevor etwas "ernst wird", läuft der Integritätscheck.
Auf jeden Fall wäre dieses Thema tatsächlich einen Erfahrungsaustausch-Thread wert!
Bernhard