Autor Thema: Lotusscript Optimierung  (Gelesen 8870 mal)

Offline schroederk

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.924
  • Geschlecht: Männlich
  • Ich liebe dieses Forum!
Lotusscript Optimierung
« am: 09.11.11 - 08:31:37 »
Hallo zusammen,

ich würde gerne von Euch über den folgende Code schauen lassen. Dieser wird über Web aufgerufen und soll aus dem Raum-und Reservierungsplaner mit angegebenem Datum und Raumname die vorhandenen Termine auflisten.
Der Code hat sicher noch Optimierungspotential und ich würde gerne konstruktive Kritik erfahren, wie ich was besser machen kann.
Die Ausgabe ist im Moment noch sehr spartanisch, ich weiß aber auch noch nicht, ob ich die Werte Komma-separiert übertrage und vom Web aus die Aufbereitung vornehme oder ob ich das schon im Script machen soll.

Zitat
Option Public
Option Declare

Sub Initialize
   Dim s As New NotesSession
   Dim db As NotesDatabase
   Dim view As NotesView
   Dim doc As NotesDocument
   Dim vc As NotesViewEntryCollection
   Dim str_datum, str_aktdatum, str_raumname As String
   Dim col As NotesDocumentCollection
   Dim arg As String, p1 As Long
   Dim argarray As Variant
   Dim todaysdate As New NotesDateTime("Today")
   Dim startdatum, enddatum, raumname As String
   Dim teilnehmer As String
   Dim besprechtitel As String

   str_aktdatum = todaysdate.DateOnly

   On Error GoTo processError

   arg = s.DocumentContext.Query_String(0)
   p1 = InStr(arg, "&")
   arg = LCase(Mid$(arg, p1 + 1))                     ' alle Parameter aus der URL extrahieren
   argarray = Evaluate({@Explode("} & arg & {"; "&")})      ' jeden Parameter trennen und in Array speichern

   str_datum = argarray(0)
   str_raumname = argarray(1)
   If str_datum = "" Then                           ' Wenn kein Datum angegeben wurde, dann aktuelles Datum wählen
      str_datum = str_aktdatum
   End if
 
   Set db = s.GetDatabase("MAILSERVER/SRV/Group", "Besprech.nsf", False)
   If Not db.IsOpen Then Call db.Open("", "")

   Set view = db.GetView("Reservierungen nach Datum")         ' Alle Reservierungen nach Datum
   Set doc = view.GetFirstDocument

   While Not(doc Is Nothing)                           ' Alle Dokumente in Ansicht abarbeiten
      startdatum = Left(doc.GetItemValue("StartDate")(0),10)
      enddatum = Left(doc.GetItemValue("EndDate")(0),10)
      raumname = doc.GetItemValue("Room")(0)
      If raumname <> "" then
         raumname = Left(raumname,InStr(raumname,"/")-1)
      End if
      teilnehmer = doc.GetItemValue("Capacity")(0)
      besprechtitel = doc.GetItemValue("Purpose")(0)
      If str_datum = startdatum Or str_datum = enddatum Then
         If str_raumname = "" Or str_raumname = LCase(raumname) Then
            Print startdatum, enddatum, raumname, teilnehmer, besprechtitel, "<br>"
         End if
      End If
      Set doc = view.GetNextDocument(doc)
   Wend   
   Exit Sub
processError:
   Print "Fehler " & Str(Err) & ": " & Error$ & " in Zeile " & Str(Erl)
   Exit Sub    
End Sub
Ich wäre ja gerne weniger egoistisch, aber was hab ich davon?

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #1 am: 09.11.11 - 09:08:45 »
Option Public
Option Declare

Sub Initialize
   Dim s As New NotesSession
   Dim db As NotesDatabase
   Dim view As NotesView
   Dim doc As NotesDocument
   Dim vc As NotesViewEntryCollection *
   Dim str_datum, str_aktdatum, str_raumname As String **
   Dim col As NotesDocumentCollection *
   Dim arg As String, p1 As Long
   Dim argarray As Variant
   Dim todaysdate As New NotesDateTime("Today")
   Dim startdatum, enddatum, raumname As String **
   Dim teilnehmer As String
   Dim besprechtitel As String

