Das Notes Forum
Domino 9 und frühere Versionen => ND8: Entwicklung => Thema gestartet von: Peter Mewes am 20.05.11 - 15:35:22
-
Hallo!
Ich versuche gerade die Werte einer Spalte / Ansicht, mit einem Fixwert zu vergleichen.
Also WENN Wert "Pete" & "Melecay" enthalten in Werte / Spalte DANN gib aus "User bereits vorhanden"
Dazu habe ich Mir die Werte besorgt und in ein Feld geschrieben:
@SetField ("list1" ; (@DbColumn("" ; "" : "******iles.nsf" ; "nach Nachnamen" ; 1) ));
@SetField ("list2" ; (@DbColumn("" ; "" : "******iles.nsf" ; "nach Vornamen" ; 1) ));
Das Auslese der Werte und importieren in Feld hat auch geklappt.
Dann wollte ich mit :
@If (@Contains(list1;"Melecay") & @Contains(list2;"Pete")) ; @Prompt ( "Peter Melecay ist bereits vorhanden")
Schritt zwei meiner Zielsetzung erreichen... ohne Erfolg. Finde in der Hilfe und im forum nix weiter, was mir meinen
Fehler aufzeigt. Leider habe ich die Zusammenarbeit von @IF mit @Contains offenbar nicht ganz korrekt verstanden.
Zumal der Output der Contain Funktion ja auch bolean sein soll? Hm... :(
Pete
-
"ohne Erfolg" ist eine ganz miese Fehlerbeschreibung. Das gepostete Konstrukt lässt sich schon nicht speichern, weil der Else-Zweig eingespart wurde.
Bernhard
-
Hallo!
Die Tatsache, dass ich die Formel nicht speichern kann, umschreibt den Gesamterfolg schon gut! :)
Fehler : "Nicht genügend Argumente für @-Function"
Wie muss das Konstrukt denn Aussehen, wenn @Contains(list1;"Melecay") & @Contains(list2;"Pete") geprüft und
bei True irgendeinen Satz ausgeben soll, Beispielsweise: "Pete Melecay ist schon vorhanden." ?
Würdest du mir das:
@If (@Contains(list1;"Melecay") & @Contains(list2;"Pete")) ; @Prompt ( "Peter Melecay ist bereits vorhanden")
Evtl von der Syntax her umstellen, dass es koscha ist?
Peter
-
Das steht in der DesignerHelp unter @If und hat mit @Contains nichts zu tun.
Bernhard
-
Siehe Bernhards Text. Dazu noch als Tipp, worauf Du Dein Beispiel kontrollieren solltest:
1) Stimmt die Anzahl der ";"?
2) Stimmt Anzahl der "(" mit der Anzahl der ")" überein?
-
Was ist denn der Sinn und Zweck dieser Übung? Um nur die Meldung auszugeben, dass es den Herrn XY schon gibt, brauchst du die Werte nicht in Felder einzufügen.
Außerdem hinkt dein Konstrukt sowieso. Was passiert denn wenn es folgende User gibt?
Pete Smith
Jon Melecay
Dreimal darfst du raten. ;)
Axel
-
Danke, Martin - das hatte ich übersehen: Es fehlt ja nicht nur der Else, sondern auch schon der Then-Teil.
Axels Anmerkungen möchte ich mich ebenfalls anschliessen.
Bernhard
-
Hallo,
und ganz nebenbei prüft Deine Abfrage NICHT, ob ein "Peter Melecay" schon vorhanden ist, sondern ob irgendwer mit dem Vornamen 'Peter' und irgendwer mit dem Nachnamen 'Melecay' vorhanden ist !
Gruß
Jörg
Oops - da war einer schneller !
-
Ausserdem wird nicht berücksichtigt, dass der Lookup sich ja auch SELBST findet, nämlich dann, wenn das Dokument einmal gespeichert wurde... Des weiteren wäre so eine Abfrage richtigerweise in einer Feldvalidierung unterzubringen, und dort nimmt man kein @Prompt sondern ein @Failure.
Und in einer nagelneuen Datenbank laufen gleich 2 Lookups auf Fehler, weil ja noch keine Daten vorhanden sind, und der Fehlerfall wird gar nicht abgefangen...
Viele wenns und abers...
-
Es lohnt sich auch ein Blick auf diesen Thread: http://atnotes.de/index.php/topic,32010.0.html
HTH,
Bernhard
-
Soviel richtige und wichtige Kritik.
Also als Erklärung: Ich beginne gerade eine Ausbildung... bei NULL. Daher mangelt mir noch an weitblick.
Ich probiere gerade mehr rum, als dass ich vorhabe schon endgültige Varianten abzuliefern.
Das meine Suche an sich falsch aufgebaut ist, war mir zwar klar, imom bin ich aber grad an @IF und @Contains dran,
deswegen arbeite ich bewusst damit.
Ich habe die Formel inzwischen angepasst, Fehler lag in den Prompt argumenten:
@If (@Contains(list1;"Mew") & @Contains(list2;"Pet") ); @Prompt([Ok];"Name vorhanden"; "Pet Mew ist bereits in der Liste") ; @Prompt([Ok];"Name nicht vorhanden" ; "Pet Mew ist nicht in der List").
Funktioniert - Bedingt. Allerdings gibt er nun aus, dass Pet Mew sowohl in der Liste, als auch nicht in der Liste ist.
Danke für Link Bernard.
Gruß
Pete
-
Die Klammerung ist hinsichtlich @If immer noch falsch.
Du musst logisch denken, sonst wirst Du nie programmieren können. Die falschen @Prompt-Parameter (hat von uns auch keiner mehr gemerkt, weil schon gar nicht mehr hingeschaut) waren nur ein "Nebenkriegsschauplatz".
Bernhard
-
Du schliesst Deine @If- Klammer zu früh... die gehört HINTER die beiden Prompts...
@If (@Contains(list1;"Mew") & @Contains(list2;"Pet") ); @Prompt([Ok];"Name vorhanden"; "Pet Mew ist bereits in der Liste") ; @Prompt([Ok];"Name nicht vorhanden" ; "Pet Mew ist nicht in der List")
@If (@Contains(list1;"Mew") & @Contains(list2;"Pet") ; @Prompt([Ok];"Name vorhanden"; "Pet Mew ist bereits in der Liste") ; @Prompt([Ok];"Name nicht vorhanden" ; "Pet Mew ist nicht in der List") )
-
Howdy,
danke abermals - Besonders Tode. Die Klammer hat gebracht, dass der Code nun geht. Wegen der regen Kritik, werde ich wohl
aber auf eine andere Methode zurückgreifen, sobald ich die IF / Contain geschichte verinnerlicht habe.
Pete
-
Pete, trenne @If von @Contains.
@If (Wenn; Dann; Sonst)
Und wenn Dein "Wenn" umfangreicher wird, musst Du natürlich auch die Klammern beherrschen:
@If ((Das ist so) & (Und auf jeden Fall auch so); Dann; Sonst)
@Contains (Wo; Was)
Und nochmals: Ohne logisches (und ruhiges) Denken bist Du in er Programmierung völlig erschossen. Dir können dann höchstens "Glückstreffer" gelingen.
Bernhard
-
So jetzt noch mein unqualifizierter Beitrag.
Du solltest gegen Listen nicht mit einem @Contains , sondern mit einem @IsMember prüfen. @Contains macht ja prüft ja nur ob in einem deiner Inhalte ein "Pet" enthalten ist. Und nicht ob nur "Pet" enthalten ist.
Desweiteren würde ich eine Spalte bauen, damit du nicht 2 @dbColumn los treten musst. Das spart noch ein Quäntchen Performance.
-
Hallö. Also mein Amateur-Duplikationstest geht soweit:
@SetField ("list1" ; (@DbColumn("" ; "" : "xxxx.nsf" ; "vDoppelpreuf" ; 1) ));
@SetField ("list2" ; (@DbColumn("" ; "" : "xxxx.nsf" ; "vDoppelpreuf" ; 2) ));
@SetField ("f_list3" ; (@DbColumn("" ; "" : "xxxx.nsf" ; "vDoppelpreuf" ; 3) ));
@Command([FileSave]);
@If (@Contains(list1; _name) & @Contains(list2;_vorname) & @Contains(f_list3;_straße); @Prompt([Ok];"¿Doppeltes Profil?"; "Entweder das Dokument ist leer, oder es wurden weitere Profile mit ähnlichen Eigenschaften gefunden.") ; @Prompt([Ok];"! Profil Unique !" ; "Es scheint, als ob das Profil nicht doppelt vorhanden ist.") )
Ist zwar nicht wasserdicht, aber immerhin. Wie meintest du das mit einer Spalte um mehrere Dbcolumns zu vermeiden?
-
1. Lies Dir mal die Antwort #5 durch
2. Warum speicherst Du das Dokument, bevor Du geprüft hast, ob es schon so eines gibt?
3. Mit @DBColumn wirst Du irgendwann ein 32-k-Problem bekommen
Mein Vorschlag: Bau Dir eine Ansicht, in der in der ersten sortierten Spalte alle Werte, die Du prüfen willst, mit Trennzeichen getrennt stehen (z.B. Hans#Meier#Hauptstraße 1)
Gib in der zweiten Spalte die UniversalID aus (@Text (@DocumentUniqueID))
Lass Dir mit @DBLookup und dem zusammengesetzten Schlüssel die zweite Spalte ausgeben
Entferne aus dem Ergebnis die UniversalID des gerade geöffneten Dokuments
Ist das Ergebnis dann nicht leer, hast Du einen Konflikt
Edit: @IsError ist Dein Freund bei dem @DBLookup. Warum gibst Du eine Fehlermeldung aus, die sagt, dass es ähnliche Dokumente gibt? Du überprüfst doch nur die Gleichheit (allerdings sinnfrei).
-
Also davon abgesehen, dass dieser Code nichts tut, als eine Meldung rauszugeben (wie wäre es mit dem verhindern des speicherns, o.ä.), ist die Prüfung -wie bereits mehrfach erwähnt- vollkommen sinnlos.
Nehmen wir den Fall, dass Deine Daten so aussehen:
Hans Wurst, Friedrich-Metzgerstrasse 5
Tido Test, Teststrasse 11
Maria Müllermeister, Hauptstrasse 12
Rate mal, was passiert, wenn Du einen
Tido Müller, Metzgerstrasse 5
anlegen willst !!!
Müller ist Bestandteil von Wurst, Test, Müllermeister -> Contains ist true
Tido ist Bestandteil von Hans, Tido, Maria -> Contains ist true
Metzgerstrasse ist Bestandteil von Friedrich-Metzgerstrasse 5, Teststrasse 11, Hauptstrasse 12 -> Contains ist true
Du erhälst die Meldung, dass es den Herrn schon gibt...
Erstens prüft contains nur Teilzeichenketten (@Contains( "Müllermeister" ; "Müller" ) = @True !!!! ) und zweitens prüfst Du nirgends, ob die Treffer alle im gleichen Dokument vorkommen...
So wird das nichts...
Tode
-
Hallo Namenvetter!
1. Lies Dir mal die Antwort #5 durch
Geschehen und bereits geantwortet, dass meine Fachkompetenz imom nur für dieses Konstrukt reicht.
2. Warum speicherst Du das Dokument, bevor Du geprüft hast, ob es schon so eines gibt?
War nicht aktuell, sorry. Aktuell bei Querysave:
@SetField ("list1" ; (@DbColumn("" ; "" : "xxxx.nsf" ; "vDoppelpreuf" ; 1) ));
@SetField ("list2" ; (@DbColumn("" ; "" : "xxxx.nsf" ; "vDoppelpreuf" ; 2) ));
@SetField ("f_list3" ; (@DbColumn("" ; "" : "xxxx.nsf" ; "vDoppelpreuf" ; 3) ));
@If (@Contains(list1; _name) & @Contains(list2;_vorname) & @Contains(f_list3;_straße); @Prompt([Ok];"¿Doppeltes Profil?"; "Es scheint bereits ein Profil für diesen Mitarbeiter zu geben. Es wurde eine Email an den zuständigen Admin versandt, um das Problem zu überprüfen.") ; @Prompt([Ok];"Profil neu angelegt" ; "Das Profil wurde gespeichert.") );
@If (@Contains(list1; _name) & @Contains(list2;_vorname) & @Contains(f_list3;_straße) ; @MailSend( "Admin" ; "" ; "" ; "Vermeintlich doppeltes Profil erkannt" ; " Bitte den Link im Anhang prüfen und gegebenenfalls das Doppelte Profil löschen oder bearbeiten." ; "" ; [IncludeDoclink] ) ; "" );
--> Bin gerade dabei etwas zu improvisieren, dass den Querysave abbricht, bei Doppelten Dokumenten. Finde aber das Formel-Gegenstück zu continue = False nicht.
Anhang: Habe mit @return / @ false / @ failure experimentiert. Ohne Erfolg. Werde nun auf die Dblookup-Variante von Peter umsteigen.
3. Mit @DBColumn wirst Du irgendwann ein 32-k-Problem bekommen
Das klingt ungut. Hoffe wird in meiner Testdatenbank aber so schnell nicht passieren ( 10 Profile? ). Habe es aber im Hinterkopf für später!
Mein Vorschlag: Bau Dir eine Ansicht, in der in der ersten sortierten Spalte alle Werte, die Du prüfen willst, mit Trennzeichen getrennt stehen (z.B. Hans#Meier#Hauptstraße 1)
Muss ich mich erstmal belesen wie sowas geht. Bisher weiss ich nur, wie man einer Spalte Werte aus einem Feld zuweist.
Anhang: Success
Gib in der zweiten Spalte die UniversalID aus (@Text (@DocumentUniqueID))
Ich verstehe wo der Zug hinfährt!
Lass Dir mit @DBLookup und dem zusammengesetzten Schlüssel die zweite Spalte ausgeben.
Entferne aus dem Ergebnis die UniversalID des gerade geöffneten Dokuments.
Oright! Sofort wenn ich die Hilfe gegeißelt habe bzgl zusammengesetzer Wert in einer Spalte.
Ist das Ergebnis dann nicht leer, hast Du einen Konflikt
Edit: @IsError ist Dein Freund bei dem @DBLookup. Warum gibst Du eine Fehlermeldung aus, die sagt, dass es ähnliche Dokumente gibt? Du überprüfst doch nur die Gleichheit (allerdings sinnfrei).
Schon verstanden. Auch @ Tode. Das Problem, dass gemixte Daten auch einen "fälschlichen" Konflikt erzeugen ist mir bekannt. Aber bisher die Lösung, die dem was ich möchte am nächsten kommt. Bin wie gesagt noch nicht so weit. Genaugenommen erst seit 2 Wochen.
Anhang: Habe die Daten in Spalte verknüpft. UniqueID wird auch in Spalte Zwei ausgegeben. Muss jetzt aber los. Mir ist eben auch noch
eine Variante mit DBlookup aufgefallen, die ne Menge arbeit sparen würde, die ich vielleich tsogar hinbekomme.
So far großes Danke schonmal.
-
Im querysave ist dein code falach, weil es in der formelsprache kein continue=false gibt. Wie ich dir schon im 8. Post hier geschrieben habe, gehört dein code in eine feld- validierungsformel. Dort mit @failure abbrechen, und schon lässt sich dein konflikt nicht mehr speichern. Dummerweise halt auch nich, wenn es sich um einen false positive handelt.
Ich werde mich aber hier ausklinken, weil ich das Gefühl habe, dass dieses Forum Dir als billige Schulung dienen soll. Und auf diese weise Geld zu sparen ist sehr kurzsichtig, weil es dafür ein vielfaches kostet, den Ärger, den eine solche Herangehensweise beim Endanwender verursaxht, wieder gut zu machen. Und dann heisst es wieder "Notes ist scheisse...", und das nur, weil es per rapid develpment umgebung jedem anfänger ermöglicht, irgendwie was zusammenzuschustern...
-
Ich werde mich aber hier ausklinken, weil ich das Gefühl habe, dass dieses Forum Dir als billige Schulung dienen soll. Und auf diese weise Geld zu sparen ist sehr kurzsichtig, weil es dafür ein vielfaches kostet, den Ärger, den eine solche Herangehensweise beim Endanwender verursaxht, wieder gut zu machen.
Hi Tode. Schade... auch dass du mir soetwas unterstellst. Zu meiner Verteidigung kann ich nur sagen, dass wenn man wie ich keine Ahnung hat und kaum Unterstützung im direkten Umfeld, dann bleibt eben nur der Weg ins Forum. Wenn es etwas dreistes für dich darstellt, zu versuchen seine Unwissenheit in Foren zu besiegen, dann verstehe ich diese Art der Missgunst nicht und halte sie auch nicht für sonderlich förderlich.
Jeder fängt doch Mal irgendwo an. Imom fühl ich mich wie ein kleiner Junge, der am Kickertisch steht und die großen wollen ihn nicht mitspielen lassen. Und auch Tipps sind nicht drin, weil man noch nicht über die Tischkante schauen kann! Gemeinheit! :)
Ohne das Ganze ausufern lassen zu wollen und sich hier generell unbeliebt zu machen: Sei dir meines Dankes für deine Hilfe bisher absolut gewiss lieber Tode und lass dir ferner versichert sein, dass ich kein Geld habe, dass ich sparen könnte, indem ich mich hier umsonst rumtreibe...
Ich setzt mich jetzt an die DBlookup geschichte.
So far.
-
Hallo Pete,
wenn ich mich mal hier einschalten dürfte ...
Es geht hier weniger um Dich, Du versucht Dich ja -so gut es eben geht- durchzuwursteln. Wenn ich es richtig verstanden habe, machst Du gerade eine Ausbildung und Dein Ausbilder hat Dich einfach mal so in kalte Wasser geworfen und Dich auf Lotus Notes losgelassen.
Da es sich aber um ein äußerst leistungsfähiges und komplexes System handelt, dass über zig Stellrädchen individuell auf sehr viele Bedürfnisse zugeschneidert werden kann, ist das die absolut falsche Herangehensweise.
Richtig wäre es, wenn Dein Ausbilder Geld in die Hand nehmen und Dir eine Grundausbildung in Lotus Notes zukommen zu lassen würde. Mit diesem Grundwissen könntest Du dann Probleme angehen und bei speziellen Sachen direkt Fragen bzw. gezielt die Forensuche bemühen.
Hier drin schreibt jeder zunächst einmal unentgeltlich und investiert Zeit, bekanntermaßen bedeutet für Selbständige Zeit = Geld ... dies sollte man einfach mal bedenken und in gewisser Weise auch honorieren, indem man nämlich nicht versucht auf Kosten anderer grundlegendste Grundlage per "try-and-error" zu erlernen.
Ich hoffe, Du verstehst, was ich damit ausdrücken will.
Bernd
-
Hallo Pete,
wenn ich mich mal hier einschalten dürfte ...
Es geht hier weniger um Dich, Du versucht Dich ja -so gut es eben geht- durchzuwursteln. Wenn ich es richtig verstanden habe, machst Du gerade eine Ausbildung und Dein Ausbilder hat Dich einfach mal so in kalte Wasser geworfen und Dich auf Lotus Notes losgelassen.
Gerne darfst du dich einschalten! Danke für die konstruktiven Worte. Die Ausbildung beginnt erst in zwei Monaten. Solange mache ich ein recht liberales Praktikum nach dem Motto: Schau dich um, mach dich vertraut. Eigentlich etwas, dass mir entgegen kommt.
Da es sich aber um ein äußerst leistungsfähiges und komplexes System handelt, dass über zig Stellrädchen individuell auf sehr viele Bedürfnisse zugeschneidert werden kann, ist das die absolut falsche Herangehensweise.
Wie bist du denn damals in die Maschinerie gelang und wo hast du angefangen? Ich bin über JEDEN Tipp dankbar, der produktiv ist und meine Domino-kenntnisse erweitert.
Richtig wäre es, wenn Dein Ausbilder Geld in die Hand nehmen und Dir eine Grundausbildung in Lotus Notes zukommen zu lassen würde. Mit diesem Grundwissen könntest Du dann Probleme angehen und bei speziellen Sachen direkt Fragen bzw. gezielt die Forensuche bemühen.
Ich bin felsenfest davon überzeugt, dass ich noch eine detaillierte Ausbildung genießen werde, imom ist aber recht viel los und ich bin quasi nur aus Kulanz schon da. Will niemanden zur last fallen und schonmal Vorwissen sammeln.
Habe absolut verstanden was du ausdrücken willst. Kann es auch nachvollziehen. Mein einziges Problem ist, dass ich Foren für "OpenSource" halte. Und mich stört es einfach, wenn sich Leute (egal wie gut sie auch sind, wie wichtig ihre Postings sein mögen und wie teuer ihre Zeit bezahlt ist...) unbedingt lautstark zum Ausdruck bringen müssen, dass Neulinge unwillkommen sind... dabei ist das Forum (zumindest Teilweise) genau dafür da und niemand ist verpflichtet etwas zu schreiben.
Es ist keine Seltenheit, dass man bereits nach dem ersten Posting in einem Forum keine Lust mehr hat, weil der Herr oder die Frau "Hausdrachen" sofort aus der Dominanz-Ecke gesprintet kommt um einen auf den Platz zu verweisen. :(
Aber ich halt die Ohren steif! Und wenn ich groß bin, dann werd ich der beste und tollste Dominorisierer aller Zeiten! :)
Peter
Ps.: Zurück zu meinem Problem. Ich habe nun:
eine View "vAdminView". In der ersten Spalte der view "Vorname, Nachname und Straße" ( via Formel: _vorname + " " +_name + " " + _straße ). Als Platzhalter erstmal " ", statt "#", da mir der Sinn der "#" noch nciht geläufig ist. Der übersicht wegen? Egal! Weiter.
Spalte zwei beinhaltet nun die UniqueID - wie von Peter Klett vorgeschlagen - des dokuments. -> (@Text (@DocumentUniqueID)) <-
Ich habe jetzt erstmal Versucht den Inhalt der ersten Spalte in ein Feld zu injizieren. Dafür habe ich einfach ein Feld ersttellt mit dem aussagekräftigen Namen: "einFeld". Feld ist berechnet, text. Ich habe schon verschiedene Varianten des DBLookups probiert, komme aber eigentlich immer an den Error: "Nicht genügend Argumente für @function".
Mein letzer Versuch war:
einFeld := @DbLookup("":"NoCache";"":"****.nsf";"vadminview"; check;"UniqueID");
Bitte keine Schelte. Ich muss mich damit einfach nochmal beschäftigen.
-
Wie ich in die Maschinerie gelangt bin? Na genau so, wie ich es beschrieben habe. Ich durfte erst mal auf mehrere Seminare (Notes Administration, Notes Entwicklung 1 und 2, Notes Skript - Grundlagen). Den Rest habe ich mir dann aus der Hilfe und diesem Notes-Forum hier "zusammengeklaut". ;)
Du tust Torsten (Tode) übrigens wirklich unrecht (und allen anderen Schreibern indirekt auch), wenn Du ihn als Hausdrachen beschimpfst, Du solltest Dich hier zurücknehmen und Deine Gefühle runterschlucken. So benimmt man sich nicht im Forum! Hier wird einem gern geholfen.
Dazu noch ein Zitat von Bernhard (koehlerbv) von heute Nacht:
"Die konstruktive Hilfe war das der Hinweis auf das systematische Herangehen und das Heranziehen von guter Literatur. Wenn wir bei einer Bruchstückaufgabe wiederum nur Bruchstücke zuliefern würden, nützt das doch keinem - der Gesamtzusammenhang bliebe ja unklar.
Über sorgfältige und respektvolle (also verständliche und leserliche) Fragestellung hatten wir hier schon genug Beiträge, ich werde das hier nicht wiederholen ausser "Wie es in den Wald hineinruft, so schallt es wieder heraus."
Man könnte sich ja wenigstens die Mühe geben, an den doch abzählbar erforderlichen Stellen die Umschalttaste zu drücken.
Deine Fragen sind hier sehr willkommen - dafür sind wir da, und einige Leute schreiben hier nicht aus Gag vier- oder fünfstellige Antwortzahlen.
Das Einlesen in die Grundlagen und das selbständige Denken können wir aber keinem abnehmen.
Und ganz wichtig: Wenn Du programmieren willst, dann übernimmst Du immer Verantwortung für andere (es sei denn, Du betreibst "softwaretechnologische Onanie" und willst Dir nur selber was zusammen schnitzen). Die Worte "probieren" und "irgendwie anfangen" u.ä. sind damit einfach tabu.
So, und jetzt lies, bilde Dich, investiere (Zeit) - und dann her mit Deinen konkreten Fragen. Nochmals: Wir helfen gerne!
Bernhard"
Denk drüber nach bevor Du schreibst. (das ist ein netter gut gemeinter Rat ohne Moralzeigefinger)
Bernd
EDIT: Hier noch der Link zu Bernhards Eintrag:
http://atnotes.de/index.php/topic,51763.msg332764.html#msg332764
-
Ich bin felsenfest davon überzeugt, dass ich noch eine detaillierte Ausbildung genießen werde, imom ist aber recht viel los und ich bin quasi nur aus Kulanz schon da. Will niemanden zur last fallen und schonmal Vorwissen sammeln.
Habe absolut verstanden was du ausdrücken willst. Kann es auch nachvollziehen. Mein einziges Problem ist, dass ich Foren für "OpenSource" halte. Und mich stört es einfach, wenn sich Leute (egal wie gut sie auch sind, wie wichtig ihre Postings sein mögen und wie teuer ihre Zeit bezahlt ist...) unbedingt lautstark zum Ausdruck bringen müssen, dass Neulinge unwillkommen sind... dabei ist das Forum (zumindest Teilweise) genau dafür da und niemand ist verpflichtet etwas zu schreiben.
Es ist keine Seltenheit, dass man bereits nach dem ersten Posting in einem Forum keine Lust mehr hat, weil der Herr oder die Frau "Hausdrachen" sofort aus der Dominanz-Ecke gesprintet kommt um einen auf den Platz zu verweisen. :(
Aber ich halt die Ohren steif! Und wenn ich groß bin, dann werd ich der beste und tollste Dominorisierer aller Zeiten! :)
Peter
Niemand hat hier geschrieben, dass Neulinge unwillkommen sind.
Hier gibt es auch keine Hausdrachen (außer mir).
Bernhard und Tode haben nur klargestellt, wie dieses Forum funktioniert. Das ist doch netter, als wenn du einfach keine Antworten mehr bekommst, und nicht weißt warum?
Und ganz ehrlich: wenn du so am Anfang stehst, macht es durchaus Sinn, einmal z. B. die Unterlagen von Herdt zu kaufen und durchzugehen. Die sind preislich überschaubar, und in deinem Fall gut investiert.
Wenn Open Source für dich 'einfach konsumieren' heißt, dann ist dieses Forum definitiv kein 'Open Source'. Und ganz ehrlich, ich habe in der Zeit eine Menge Konsumenten hier erlebt und wenig Produzenten. Und die Konsumenten verweisen immer gerne auf den Anstand/ Ehre/ Solidarität (bel. Begriff einsetzen) der Produzenten.
Aber dieses Forum ersetzt keine grundsätzliche Ausbildung. Und es soll deinen Ausbilder auch nicht aus der Lehrverantwortung entlassen
Grüße
Dau-in
-
Aber ich halt die Ohren steif! Und wenn ich groß bin, dann werd ich der beste und tollste Dominorisierer aller Zeiten! :)
Super Einstellung, solche Leute brauchen wir! ;)
Wenn Du niemandem zur Last fallen willst, solltest Du Dir vorhandene Datenbanken (am besten einfache) anschauen. Du kannst Dir einfach eine neue Datenbank (Anwendung) aus einer vorhandenen Schablone erstellen (die vorhandenen Schablonen werden im Dialog angezeigt). Darin solltest Du Dir die wesentlichen Grundbegriffe und -funktionen aneignen
Was ist eine Maske
Was ist ein Dokument
Was ist eine Ansicht
usw.
Wenn Du erst einmal den Unterschied zwischen Maske und Dokument verstanden hast, hast Du schon etliche "Entwickler" hinter Dir gelassen ;D
Verändere einfache Dinge und schaue, was passiert. Lies auch die Hilfe, die finde ich in Notes wirklich gut gemacht.
Aber: Wenn Du wirklich gute Anwendungen entwickeln willst, solltest Du zuerst NICHT an das Entwicklungswerkzeug denken. Einen Prozess, der auf Papier nicht funktioniert, wirst Du mit keiner Software zum Laufen bekommen. Denke Dir also das, was Du umsetzen willst, papierhaft aus. Und dann erkläre jemanden, dass er das machen soll. Nichts anderes ist Entwicklung: Ein Prozess ausdenken und der Maschine so erklären, dass sie ihn so ausführt, wie Du es haben willst. Ein Computer ist schließlich auch nur ein Mensch.
In Deinem konkreten Fall sieht das z.B. so aus: Du hast verschiedene Karteikarten, auf denen Name, Vorname und Straße eingetragen wird. Du willst verhindern, dass eine Karte doppelt ausgefüllt wird. Deine bisherigen Versuche papierhaft beschrieben sehen so aus:
1. Erstelle eine Liste der Vornamen aus allen Karteikarten
2. Erstelle eine Liste der Nachnamen aus allen Karteikarten
3. Erstelle eine Liste der Straßen aus allen Karteikarten
4. Prüfe, ob der Vorname der neuen Karteikarte in der Liste der Vornamen enthalten ist
5. Prüfe, ob der Nachname der neuen Karteikarte in der Liste der Nachnamen enthalten ist
6. Prüfe, ob die Straße der neuen Karteikarte in der Liste der Straßen enthalten ist
7. Wenn alle Prüfungen 4. - 6. zutreffen, gibt es die Karte schon
Da ein Computer eher unkritisch alles tut, was man ihm sagt, wird er sich kaum wehren. Einem denkenden Menschen diesen Auftrag zu erteilen, könnte eine entsprechende Antwort nach sich ziehen. Auch die Akzeptanz in Hinsicht auf zukünftige Aufträge könnte stark leiden. Da ist das Arbeiten mit einem Computer wesentlich angenehmer, das Teil ist einfach nicht nachtragend.
Was ich sagen will: Denke erst darüber nach, was Du willst. Dann überlege Dir, wie Du es selbst machen würdest (ohne Rechner) und erst danach fange an, nach Methoden und Befehlen zu suchen, mit denen Dir die Maschine diesen Job abnehmen könnte. Wenn Du die Aufgabe nicht bewältigen kannst, kann es die Maschine auch nicht, sie kann es dann allerdings nur schneller nicht.
Und wenn Du dann Fragen (am besten konkrete) zu bestimmten Befehlen, Designelementen, Zusammenhängen usw. hast, wirst Du hier immer jemanden finden, der Dir hilft.
-
Jetzt muss ich mich doch nochmal kurz einschalten:
Dir wurde MEHRFACH von den verschiedensten Leuten geholfen. Du hast Tipps bekommen, wie etwas geht, hast Hilfe bekommen zu den (wenigen) konkreten Fragen, sogar Code wurde für Dich korrigiert.
Für mich sah aber jede Deiner Antworten so aus, als hättest Du
a) Die Antworten nicht gelesen
oder
b) Die Antworten zwar gelesen, aber gar nicht erst versucht, zu verstehen, was dahinter steckt.
Ich stimme Dir zu, dass im normalfall Foren für jeden offen sind, und auch hier wird gerne jedem geholfen.
Im Lotus Notes Umfeld befinden wir uns aber nicht auf einer privaten Spielwiese, sondern im Business- Umfeld. Sehr viele, die hier antworten, verdienen ganz nebenbei Ihr Geld mit dem, worüber Sie hier schreiben.
Und diesen -ich rede jetzt mal ausdrücklich nur von mir, obwohl ich weiss, dass es auch andere hier gibt, die ähnlich denken- geht einfach die Hutschnur hoch, wenn man sieht, dass hier nach dem Trial & Error Prinzip Code produziert wird, der den Anwendern in kürzester Zeit um die Ohren fliegen wird.
Im übrigen haben wir nur versucht, Dich davor zu bewahren, die gleichen Fehler zu machen und in die selben Fallen zu tappen, in die viele von uns halt schon getappt sind. Gerade dieses "Ich prüfe auf doppelte..." ist ein solches Minenfeld, in dem man viel mehr falsch machen kann, als richtig... Eigentlich gibt es nur einen einzigen richtigen Weg, das zu tun (unabhängig davon, mit welchem Code man den dann umsetzt) aber sehr viele falsche... Und Du bist absolut auf dem falschen Weg.
Und nur mal so nebenbei: Dass ich Dir / Deiner Firma unterstelle, auf diese Weise um Schulungen / etc. herumzukommen, kommt schlicht und ergreifend aus der Erfahrung hier im Board. Dass Du nun die löbliche Ausnahme bist, konnte ich ja nicht wissen...
Trotz allem, auch wenn es mehrfach gesagt wurde:
Lies Dich erst mal ein - Die Designer- Hilfe ist ein super Einstiegspunkt (Einfach Datei -> Anwendung -> Öffnen -> Hilfe-Verzeichnis -> Lotus Domino Designer Hilfe, dann von oben anfangen (interessant wird es ab "Anwendungsgestaltung")
Auch die Herdt- Unterlagen kann ich nur jedem empfehlen (besonders die zum 3 tägigen Lotus Entwickler- Einsteiger- Kurs)
Dann fange an zu entwickeln... Denke nach... und wenn Du dann KONKRETE Fragen hast, bist Du jederzeit hier willkommen.
Nur die "Entwickler- Denke" bzw. das logische denken / systematische Herangehen an Funktionen können wir Dir nicht ersparen.
Gruss
Tode
-
Hallo!
Es tut mir leid, dass ich so unbeholfen war. Ferner tuts mir leid wenn ich wen zunahe getreten bin. Bin halt ne Mimose. Hoffe ich krieg trotzdem nochmal Hilfe, wenn ich nicht mehr ganz so grün bin. Kann man das so stehen lassen und alle sind glücklich? Wenn sich noch wer individuell angegriffen gefühlt hat, kann er dies gerne kund tun und ich entschuldige mich auch nochmal direkt!
Pete
Ps - falls noch wer liest:
Mein Problem im Moment: Ich habe eine Ansicht. 4 Spalten: Name, Vorname, Straße, UniqueID.
Er soll Spalte 1 auf den Fix-Namen "Melecay" testen und wenn vorhanden die Unique ID ( Spalte 4 ) ausgeben. Die @failures sind zur visuellen wahrnehmung ob irgendwas klappt.
@If(@DbLookup("":"NoCache";"":""; "vdoppelpreuf"; "Melecay";4; "") != 0 ; @Failure("name gefunden") ; @Failure ("nicht gefunden"))
Geht nicht. Nicht genug Argumente für @function. Jemand ne Idee und noch lust zu helfen?
-
Heisser Tipp:
Lies doch mal in der Designer-Hilfe ! Dort sind auch entsprechende Beispiele.
z.Bsp: @If( condition1 ; action1 ; condition2 ; action2 ; ... ; condition99 ; action99 ; else_action )
@If(AreaCode<1000;@Success;@Failure("Area codes have only 3 digits"))
-
Zur Formel:
Den letzten Parameter in dbLookup lass ganz weg.
Lies nach, was dbLookup zurückliefert. Besonders in Deinem Fall bestimmt nicht die Zahl 0. Dafür könnte es auch @Error zurückgeben.
@Failure kannst Du nur in der Eingabevalidierung verwenden. Du verwendest ihn gleich zweimal - das ist Quatsch. Statt @Failure ("Name gefunden") verwende Success.
Lies die Hilfe gründlicher. Was hast Failure auf deutsch?
Und das Konstrukt ist immer noch ungenügend. Schreib doch als erstes mal genau auf, was Du haben möchtest. Erst denken, dann Coden. In Deinem Fall kommt dann auch noch das *genaue* Lesen der DesignerHelp zu den verwendeten @functions dazu.
Bernhard
-
Versuchst Du eigentlich auch mal, Deine Fehler selbst herauszufinden? Da sind wir wieder beim systematischen vorgehen...
1. Wo steht diese Formel? - @Failure funktioniert NUR in Eingabevalidierungen, sonst NIRGENDS
2. @DBLookup fängt man IMMER mit @IsError ab, sonst hat man ganz schnell Probleme
Dein Fehler liegt aber -höchst wahrscheinlich- im nicht angegebenen letzten Parameter: Entweder DU füllst Ihn mit einem Wert, den er erwartet, also zum Beispiel [FAILSILENT], oder Du lässt ihn weg.
So sähe ein sauberer DBLookup aus, den man dann auch noch warten kann:
Das ganze in einer Feldvalidierung...
viw := "vdoppelpreuf";
crit := "Melecay";
col := 4;
lkp := @DBLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) ; @Failure( "Name gefunden" ) ; @Success );
Im übrigen kann ich Bernhard nur erneut recht geben: Geh nicht blind an so ne Sache ran, sondern systematisch...
Von Systematik ist bei Dir momentan nichts zu erkennen...
Wenn Du es schon nicht schaffst, in einem Einzeiler einen Fehler zu finden, dann wirst Du in der Programmierung keine Zukunft haben...
Und das hat nichts mit der verwendeten Programmiersprache / ENtwicklungsumgebung zu tun, sondern ist allgemeingültig.
Entschuldige, dass ich so hart sein muss, aber so sehe ich das aktuell...
Gruss
Tode
-
Ist ja interessant, hier mit zu lesen. Da lernt man doch gleich dazu.
Aber das hier versteh ich nicht:
@If( res != @Text( @DocumentUniqueID ) ; @Failure( "Name gefunden" ) ; @Success );
Wenn der @IsError greift, ist res doch null leer und damit wäre doch in diesem IF der Name NICHT gefunden ???
Gruß
-
Hallo Bernhard,
Zur Formel:
Den letzten Parameter in dbLookup lass ganz weg.
So sei es.
Lies nach, was dbLookup zurückliefert. Besonders in Deinem Fall bestimmt nicht die Zahl 0. Dafür könnte es auch @Error zurückgeben.
@DbLookup looks up a specified value in the first sorted column of a specified view in a specified database. For each document that matches the search value, @DbLookup returns the value of a specified field on the document or column in the view.
Zu Deutsch Er sucht einen Bestimmten Wert ( in meinem Fall Melecay?), in der erstern sortierten Spalte ( in meinem Fall Name ), Findet er den Namen Melecay, gibt er den Wert der Spalte 4 aus ( in meinem Fall Unique ID ). WENN dieser ausgabewert nicht 0 ist ( also er einen Namen und damit dann auch einen Wert aus Spalte 4 gefunden hat ), DANN soll er mich darüber informieren, auch bei anderer Variante.
@Failure kannst Du nur in der Eingabevalidierung verwenden. Du verwendest ihn gleich zweimal - das ist Quatsch. Statt @Failure ("Name gefunden") verwende Success.
Oright!
Lies die Hilfe gründlicher. Was hast Failure auf deutsch?
So glaube man mir doch, dass ich die DBlookup rauf und runter gelesen habe. Und bitte nehme man mein momentanes Unverständnis nicht als direkten Beleg für meine generelle Unzulänglichkeit! ;( Ps.: Failure = Fehlschlag / Misserfolg
Und das Konstrukt ist immer noch ungenügend. Schreib doch als erstes mal genau auf, was Du haben möchtest. Erst denken, dann Coden. In Deinem Fall kommt dann auch noch das *genaue* Lesen der DesignerHelp zu den verwendeten @functions dazu.
Ich tu' mein bestes. Und deshalb tu ich mir noch ein paar Mal die @functions rein. Was ich machen will? ( vorerst ): In einer Ansicht, soll der fixe Name ( Melecay) gesucht werden. Wenn gefunden soll der Spaltenwert der UniqueID ausgegeben werden. Der UniqueID-Wert wird dann als Kontrollwert benutzt, ob der Name bereits vorhanden ist.
Soweit der Plan.
-
Ach menno... Das sollte Pete doch selbst rausfinden ;-).
Du hast natürlich recht... Die Zeile müsste korrekt heissen:
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Failure( "Name gefunden" ) ; @Success );
Danke fürs aufpassen...
Tode
@Pete: Wenn in Spalte 4 eine DocumentUniqueID steht, dann ist das ein Text.... wenn Du diesen jetzt mit einer Zahl (0) vergleichst, dann geht das ebenfalls schief...
Und meine Formel ist nichts anderes als Deine, nur dass die einzelnen Parameter in Variablen rausgezogen wurden und ein Errorhandling mit angefügt wurde... Diese Formel solltest Du schon lesen und auch verstehen können...
-
Danke fürs aufpassen...
Aufpassen wollte ich gar nicht, nur verstehen. ;)
Wobei mir nicht wirklich klar ist, warum man da noch die UNID vergleichen muss...
-
Wobei mir nicht wirklich klar ist, warum man da noch die UNID vergleichen muss...
Wenn das Dokument schon gespeichert wurde, und die Überprüfung noch einmal läuft, findet sich das Dokument selbst und sollte das auch erkennen, sonst wird das Speichern verhindert, weil der Schlüssel schon existiert, allerdings im gleichen Dokument, und das wär doch blöd, oder?
-
du willst nicht das 'eigene Dokument' sperren
Wenn du Tom Müller schon angelegt hast, und bearbeitest dieses Dokument nochmals, könntest du es niemals mehr abspeichern.
du willst nur verhindern, dass ein neues Dokument mit 'Tom Müller' angelegt wird
-
du willst nur verhindern, dass ein neues Dokument mit 'Tom Müller' angelegt wird
Nicht ganz vollständig, Anita: Jemand kann "böse" sein und legt ein neues Dokument mit dem Namen Niegehört Gibtesgarnicht an und speichert es (erfolgreich).
Dann editiert er das Dokument noch einmal und ändert den Namen in Tom Müller.
Es geht also nicht nur um neue Dokumente.
Bernhard
-
Wenn das Dokument schon gespeichert wurde, und die Überprüfung noch einmal läuft, findet sich das Dokument selbst und sollte das auch erkennen, sonst wird das Speichern verhindert, weil der Schlüssel schon existiert, allerdings im gleichen Dokument, und das wär doch blöd, oder?
:-X :-[
Ich geh ma in die Ecke....
Danke Dir für die Erklärung!
-
Ich begebe mich auf den Spießrutenlauf und versuche das ganze Mal aufzudröseln.
viw := "vdoppelpreuf";
crit := ~_name;
col := 4;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Failure( "Name bereits gefunden" ) ; @Prompt([Ok];"Profil scheint Unique"; "Das Profil ist nicht doppelt.") )
Okay. Die Variablendeklarierung ist klar. Aber wenn ich das Ding richtig verstehe, dann:
- wird res bei Erfolg von dblookup zu lkp ( wobei lkp die UniqueID ist).
- wird res bei Misserfolg zu ""
- wenn res am Ende NICHT der UniqueID und NICHT "" entspricht, DANN sagt er "Name bereits vorhanden"
-sollte res der UniqueID entsprechen, bzw einen Wert jenseits "" haben, dann gibt er den Prompt aus.
Konkrete Frage1: Sehe ich es richtig, dass die Ausgaben so im Moment falsch sind? Oder habe ich nur wieder die Syntax nicht ganz verstanden? Eigentlich müsste er doch bei !="" und !="UniqueID" sagen, dass der Name noch NICHT da ist, oder?
Konkrete Frage2: Was könnte zB. bei DBlookup passieren, das lkp veranlasst hätte "" zu sein.
-
Nix "Spiessrutenlauf", das war notwendige Kritik.
Und dass das positiv gewirkt hat, zeigt Dein Posting auf beste Weise. Daran "kritisiere" ich lediglich noch, dass Deine Ansicht vermutlich nicht "vdoppelpreuf" heisst ;)
Bernhard
-
Eigentlich müsste er doch bei !="" und !="UniqueID" sagen, dass der Name noch NICHT da ist, oder?
Nein. Der DBLookup findet in der Ansicht nach Deinen Suchkriterien ja ein Dokument und liefert dazu die UNID zurück.
Und wenn Du mein Nachfragen verfolgt hast, würdest Du auch verstehen, was der Vergleich der UNID macht: Es wird das gefundene Dokument mit dem verglichen, welches gespeichert werden soll. Sind die UNID nicht identisch ->
Konkrete Frage2: Was könnte zB. bei DBlookup passieren, das lkp veranlasst hätte "" zu sein.
Z.B. dass Du Dich bei der Benennung der Ansicht verschrieben hast. ;D
-
Konkrete Frage1: Sehe ich es richtig, dass die Ausgaben so im Moment falsch sind? Oder habe ich nur wieder die Syntax nicht ganz verstanden? Eigentlich müsste er doch bei !="" und !="UniqueID" sagen, dass der Name noch NICHT da ist, oder?
Wenn das Ergebnis nicht leer und auch nicht die UniversalID des aktuellen Dokuments ist, dann gibt es schon ein anderes Dokument mit den gleichen Werten. Die Meldungen sind in der korrekten Reihenfolge
Konkrete Frage2: Was könnte zB. bei DBlookup passieren, das lkp veranlasst hätte "" zu sein.
Der Name wurde in der Ansicht nicht gefunden, also DBLookup findet über den Suchschlüssel (bei Dir den Namen) kein Dokument. Aber dann wäre nicht lkp leer, sondern @IsError, und damit wird res auf "" gesetzt, aber das meintest Du wohl?
Die Zeile crit := ~_name; habe ich nicht verstanden, ist das ein Tippfehler oder etwas, was ich noch nicht kenne?
-
Hehe.
Doch die Ansicht heisst tatsächlich so.
(http://desmond.yfrog.com/Himg710/scaled.php?tn=0&server=710&filename=preuf.jpg&xsize=640&ysize=640)
Zugegeben entstanden aus einem Rechtschriebfehler, dann aus Witzigkeit beschlossen so zu belassen. Sag Mal drei Mal hintereinander das Wort "preuf", dann weisste wieso. :) Und ja... im Namen der Programmiererehre werde ich meine Ansichten in Zukunft ordentlich benennen.
Die Zeile crit := ~_name; habe ich nicht verstanden, ist das ein Tippfehler oder etwas, was ich noch nicht kenne?
Ich hatte die Tage Mal munkeln gehört, dass Feldnamen mit "_" beginnend in einer Deklaration ":=" in Formel nicht funktionieren, es sei denn, man setzt ein Tilde davor... Not?
-
Das hat nichts mit "Programmiererehre" zu tun, Pete - das spart im schlimmsten Fall ein blaues Auge ;D
Du weisst nie, wer morgen mit Deinem Code arbeiten muss, und jeder ist dankbar, wenn Variablennamen oder die Bezeichner von Designelementen selbstsprechend sind. Übrigens ist IBM Lotus hier selbst kein leuchtendes Beispiel - die Leute dort schreiben manchmal ganz schön schlampig.
Ein weiterer Tipp: Wenn Du die Ansicht zumindest vor unbedarft-neugierigen Anwendern verbergen willst, dann setze den Ansichtsnamen in Klammern. Bei "normalen" Aktionen werden diese Ansichten dann nicht angezeigt.
Bernhard
-
Die Zeile crit := ~_name; habe ich nicht verstanden, ist das ein Tippfehler oder etwas, was ich noch nicht kenne?
Das kann man so machen, muss es aber nicht ;)
Im Gegensatz zu LotusScript, wo man ja beispielsweise
docMail._ViewIcon = 1
nicht verwenden kann und statt dessen eben die Mathilde einsetzen muss:
docMail.~_ViewIcon = 1
Beste Grüsse nach Norwegen,
Bernhard
-
EDIT: Falsch verstanden.
-
Nochmal zu ~_name:
@Bernhard: Dass man das mit Script so machen kann, habe ich hier auch erst gelernt (ich verwende da immer doc.GetItemValue)
@PeteM: Was ist das bei Dir? Ist das das Feld _Name im Dokument (in der Maske kann es kaum sein), wenn ja, wie ist das da reingekommen? Kann ich mir also kaum vorstellen. Oder hast Du eine Variable in der Formel so benannt? Zusammengefasst also so:
~_name := MeinNamenfeld;
crit := ~_name;
Das würde wohl funktionieren, wäre aber doppelt gemoppelt.
-
Der Tipp mit den ( ) ist super. Direkt in den Wissensfundus absorbiert.
Wissenlücke Tilde auch gefüllt.
Das der Designer hustet is mir neu. Meine Felder haben fast alle Namen mit "_" beginnend. Ist aber nur noch so, weil ich zu faul bin sie alle und die darauf verweisenden Routinen umzubennen. Werde es aber nicht wieder tun. Und ja, die Felder sind in Masken. ^^;
Zurück zu:
viw := "vdoppelpreuf";
crit := Mewes;
col := 4;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
@SetField ("list2" ; lkp);
@SetField ("f_list3" ; "Hallo");
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Failure( "Name vorhanden" ) ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil scheint Unique.") )
Funktioniert leider nicht. Bzw nicht so wie ich dachte. Ich habe zur Überprüfung den lkp Wert in das auf dem Screenshot zu sehende Kontrollfeld "f_list3" gesetzt und das Feld "list2" mit Hallo bestückt.
Das Feld list2 bleibt immer "". Egal ob man einen Namen wählt, der definitiv vorhanden ist, einen der nicht vorhanden ist, oder ob man das ~_name durch einen Fixwert ( Melecay ) der bereits vorhanden ist ersetzt. Irgendwas greift nicht.
-
Pete, bitte ändere nicht nachträglich Deine Posts, wenn sich dadurch der Sinn des Inhalts verändert. Wenn vorab schon jemand geantwortet hat, sieht keine Sau mehr durch oder es entstehen Missverständnisse.
Wenn Dein Feld _Name heisst, dann führt eine Zuweisung variable := ~_name zu einem Leerstring, da ~_name nicht als Item vorhanden ist.
Wie schon an Peter geschrieben, ist das in LotusScript anders. Da braucht es in Kombination mit Underscore die Mathilde.
@Peter: Die Bennenung eines Feldes (!) "_name" ist notesseitig statthaft und machbar.
Bernhard
-
Mewes ist ein Itemname, Pete!
Du willst "Mewes" verwenden.
Bernhard
-
@Peter: Die Bennenung eines Feldes (!) "_name" ist notesseitig statthaft und machbar.
Man wird alt wie ne Kuh und lernt immer noch dazu ... ;)
Man kann sich damit das Leben allerdings auch unnötig schwer machen, spätestens bei Script wird es dann lästig. Ich verwende den Unterstrich i.d.R immer vor Variablen in Formeln, um damit eindeutig erkennen zu können, dass damit KEIN Feld gemeint ist. Also mein Dialekt wäre gewesen:
_viw := "vdoppelpreuf";
_crit := Namenfeld;
_col := 4;
_lkp := @DbLookup( "" : "NoCache" ; "" ; _viw ; _crit ; _col );
...
Zum Glück haben wir da alle unsere Freiheiten ...
-
Man wird alt wie ne Kuh und lernt immer noch dazu ... ;)
Das ist die Bedingung, um bei AtNotes mitmachen zu dürfen ;)
Bernhard
-
Mewes ist ein Itemname, Pete!
Du willst "Mewes" verwenden.
Bernhard
Da hast du sowas von Recht gehabt.
Danke. Schönen Feierabend erstmal.
-
Wo steht denn jetzt der Code, den Du gepostet hast?
Wenn der in den Schaltflächen steht, die Da im Screenshot angezeigt werden, dann passiert GAR NIX, wenn er ein Dokument findet...
Denn @Failure ist -wie ich schon mehrfach geschrieben habe- NUR in Feldvalidierungen gültig!!!
Auszug aus der Designer- Hilfe (Die Du scheinbar noch immer meidest wie der Teufel das Weihwasser):
Usage
@Failure is intended for use only in input validation formulas.
@Failure does not terminate execution of the formula. Use @Return to force a formula to exit.
-
Wo steht denn jetzt der Code, den Du gepostet hast?
Wenn der in den Schaltflächen steht, die Da im Screenshot angezeigt werden, dann passiert GAR NIX, wenn er ein Dokument findet...
Denn @Failure ist -wie ich schon mehrfach geschrieben habe- NUR in Feldvalidierungen gültig!!!
Auszug aus der Designer- Hilfe (Die Du scheinbar noch immer meidest wie der Teufel das Weihwasser):
Usage
@Failure is intended for use only in input validation formulas.
@Failure does not terminate execution of the formula. Use @Return to force a formula to exit.
Der Code :
viw := "vdoppelpreuf";
crit := _name;
col := 4;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in kürte mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil ist Unique.") )
Steht im Querysave einer Maske mit Eingabefeldern - stand. Inzwischen steht dort:
viw := "vadminview";
outpd := _vorname + " " +_name + " " + _straße ;
crit := outpd;
col := 2;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in kürte mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil ist Unique.") )
Das stellt meinen Versuch dar auf mehrere Faktoren, als den Nachnamen zu prüfen. Klappt aber NOCHT nicht so ganz.
-
OK... ich gebs auf...
-
OK... ich gebs auf...
Okay. Tut mir leid.
-
Ignorieren wir im ersten Schritt einmal, dass es sinnvoller wäre, das Speichern zu verhindern. Wenn Deine Formel funktioniert, bekommst Du eine Fehlermeldung, dass der Schlüssel doppelt ist, das Dokument dann aber trotzdem gespeichert wird.
Was funktioniert jetzt nicht?
Wie sieht der Inhalt der ersten Spalte in Deiner Suchansicht aus?
outpd := _vorname + " " +_name + " " + _straße ;
finde ich etwas unglücklich, denn die Leerzeichen zwischen den Feldern könnten u.U. dazu führen, dass andere Dokumente passen, obwohl sie nicht identisch sind.
outpd := _vorname + "#" +_name + "#" + _straße ;
fände ich besser, müsste sich dann aber auch in der Ansicht wiederfinden
-
Also Ansicht :
(http://imageshack.us/m/695/1905/ansichtm.jpg)
Spalte 1: (_vorname + "#" +_name + "#" + _straße)
Spalte 2: (@Text (@DocumentUniqueID))
Das Querysaveevent:
viw := "vadminview";
crit := (_vorname + "#" +_name + "#" + _straße);
col := 2;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in kürte mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil ist Unique.") )
Resultat: Imom findet er garkeine Duplikate. Suche grad den Fehler. Ich schau imom nach Formatierungsfehlern von Crit oder der Ansichtsspalte.
-
Wichtig ist, dass die erste Spalte der Ansicht sortiert ist (falls das bisher noch nicht genannt wurde). Sieht ansonsten aber schon ganz gut aus (unabhängig von dem Ablauf mit der Info an den Admin und so)
-
Wichtig ist, dass die erste Spalte der Ansicht sortiert ist (falls das bisher noch nicht genannt wurde). Sieht ansonsten aber schon ganz gut aus (unabhängig von dem Ablauf mit der Info an den Admin und so)
Danke. Die Spalte war nicht sortiert. Resultat ist aber nach wie vor das selbe. Die Prompts werden später noch sinnvoll ersetzt.
-
Hm. Ich kriegs einfach nich zum laufen. Eigentlich sollte es doch?!
Querysave Maske:
viw := "vadminview";
crit := (_vorname + "#" +_name + "#" + _straße);
col := 2;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in Kürze mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil ist Unique.") )
Ansicht vadminview = 2 Spalten. Spalte 1 : (_vorname + "#" +_name + "#" + _straße) ; Spalte 2 : UniqueID
Ausgabe vom Prompt IMMER: Das Profil sei Unique.
Setzt man stattdessen dieses hier in den Querysave:
viw := "doppelpreuf";
crit := (_name);
col := 4;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in Kürze mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil ist Unique.") )
Geht es wunderbar. Allerdings nur mit dem Nachnamen. Ansicht doppelpreuf hat dabei 4 spalten wobei 1. der _name ist und 4. UniqueID.
Meine Vermutung ist nachwievor, dass irgendwas falsch formatiert ist. Entweder "crit", oder die Ansichsspalte. Hab aber schon alles an Optionen in der Ansicht gesprüft, geschaut ob versteckte Spalten existieren, ob sie sortiert ist... etc. Auch in den Spalten keine Unterschiede.
If ownlogic =< fail ; call klett (help) & call bernhard (help) ; verzweiflung. ;(
Pete
-
Wenn Du magst, stell doch mal Deine Datenbank hier rein (keine lokale Verschlüsselung, Zugriff für Default = Manager), dann schaue ich mir das gerne mal an. Anders kommen wir wohl nicht weiter, denn vom Grundsatz sieht das technisch ok aus. Falls Du die db nicht so öffentlich bereitstellen willst, schick sie mir per Mail (baleit@online.no).
-
Lass dir vor dem dblookup alle Werte mal mit @prompt anzeigen.
-
Hast Du die Ansicht in Klammern?
Dann muss es lauten:
viw := "(vadminview)";
Gruß
Bernd
-
Habe es mal nachgebaut, die Formel funktioniert (mit den Klammern). :D
Gruß
Bernd
-
@ Peter : Danke. Mail ist raus. Nicht erschrecken!!!! :)
@ klauss : Sofort. Grad Käffchen besorgen. Hatte die Werte bis dato nur in Felder ausgegeben. Waren korrekt.
@ Bernd : Nein noch nicht. Die Klammern kommen naher im Finetuning bzw. bei der nächsten Anwendung gleich von vornherein.
@ Bernds nachtrag: Was? Die Ansicht ist aber nicht in Klammern? Ähmm... :P
-
@ Bernds nachtrag: Was? Die Ansicht ist aber nicht in Klammern? Ähmm... :P
Na, ich hab diese kleine Anwendung bei mir mal schnell nachgebaut (mit einer verborgenen Ansicht in Klammern) und die Formel ins Querysave der Maske eingesetzt und sie funktioniert wie beschrieben.
Vielleicht hast Du irgendwo einen Schreipfeler oder so. ;) Lies mal exakt die Feldnamen und die Ansichtsnamen und dergleichen.
Gruß
Bernd
-
@ Peter : Danke. Mail ist raus. Nicht erschrecken!!!! :)
Prima, schaue ich mir an, wenn sie eingegangen ist (dauert hier immer etwas, vermutlich muss die noch durch den Zoll).
Erschrecken wird mich nichts, dazu habe ich schon zuviel gesehen ;)
-
@ Bernd: Also ich hab grad auchnochmal extra ne neue Datenbank angelegt. Mir 3 Feldern und ner Suchansicht + die Formel...
Geht. -_°;
Sehr ominös.
-
Korrigierte Datenbank ist unterwegs. Sie tut genau das, was Du von ihr willst (über die Sinnhaftigkeit wollten wir ja nicht diskutieren, ist schließlich eine Übungsdatenbank - HOFFENTLICH).
Gerade zu Beginn solltest Du nicht an zu vielen Schrauben gleichzeitig drehen. In Deiner Testmaske hattest Du mittlerweile das Prompt im negativen Fall durch ein Count := Count + 1 ersetzt, dass dann keine Fehlermeldung kommt, ist logisch.
Also weniger überall probieren, sondern in Ruhe und gezielt ändern ist meine Empfehlung.
-
Na, is doch supi! :D
-
Hallo Peter,
Das mit dem count tut mir leid, da war ich grad dabei was auszuprobieren, als du anbotest das File einzusenden.
Ich hoffe du hast keine geheimen Trojaner eingebaut? :D
Zurück zur Ernsthaftigkeit. In der Tat geht das eigentliche "Profil erstellen". Ich sehe aber keine Änderung.
Hast du was geänert? ^^; Wo war denn nun der Fehler?
Riesen Danke auf jeden Fall,
Peter
-
Ich habe in der Testmaske #2 v2 (so hieß die wohl?) das Querysave geändert, da war auch noch der Zugriff nur mit dem Namen auf die ...preuf-Ansicht drin (so hatte ich die Mail verstanden).
An Trojanern hatte ich gerade nichts brauchbares zur Hand ... ;)
-
Ich habe in der Testmaske #2 v2 (so hieß die wohl?) das Querysave geändert, da war auch noch der Zugriff nur mit dem Namen auf die ...preuf-Ansicht drin (so hatte ich die Mail verstanden).
An Trojanern hatte ich gerade nichts brauchbares zur Hand ... ;)
Also die Testmaske geht nicht, dafür aber die eigentliche Maske. *ratlos* Ich räum jetzt erstmal die komplette Datenbank auf und schmeiss die Code-leichen raus, die noch überall rumliegen.
-
Die Originalmaske ("Profil erstellen") funktioniert bei mir ohne Änderung. Möglicherweise hattest Du immer eine andere Maske benutzt, als Du dachtest. Aufräumen ist auf jeden Fall eine gute Idee.
-
So. Alles äufgeräumt.
Habe das Querysave nun so geändert:
@If( res != @Text( @DocumentUniqueID ) & res != "" ; save = "1" ; @Prompt([Ok];"Profil angelegt"; "Das Profil wurde gespeichert.") );
FIELD SaveOptions := SaveOptions;
@If( save = "1"; @Return(@SetField("SaveOptions";"0")); @SetField("SaveOptions";@Unavailable)); @Prompt( [Ok]; "";"Es besteht bereits ein Profil von " + _vorname + " " + _name + " in der " + _straße + ". " + "Das Profil wurde deshalb nicht gespeichert! Ein Admin wird Sie kontaktieren um das Problem zu beheben");
Jetzt werden doppelte Profile so schnell nicht mehr gespeichert.
Bedarf überarbeitung. Jetzt erstmal Feierabend.
-
http://www.herdt.de/artikel/IBM-Lotus-Notes-Domino-8-fuer-Windows-VK05736/?query=lotus&type=product&sort=0
die Grundlagen sind noch die gleichen:
http://www.herdt.de/artikel/IBM-Lotus-Notes-Domino-6-fuer-Windows-VK02951/?query=lotus&type=product&sort=0&page=2
http://www.herdt.de/artikel/IBM-Lotus-Notes-Domino-7-fuer-Windows-VK04831/?query=lotus&type=product&sort=0
http://www.herdt.de/artikel/IBM-Lotus-Notes-Domino-7-fuer-Windows-VK04832/?query=lotus&type=product&sort=0&page=2
evtl. liegen auch alte Ausgaben bei euch rum?
Zum Einstieg sind die prima, frag doch mal in eurem Betrieb, ob sie sie nicht kaufen können.
Für den Betrieb ist das eine Mini-Ausgabe an Geld (wenn die Teile zu teuer sind, würde ich mir einen anderen Betrieb suchen) und du belästigst nicht die anderen Mitarbeiter.
-
Hallo!
Danke für die Links. Ich habe bereits ein paar ältere Versionen der Herdt-Bücher von Wolfgang Thomas Schulte abstauben können. Wenn ich diese gesichtet und konsumiert habe, komme ich auf die neueren zurück - sofern es sich lohnt. Muss dann Mal wen ausquetschen, der die alten und neuen gelesen hat und die Unterschiede kennt oder das Sichtgerät mit zwei OO bemühen wo sich die Ausgaben prägnant unterscheiden.
Pete
-
Hallo!
Ich habe heute versucht die Speicherunterbindung in meine Prüfung auf Doppelte Profile
zu implementieren - Ohne Erfolg mit Erfolg mit Teilerfolg
Ausgangsbasis war:
viw := "vadminview";
crit := (_vorname + "#" +_name + "#" + _straße);
col := 2;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Bitte eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in kürte mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil ist Unique.") )
Funktioniert auch einwandfrei. Daraus habe ich gemacht:
FIELD SaveOptions := "0";
viw := "vadminview";
crit := (_vorname + "#" +_name + "#" + _straße);
col := 2;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in Kürze mit Ihnen in Verbindung setzen.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil wurde gespeichert.") );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; Allowsave ="0" ; Allowsave = "1");
@If( Allowsave = "0"; @Return(@SetField("SaveOptions";"0")); @SetField("SaveOptions"; "1"))
Die Idee war, dass grundsätzlich Speichern nicht erlaubt ist. Wenn doppelte Dokumente vorhanden sind, soll das auch so bleiben, wenn das Profil unique ist, wird Allowsave auf 1 gesetzt und damit dann SaveOptions auf "1" - was das Speichern ermöglichen sollte. Das Resultat ist, dass er zwar erkennt, wenn ein Profil doppelt ist oder nicht, aber generell kein Speichern mehr möglich ist ( vermutlich weil das SaveOption von "0" hinterher nicht mehr auf "1" umgesetzt wird.
Ps.: Sollte ich einen neuen Thread aufmachen, weil das ganze schon recht weit weg von @If / @Contains ist?
Peter
EDIT: Hab den Fehler nicht direkt gefunden. Imom können garkeine Dokus mehr gespeichert werden.
-
Sollte ich einen neuen Thread aufmachen ...
Nein, Du sollst Dir endlich in diesem Thread durchlesen, was Dir schon mehrere Leute teilweise wiederum mehrfach geschrieben haben!
Bernhard
-
Hallöle Bernhard!
Von dem "endlich" einmal abgesehen, habe ich mir "abermals" den Thread gründlich durchgelesen. Selbst die Stellen die noch mit @If zu tun hatten.
Ich sehe / verstehe nicht, wo ich etwas ignoriert / überlesen hätte, dass mir aus meiner momentane Miesere helfen könnte. Naja ausser der Geschichte mit der "Feldvalidierung" über die sich Tode aufgeregt hat. Meinst du das? Wenn ja, dann wäre ich dankbar, wenn mich eben jemand mit einem gezielten Tritt in die richtige Richtung in der Hilfe befördert. Feldvalidierung sagt mir leider garnix.
Peter
-
Eingabevalidierung bzw. input validation.
-
Merci
-
Ich habe lange überlegt - jetzt mische ich mich doch ein ;-)
@Peter Mewes
Zunächst einmal finde ich es lobenswert, dass du nicht einfach aufgibst - man lernt schließlich nie aus und jeder hat mal klein angefangen.
Wenn ich deine Anforderung richtig verstehe, geht es doch darum, zu prüfen, ob ein Dokument mit bestimmten Angaben (Vorname, Nachname und Straße) bereits exisitiert.
Bevor du weiter machst, überleg dir bitte, wie deine Anwendung eingesetzt werden soll und wer sie später nutzt.
1. Soll die Anwendung in einer replizierten Umgebung (lokal und mehrere Server) eingesetzt werden?
Wenn ja, vergiss es! Warum? Weil auf einer Replik deiner Anwendung (noch) nicht alle Dokumente vorhanden sein müssen und deine Prüfung deshalb nicht immer korrekt funktioniert.
Wenn nein, vergiss es auch! Warum? Weil du nicht gewährleisten kannst, dass deine Anwendung auf Dauer nur auf einem zentralen Server läuft.
2. Wenn du trotzdem weitermachst, solltest du bei deinen Prüfungen vielleicht auch berücksichtigen, dass
"Reiner#Wahnsinn#Hauptstraße 100"
ein anderer ist als
"Reiner#Wahnsinn#Hauptstrasse 100"
oder
"Reiner#Wahnsinn#Hauptstr. 100"
oder schreibt er sich vielleicht sogar
"Rainer#Wahnsinn#Hauptstraße 100"
oder vielleicht gibt ein User sogar die Hausnummer falsch an
"Reiner#Wahnsinn#Hauptstraße 1oo"
oder...
Jetzt könntest du auf die Idee kommen und das Ganze mit einer eindeutigen Personalnummer machen, aber da kommt wieder 1. zum tragen. (Zum Thema "Eindeutigkeit" gibt es in diesem Forum eine Menge zu lesen.)
Du sieht also, dass deine Überlegungen zwar richtig, aber eben so gut wie zum Scheitern verurteilt sind, weil Notes eben keine relationelle Datenbank ist.
Fazit: Ok zum lernen und üben, aber eben nicht für den produktiven Einsatz.
Lass dich aber trotzdem nicht entmutigen!
Hier vielleicht noch ein nützlicher Link zum Thema SaveOptions http://atnotes.de/index.php/topic,16581.0.html
Gruß
Stefan
-
@Stefan:
Zu
1. Soll die Anwendung in einer replizierten Umgebung (lokal und mehrere Server) eingesetzt werden?
Wenn ja, vergiss es! Warum? Weil auf einer Replik deiner Anwendung (noch) nicht alle Dokumente vorhanden sein müssen und deine Prüfung deshalb nicht immer korrekt funktioniert.
Wenn nein, vergiss es auch! Warum? Weil du nicht gewährleisten kannst, dass deine Anwendung auf Dauer nur auf einem zentralen Server läuft.
Damit könnte ich als Programmierer und Anforderer leben. Im Umkehrschluß würde das ja bedeuten, dass ich in Notes niemals einen Konfliktcheck oder dergleichen machen soll, weil ja irgendwann mal auf einem anderen Server repliziert werden KÖNNTE.
@Peter Mewes
Zur Beruhigung: Ich mache solche Konfliktchecks auch, sogar in verteilten Datenbanken ;-)
Um Tippfehler oder kleinere Abweichungen bei der Eingabe ebenfalls zu berücksichtigen, nutze ich die Funktion @Soundex (vielleicht wurde in diesem Thread bereits darauf hingewiesen, ich habe allerdings nicht alle Beiträge gelesen...)
Zum Thema Saveoptions: Anstatt das auf "1" oder 1 zu setzen, solltest Du das auf @Unavailable oder "" setzen.
Andreas
-
Wobei ich das Thema SaveOptions hier heraushalten würde, weil es mit diesem Anliegen von Peter nix zu tun hat (es sei denn, man will die Sache verkomplizieren).
Bernhard
-
@Stefan:
Zu
1. Soll die Anwendung in einer replizierten Umgebung (lokal und mehrere Server) eingesetzt werden?
Wenn ja, vergiss es! Warum? Weil auf einer Replik deiner Anwendung (noch) nicht alle Dokumente vorhanden sein müssen und deine Prüfung deshalb nicht immer korrekt funktioniert.
Wenn nein, vergiss es auch! Warum? Weil du nicht gewährleisten kannst, dass deine Anwendung auf Dauer nur auf einem zentralen Server läuft.
Damit könnte ich als Programmierer und Anforderer leben. Im Umkehrschluß würde das ja bedeuten, dass ich in Notes niemals einen Konfliktcheck oder dergleichen machen soll, weil ja irgendwann mal auf einem anderen Server repliziert werden KÖNNTE.
Ok, "vergiss es" war vielleicht etwas too much - ich wollte Peter aber auf mögliche Fehlerquellen aufmerksam machen.
Stefan
-
@Peter Mewes:
Ich pflichte Stefan bei: Die Eingaben der Anwender sind einfach nicht vorhersehbar und kaum abzufangen. Wir pflegen in einer Anwendung ca. 30.000 Kundendaten und bislang scheiterte jeder Versuch, Doppelanlagen zu vermeiden. Zwei Ansätze haben die Situation stark verbessert:
1. Anwender in den Suchfunktionen intensiv schulen. Selbst langjährigen Anwendern kann man da immer Neues zeigen
2. Eigene Suchmasken: Mit Postleitzahl und dem Anfang der Strasse verengt sich eine Auswahl so stark, dass die Mitarbeiter nur noch eine kurze Auswahl möglicher bestehender Kunden/Ansprechpartner zur Auswahl bekommen. Wenn da der neue Partner nicht gefunden wird, dann wird er angelegt.
Kleiner Trost: Auch die Post vertreibt eine Software, um Massenmailings vorbereiten zu können (Infopost-Manager). Die Doublettenprüfung dort ist auch nicht das "Gelbe" (nun auch noch Kalauer in diesem Thread).
Wer immer die Idee hatte, dass Du so eine Doublettenprüfung versuchen solltest, hat Dich in die Irre geführt und uns - Dank Deiner lobenswerten Hartnäckigkeit - einen amüsanten Thread beschert.
Vielleicht haust Du nun aber mal in Dein erstes Posting den "Daumen hoch" rein?
-
Hallo Cebolina, Hallo Glombi.
Das Problem mit der lokalen oder Serverseitigen-Geschichte schiebe ich schon seit Anfang an vor
mir her. Imom ist alles noch lokal. Zum testen ausreichend. Weil ich aber die Tage mit Autoren / Leser-Feldern und allgemein der ACL arbeiten will, wird das Programm vermutlich "aus Jux" in unserer DEV-Umgebung repliziert werden.
@Soundex ist mir neu. Scheint sinnvoll - weiß nur noch nicht direkt wofür. Setze ich hinten auf die Liste. Inwiefern hilft mir Soundex letztlich dabei "Rainer" von "Reiner" zu unterscheiden, bzw. inwiefern will ich das? Rainer und Reiner sind für mich 2 verschiedene Personen. :P
Wobei ich das Thema SaveOptions hier heraushalten würde, weil es mit diesem Anliegen von Peter nix zu tun hat (es sei denn, man will die Sache verkomplizieren).
Leider ist die SaveOption bzw allgemein das verhindern von Speichern genau der Punkt, wo ich grad ankomme. ;)
Zum Thema Saveoptions: Anstatt das auf "1" oder 1 zu setzen, solltest Du das auf @Unavailable oder "" setzen.
Hatte ich am Anfang so. Hatte den Code aus dem Post, auf den du grad verwiesen hast, abgekupfert. Als er aber mit Unavaible nicht ging, in der Hilfe stand, dass Unavaible = Deletefield ist und ich nicht wusste, was der Defaultwert von SaveOptions ist, habe ich es mit "1" und 1 probiert. Wie interpretiert Notes den Sachverhalt wenn ich den Wert auf "" setze? Als "SaveOptions 0?
Bin grad' dabei mir zu überlegen, wie ich das ganze sinnvoller aufbauen kann. Ich möchte ja den Leuten mit der Feldvalidierungskritik entgegen kommen. Das einzige was mir da aber grad einfällt wäre, die Formel als Eingabevalidierung für die Felder Name, Vorname, Straße zu nehmen und eine Variable mit "1" / "0" zu erzeugen, die dann im Querysave via LS ein continue = false triggert - oder auch nicht.
Habe bei der unten geposteten Variante aber immernoch Verständnisprobleme, da die Formel zwar geht, um zu prüfen ob Profile doppelt existieren, aber sobald ich die selbe Formel nehme um den "saver" auf 1 oder 0 zu setzen, versagt sie. Laut einem Ausgabe Prompt zumindest, da der Saver immer auf "" bleibt und die SaveOptions auf "", egal ob Profil doppelt existiert oder nicht. Wäre nett wenn das jemand enträtseln könnte. Randinfo: Auf der Maske befindet sich ein Feld SaveOptions. Wert: "". Ist der Wert bspw. "1", dann gibt der Prompt am Ende diesen Wert aus. Ergo: Weder der Zugriff auf die saver-Variable, noch auf die SaveOptions via SetField ziehen. Syntax-, oder Denkfehler?
saver :=saver;
viw := "vadminview";
crit := (_vorname + "#" +_name + "#" + _straße);
col := 2;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in Kürze mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"Profil erstellt"; "Das Profil wurde gespeichert.") );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @SetField (saver ; "1"); @SetField (saver ; "0" ));
@If ( saver = "0" ;@SetField( SaveOptions ; "0") ; @SetField ( SaveOptions ; "1"));
@Prompt([ok]; Blah ; "Hallo, der Saver ist auf " + saver + " . Die SaveOption ist auf " + SaveOptions +". ")
Ps.: Ich habe in der Hilfe nichts zum Thema @DaumenHoch gefunden!!!
Pps.: Ich würd nen Daumen hoch geben, auch zwei, aber ich finde den Daumen wirklich nicht. ^^;
-
Wirklich allerletzter Versuch: Du sollst Deinen Code in die Eingabevalidierung packen und mit @Failure arbeiten!
Bernhard
-
Deine Formel habe ich mir nicht genauer angeschaut, da kriege ich Augenkrebs (wg. der Farbe), habe nur soviel gesehen, dass ich mich wundere, wozu Du ein Feld saver ins Dokument schreibst, anhand dessen Du SaveOptions setzt.
Wenn Du sowieso im QuerySave mit Script arbeiten willst, warum machst Du dann nicht gleich Deine Abfrage in Script (hatte das bisher ausgeschlossen, damit Du nicht an zu vielen Hochzeiten gleichzeitig tanzt)?
Zum Thema Eindeutigkeit: Vorname, Name und Straße sind (unabhängig von der Problematik mit der Replikation) natürlich keine eindeutigen Schlüssel. Paul Meier in der Haupstraße 1 gibt es sicherlich nicht nur einmal in Deutschland. EMailadresse ist da schon eindeutiger, aber das ist nur ein logisches Thema und hat nichts mit der von Dir zu erlernenden Technik zu tun.
Zum Thema Leserfelder: Wenn Du die Dokumente mit Leserfeldern versiehst, erfolgt die Prüfung auf Eindeutigkeit nur gegen die Dokumente, die der Benutzer lesen darf, außer Du lässt diese Prüfung per agent.RunOnServer von einem höher berechtigten User ausführen, aber dann kommst Du thematisch noch tiefer, das wird Deinen Blick auf die m.E. viel wichtigeren Basics noch mehr stören.
-
Ad @SetField (saver ...):
Was steht denn in der Variablen saver drin? Nix? Na, dann sollte alles klar sein ...
Bernhard
-
Peter Mewes,
nimm doch bitte Deine Formel:
viw := "vadminview";
crit := (_vorname + "#" +_name + "#" + _straße);
col := 2;
lkp := @DbLookup( "" : "NoCache" ; "" ; viw ; crit ; col );
res := @If( @IsError( lkp ) ; "" ; lkp );
@If( res != @Text( @DocumentUniqueID ) & res != "" ; @Prompt([Ok];"¿Profil bereits vorhanden"; "Das Profil ist bereits vorhanden. Bitte eine Nachricht wurde an den zuständigen Admin versendet. Er wird sich in kürte mit Ihnen in Verbindung setzen. NICHT Unique.") ; @Prompt([Ok];"¿Profil nicht vorhanden"; "Das Profil ist Unique.") )
und setze sie in die "Eingabevalidierung" des letzten Eingabefeldes. Ersetze dann das @Prompt mit dem @Failure bzw. @Success.
In etwa so:
@If(
res != @Text( @DocumentUniqueID ) & res != "" ;
@Failure( "Das Profil ist bereits vorhanden.") ;
@Success )
@Failure in der Eingabevalidierung promptet Dir die eingegebene Meldung und verhindert das Speichern wirklich ganz ordentlich.
-
Was heisst "ganz ordentlich"? @Failure und das Speichern ist unmöglich!
Bernhard
-
@bernhard
Ja klar ... sollte ironisch sein.
;D
-
@VB3Bernd und Bernhard: Okay. @Failure hat geholfen. DANKE.
Kann mir jetzt noch jemand erklären, warum das Konstrukt im Querysave so nicht ging? Wäre mir wichtig zwecks lernen aus Fehlern und so...
@Bernhard :knuddel: : Ad @SetField (saver ...):
Was steht denn in der Variablen saver drin? Nix? Na, dann sollte alles klar sein ...
Sollte nachdem SetField gelaufen ist nicht der Wert drinne stehen, auf den SetField es setzt?
@Peter: Ja ich gebe zu das mit dem saver war ein lausiger Workaround. War eigentlich nur, weil ich mir mit den Ausgabewerten von @Unavaible nicht sicher war und fälschlicherweise kurz angenommen hatte, es wäre einfacher und sicherer das ganze ausserhalb der IF anweisung zu machen, weil ich noch nicht sonderlich gut darin bin, Syntaxe sinnvoll zu verknüpfen.
Warum ich nich gleich in Script gemacht habe... Naja zum einen las ich, dass Querysave continue = false eine zweitklassige Lösung sei und zudem gehe ich (noch) davon aus, dass Formula einfacher zu meistern ist am Anfang.
-
QuerySave wird ausgelöst beim Speichern (im Grunde kurz vor dem Speichern) des Dokumentes. Dein Code enthält aber nur Prompts bzw. Dinge, die in diesem Zusammenhang zu spät sind oder im falschen Syntax geschrieben wurden.
Schau Dir bitte genau die Syntax von @setfield an. An der ersten Stelle nach der Klammer steht ein Feldname (als String). Wenn Du also einen festverdrahteten Feldnamen angeben willst, musst Du diesen in Anführungsstriche setzen. So wie Du es geschrieben hast: @setfield(saver ; ...) sucht er eine Variable in Deiner Formel die den Feldnamen enthalten soll ... die gibts aber nicht.
Also nochmal die Hilfe zu Rate ziehen.
-
Fröhliche 16.00 Uhr wünsche ich! Mit der Begründung kann ich vorerst leben. Hatte insgeheim sowas ähnliches vermutet. Habe den Tread auf Daumen hoch gemacht.
Großen Dank auch nochmal an alle, habe mir einiges an Strukturierung und Herangehensweisen abgeschaut.
Pete
-
Warum ich nich gleich in Script gemacht habe... Naja zum einen las ich, dass Querysave continue = false eine zweitklassige Lösung sei und zudem gehe ich (noch) davon aus, dass Formula einfacher zu meistern ist am Anfang.
Dass Du Dich zu Beginn auf die Formeln konzentrierst, ist m.E. absolut richtig, aber dass Continue = False eine zweitklassige Lösung sei, finde ich äußerst interessant. Die Quelle würde mich interessieren.
Seit 1999 (damals noch unter 4.5 und OS/2) validiere ich ausschließlich per Script im Querysave, habe dann eine Box, in der alle gesammelten Fehler - auch in verschiedenen Teilmasken gerechnet - des Dokuments aufgelistet sind, und verhindere das Speichern mit Continue = False.
-
Hi Peter,
habe gerade nochmal dannach gesucht, aber nicht wieder gefunden. War glaube ich im Domino-Forum. Ungefährer Wortlaut: Mit Continue = False im Querysave kann man nicht restlos verhindern, dass User Dokumente Ändern / Speichern.
-
@Soundex ist mir neu. Scheint sinnvoll - weiß nur noch nicht direkt wofür. Setze ich hinten auf die Liste. Inwiefern hilft mir Soundex letztlich dabei "Rainer" von "Reiner" zu unterscheiden, bzw. inwiefern will ich das? Rainer und Reiner sind für mich 2 verschiedene Personen. :P
Ok, ich wusste ja nicht, dass Du NUR die Vornamen prüfst. Dann hätte ich das naürlich nicht als Tipp geschrieben.
Wünsche Dir weiterhin viel Spß am Herumwurschteln! :P
-
Nur um nochmal den Klugscheisser- Modus anuwerfen: dass das Querysave der falsche Ort für deine Formel ist, wurde Dir gleich zu Beginn des Threads mehrfach gesagt.
Nun zu der (wahren) Behauptung, Continue=False im Querysave sei nicht 100% sicher:
Leider ist in jedem Client der Script- Debugger mit dabei. Wenn man den über Werkzeuge einschaltet, und einfach die Script- Abarbeitug abbricht, bevor continue=false gesetzt wird, dann wird das Dokument ganz normal gespeichert. Das selbe gilt übrigens auch für Queryopen, QueryModeChange ( wird gerne verwendet um das Bearbwiten zu verhindern) oder im QueryDocumentDelete.
Das setzt aber eine gewisse Kenntnis der materie und vor allem Absicht voraus, weshalb man das im normalfall ignorieren kann.
Und über verstecken der Gestaltung oder auslagern des scripts in lss dateien kann man auch dieses Hintertürchen schliessen, aber fängt sich dafür weitere Kröten ein... aber das ist jetzt alles schon zu weit off topic...
-
Ich halte ein verborgenes Design schon allein aus Investitionsschutz für ein absolutes Muss. Bei uns kann kein Mitarbeiter außerhalb der Entwicklung oder Administration eine offene Kopie einer Datenbank zum nächsten Arbeitgeber mitnehmen. Debuggen und Scripte abbrechen fällt damit auch aus, genauso wie Entwickeln in der Produktivumgebung.
Irgendwelche Kröten sind mir dabei noch nicht begegnet ...