* nicht verwendete Variablen solltest Du nicht definieren
** diese Deklarationen sind m.W. nicht korrekt, da die ersten Variablen Variants werden, und keine Strings


   str_aktdatum = todaysdate.DateOnly

   On Error GoTo processError

   arg = s.DocumentContext.Query_String(0)
   p1 = InStr(arg, "&")
   arg = LCase(Mid$(arg, p1 + 1))                     ' alle Parameter aus der URL extrahieren
   argarray = Evaluate({@Explode("} & arg & {"; "&")})      ' jeden Parameter trennen und in Array speichern

   Hier könntest Du auch den Script-Befehl Split verwenden

   str_datum = argarray(0)
   str_raumname = argarray(1)
   Du solltest vorher prüfen, ob es argarray (1) gibt (z.B. If Ubound (argarray) > 0 Then ...)
   If str_datum = "" Then                           ' Wenn kein Datum angegeben wurde, dann aktuelles Datum wählen
      str_datum = str_aktdatum
   End if
 
   Set db = s.GetDatabase("MAILSERVER/SRV/Group", "Besprech.nsf", False)
Server- und Dateinamen solltest Du nicht hart codieren, und wenn Du keine Möglichkeit siehst, diese Information irgendwo zu hinterlegen oder automatisch zu ermitteln (z.B. den Server aus der aktuellen Datenbank), dann sollte die Definition in Konstanten ganz oben im Script erfolgen, damit Du die später schnell findest und ändern kannst
Const server = "Mailserver/...."

   If Not db.IsOpen Then Call db.Open("", "")

   Set view = db.GetView("Reservierungen nach Datum")         ' Alle Reservierungen nach Datum
   Set doc = view.GetFirstDocument

   While Not(doc Is Nothing)                           ' Alle Dokumente in Ansicht abarbeiten
      startdatum = Left(doc.GetItemValue("StartDate")(0),10)
      enddatum = Left(doc.GetItemValue("EndDate")(0),10)
      raumname = doc.GetItemValue("Room")(0)
      If raumname <> "" then
         raumname = Left(raumname,InStr(raumname,"/")-1)
Das kracht, wenn Raumname kein "/" enthält, sicherer ist
         raumname = Left(raumname,InStr(raumname & "/","/")-1)

      End if
      teilnehmer = doc.GetItemValue("Capacity")(0)
      besprechtitel = doc.GetItemValue("Purpose")(0)
      If str_datum = startdatum Or str_datum = enddatum Then
         If str_raumname = "" Or str_raumname = LCase(raumname) Then
            Print startdatum, enddatum, raumname, teilnehmer, besprechtitel, "<br>"
         End if
      End If
      Set doc = view.GetNextDocument(doc)
   Wend   
   Exit Sub
processError:
   Print "Fehler " & Str(Err) & ": " & Error$ & " in Zeile " & Str(Erl)
   Exit Sub   
End Sub

Deine Suchlogik solltest Du überprüfen. Wenn Du einen Raum hast, der vom 01.12. bis zum 03.12. gebucht ist, und Du suchst nun nach diesem Raum am 02.12., wirst Du ihn so nicht finden, da Du nur Start- und Enddatum vergleichst. Auch das Durchkämmen der ganzen Ansicht wird mit der Dauer immer langsamer werden, wenn alte Einträge stehen bleiben. Ich würde da lieber ein db.Search nehmen. Da könntest Du
1. nur nach dem Raum suchen
2. nach Buchungen, deren Anfangsdatum <= dem Suchdatum ist und deren Enddatum >= dem Suchdatum ist (mehrtägige Buchungen hast Du anscheinend nicht in Deiner Suchabfrage)
Als Ergebnis hast Du gleich alle relevanten Dokumente. Die musst Du dann nur noch sortieren

Offline schroederk

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.924
  • Geschlecht: Männlich
  • Ich liebe dieses Forum!
Re: Lotusscript Optimierung
« Antwort #2 am: 09.11.11 - 09:48:29 »
Vielen Dank für die Prüfung und die konstruktiven Anmerkungen.
Ich werde sie beherzigen.

Bei den Variablen-Deklarationen verhau ich mich immer wieder, dank anderer Programmiersprachen.

Bei unseren Besprechungen haben wir bisher noch keine Reservierung gehabt, die länger als 1 Tag gedauert hat. Aber sicher hast Du recht, dass hier zukünftige Eventualitäten gleich berücksichtigt werden sollte.

Ich werde mir die Suche mit db.Search mal anschauen. Ist damit sicher besser umgesetzt.
Ich wäre ja gerne weniger egoistisch, aber was hab ich davon?

Offline mezz

  • Junior Mitglied
  • **
  • Beiträge: 69
Re: Lotusscript Optimierung
« Antwort #3 am: 09.11.11 - 10:01:14 »
Code
   arg = s.DocumentContext.Query_String(0)
   p1 = InStr(arg, "&")
   arg = LCase(Mid$(arg, p1 + 1))                     ' alle Parameter aus der URL extrahieren
   argarray = Evaluate({@Explode("} & arg & {"; "&")})      ' jeden Parameter trennen und in Array speichern

Dazu noch eine Anmerkung: Dieses oder ähnliche Konstrukte sieht man leider häufiger, der QueryString wird hier ungefiltert in ein Evaluate übernommen dies kann im ungünstigsten Fall dazu führen das in den QueryString eingehängter Code (Formelsprache) im Kontext des Programmes/Agenten ausgeführt wird.
Ich empfehle mal etwas Lektüre zum Thema Sicherheit in Webanwendungen. :)

perl -e 's,,q#$:%*?:!&=(:!>@.#.$/,e;y;!-./:-@[-]{-~; a-uJP;;print;'

Offline schroederk

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.924
  • Geschlecht: Männlich
  • Ich liebe dieses Forum!
Re: Lotusscript Optimierung
« Antwort #4 am: 09.11.11 - 10:54:47 »
Danke für den Hinweis, mezz. Da der Agent nicht vom Benutzer sondern vom Webserver aufgerufen wird, ist da die Manipulationsmöglichkeit eingeschränkt. Zudem habe ich jetzt auf die Split-Funktion umgebaut, insofern konnte ich auf das Evaluate verzichten. (Bin ich eh kein Fan von)

Die Suche mit db.Search bereitet mir noch ein paar Problemchen. Die Hilfe ist dabei etwas verwirrend und die gefundenden Beispiele im Internet halfen nicht wirklich weiter.
In den Beispielen wird immer innerhalb einer Form gesucht. Kann ich anstelle der Form auch nach einer View suchen?

Also etwa sowas:
searchFormula = {View = "Reservierungen nach Datum" & Left(StartDate,10) <= str_datum & Left(EndDate,10) >= str_datum}

Ist die Suche wirklich schneller oder wäre es nur schneller wenn man FTSearch verwendet. (Vorausgesetzt, dass der Fulltext Index erstellt wurde, was ja nicht das Problem darstellen sollte)
Ich wäre ja gerne weniger egoistisch, aber was hab ich davon?

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #5 am: 09.11.11 - 10:58:10 »
Warum sollte man das über eine View machen (was bei dbSearch eh nicht gehen kann)?

Wenn Dir aber die Vorauswahl einer View gefällt, kannst Du die SELECT-Formel der View als Teil Deines dbSearch-Querystrings mit einbauen.

Bernhard

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #6 am: 09.11.11 - 12:17:43 »
searchFormula = {View = "Reservierungen nach Datum" & Left(StartDate,10) <= str_datum & Left(EndDate,10) >= str_datum}

Ein db.Search sucht nur Dokumente. Wenn Du alle Dokumente einer Ansicht haben willst, übernimmst Du die Selektionsformel der Ansicht.

Beispiel:

Du hast eine Ansicht "Reservierungen" mit der Selectionsformel: Form = "reservierung"

Unter Verwendung eines db.Search ({Form = "reservierung"}, Nothing, 0) bekommst Du genau die gleichen Dokumente in die NotesDocumentCollection, die auch in der Ansicht sind.

Verstehe db.Search als eine temporäre Ansicht, die Du zur Laufzeit generierst, nur dass das Ergebnis eben eine NotesDocumentCollection ist, dann ist es ganz einfach, damit zu arbeiten. Du hast dabei den Vorteil, dass Du die Selektionsformel dynamisch errechnen kannst, was in einer Ansicht nicht geht.

Ich arbeite sehr viel mit db.Search und behaupte, dass die Performance nicht wirklich schlecht ist. Dadurch erspare ich mir sehr viele Ansichten, die die Datenbank auch nicht gerade schneller machen würden. Bei Zugriff auf fremde Datenbanken habe ich u.U. auch keine Möglichkeit (oder will es auch nicht), eine benötigte Ansicht einzubauen. Defekte Indizes kenne ich dabei auch nicht.

Wir hatten neulich hier im Forum über db.Search diskutiert, vielleicht findest Du da auch noch ein paar hilfreiche Hinweise.

Nachtrag: In Deiner angegebenen Suchformel vergleichst Du Datum auf Textbasis, das wird nicht klappen

"01.01.2012" ist kleiner als "02.01.2011", aber nur als Text, nicht als Datum
« Letzte Änderung: 09.11.11 - 12:21:24 von Peter Klett »

Offline schroederk

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.924
  • Geschlecht: Männlich
  • Ich liebe dieses Forum!
Re: Lotusscript Optimierung
« Antwort #7 am: 09.11.11 - 14:03:57 »
Von diesen Date-Operationen bekomm ich irgendwie immer Kopfschmerzen  :-\

In str_aktdatum steht "09.11.2011", in StartDate steht bspw. "09.11.2011 08:00:00 CET"

Ich habe den Quellcode jetzt folgendermaßen ergänzt:

Dim comparedate As Variant
Set comparedate = CDat(str_aktdatum)
searchFormula = {Form = "Reservierungen nach Datum" & StartDate <= comparedate & EndDate >= comparedate}

Die Folge ist ein Type Mismatch (wobei die angegeben Zeile bei mir eine Leerzeile ist  ???)

Muss ich erst das "09.11.2011" in ein "11/09/2011" umwandeln, damit CDat funktioniert oder liegt der Fehler jetzt beim Vergleich Startdate <= comparedate?
Ich wäre ja gerne weniger egoistisch, aber was hab ich davon?

Offline ascabg

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.697
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #8 am: 09.11.11 - 14:10:06 »
Hallo,

Kleine Frage.

Code
Set comparedate = CDat(str_aktdatum)
Warum machst Du hier ein Set?

Es reicht doch comparedate = cdat(str_aktdatum)


Andreas

Offline schroederk

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.924
  • Geschlecht: Männlich
  • Ich liebe dieses Forum!
Re: Lotusscript Optimierung
« Antwort #9 am: 09.11.11 - 14:18:35 »
Hmm, weil er mir beim Schreiben gemeckert hatte, ich müsste ein 'Set' davorsetzen. Jetzt hab ich es wieder weggenommen, keine Fehlermeldung mehr.
Allerdings auch noch das Problem, dass die searchFormula offenbar keine Elemente findet.
Ich befürchte, ich vergleiche noch immer Äpfel mit Birnen  :-:
Ich wäre ja gerne weniger egoistisch, aber was hab ich davon?

Offline ascabg

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.697
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #10 am: 09.11.11 - 14:23:46 »
Muesste die searchFormula nicht so aussehen.

searchFormula = {Form = "Reservierungen nach Datum" & StartDate <= } & comparedate & { EndDate >= } & comparedate

comparedate ist doch Deine Variable und kein Feld der betreffenden Form.


Andreas

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #11 am: 09.11.11 - 14:24:21 »
Gibt es denn überhaupt eine Maske namens "Reservierungen nach Datum"? Das wäre ein schräger Maskenname ...

Bernhard

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #12 am: 09.11.11 - 14:26:51 »
Muesste die searchFormula nicht so aussehen.

searchFormula = {Form = "Reservierungen nach Datum" & StartDate <= } & comparedate & { EndDate >= } & comparedate

comparedate ist doch Deine Variable und kein Feld der betreffenden Form.


Andreas

Das knallt auch, Andreas - eine DT-Variable kannst Du nicht mit einem String verhereiraten.

Statt comparedate müsste ein Konstrukt wie @Date (....) gebildet werden.

Bernhard

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #13 am: 09.11.11 - 14:38:12 »
searchFormula = {Form = "Reservierungen nach Datum" & StartDate <= @TextToTime ("} & comparedate & {") &  EndDate >= @TextToTime ("} & comparedate & {")}

wäre eine Möglichkeit, wobei das @TextToTime das Risiko birgt, bei abweichenden Ländereinstellungen falsche Ergebnisse zu liefern. Da wird dann ein @TextToTime ("04.01.2011") plötzlich zum ersten April.

Ganz sauber bekommst Du es hin, wenn Du die Datumsangaben in ein Textformat wie JJJJMMNN umwandelst, das kannst Du dann auch als Text mit <= korrekt vergleichen.

Bist Du sicher, dass die Form "Reservierungen nach Datum" lautet?

Nachtrag: Das hatte Bernhard schon geschrieben, hatte ich nicht gesehen ...
« Letzte Änderung: 09.11.11 - 14:41:19 von Peter Klett »

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #14 am: 09.11.11 - 14:44:21 »
Auch das gibt einen type mismatch, Peter, da "..(" & comparedate nicht zusammen passt.

Andererseits würde es kein Einstellungsproblem geben, da alle Umwandlungen ja in der gleichen Maschine stattfinden.

Bernhard

Offline schroederk

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.924
  • Geschlecht: Männlich
  • Ich liebe dieses Forum!
Re: Lotusscript Optimierung
« Antwort #15 am: 09.11.11 - 14:57:26 »
Ohne die "Form = ..." funktioniert die Suche jetzt.
Allerdings nicht wesentlich schneller, als die View zu selektieren und alle Dokumente in der Schleife abzuarbeiten.
Die Form muss wohl richtigerweise "Reservations By Date Template" heissen. So zumindest der Alias.
Funktioniert aber auch damit nicht.
Ich wäre ja gerne weniger egoistisch, aber was hab ich davon?

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #16 am: 09.11.11 - 15:00:25 »
Das ist keine Form, sondern eine view! Und nützt Dir somit gar nichts.

Bernhard

Offline Thomas Schulte

  • @Notes Preisträger
  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 4.388
  • Geschlecht: Männlich
  • Ich glaub mich tritt ein Pferd
Re: Lotusscript Optimierung
« Antwort #17 am: 09.11.11 - 15:01:57 »
Das ist ein $$ViewTemplate und keine Form. Die Form ist das was bei so einer Reservierung im Feld Form drinsteht. Deine Selektion kann nicht funktionieren.

(Bernhard war schneller)
Thomas Schulte

Collaborative Project Portfolio and Project Management Software

"Aber wo wir jetzt einmal soweit gekommen sind, möchte ich noch nicht aufgeben. Versteh mich recht, aufgeben liegt mir irgendwie nicht."

J.R.R.Tolkien Herr der Ringe, Der Schicksalsberg

OpenNTF Project: !!HELP!! !!SYSTEM!!  !!DRIVER!!

Skype: thomasschulte-kulmbach

Offline ascabg

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.697
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #18 am: 09.11.11 - 15:09:12 »
@Bernhard,

Auch wenn die Programmierung dadurch nicht "sauber" wird, warum kann ich die beiden Sachen nicht miteinander verheiraten?
Code
Das knallt auch, Andreas - eine DT-Variable kannst Du nicht mit einem String verhereiraten.

Das folgende Konstrukt funktioniert doch auch problemlos.

Code
Dim varTest  as Variant
Dim strTest as String

varTest = cdat("01.01.2011")
strTest = "Heute ist der " & varTest

Msgbox strTest


Andreas

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: Lotusscript Optimierung
« Antwort #19 am: 09.11.11 - 15:11:30 »
Füg da mal noch weitere Terme dazu - das muss dann nicht mehr gut gehen mit solcher Ferkelei  ;)

Bernhard

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz