Autor Thema: [LotusScript] Type Mismatch  (Gelesen 10608 mal)

Offline DaWutz

  • Senior Mitglied
  • ****
  • Beiträge: 253
  • Geschlecht: Männlich
[LotusScript] Type Mismatch
« am: 01.03.05 - 18:33:47 »
In einem Agenten zum kopieren von Dokumenten von einer DB in einer andere bekomme ich eine Fehlermeldung "Type Mismatch".

Im Debugger kann ich nun sehen, dass das Feld das ich auslese (Categories) vom Value her Variant ist, der Wert Categories[0] aber vom Typ String. Aus dem [] schliesse ich, das das aber doch ein Array ist, oder?

Wie bringe ich ihn den nun dazu, den Wert einfach so zu splitten, wie ich das gerne hätte?

Code:
Sub Initialize
   Dim session As New NotesSession
   Dim SourceDB As NotesDatabase
   Dim DestinationDB As NotesDatabase
   Dim coll As NotesDocumentCollection
   Dim docOld As NotesDocument
   Dim docNew As NotesDocument
   Dim counter As Integer
   Dim splitPart1 As String
   Dim splitPart2 As String
   
   Set SourceDB = session.CurrentDatabase
   Set DestinationDB = session.GetDatabase(SourceDB.Server,"IT\it-kb.nsf")
   
   Set coll = SourceDB.UnprocessedDocuments
   Set docOld = coll.GetFirstDocument()   
   counter = 0
   
   Do While Not docOld Is Nothing
      Set docNew = New NotesDocument(DestinationDB)
      docNew.Form = "Documentation"
      docNew.Title = docOld.Subject
      docNew.CreatedBy = docOld.From
      docNew.CreatedOn = docOld.Date
      docNew.Content = docOld.Body
      splitPart1 = Strtoken(docOld.Categories, "/", 1 , 5)
      splitPart2 = Strtoken(docOld.Categories, "/", 2 , 5)
      docNew.Category = splitPart1
      docNew.SubCategory = splitPart2
      
      Call docNew.Save(True,True)
      Set docOld= coll.GetNextDocument(docOld)
      counter = counter + 1
   Loop
   Msgbox( counter & " Dateien kopiert!")
   
End Sub
« Letzte Änderung: 03.03.05 - 13:31:28 von DaWutz »
Grüße aus Bonn,

Daniel!

Domino 6.5.3 auf Win2k
Clients ab 6.01 CF2

>>... es ist mir scheißegal wer Dein Vater ist! Solange ich hier angele, wird NICHT über´s Wasser gelaufen!! <<

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: [LotusScript] Type Mismatch
« Antwort #1 am: 01.03.05 - 18:37:28 »
Irgendwie fehlt hier noch massgeblicher Code und die Angabe, in welcher Zeile es knallt.

Und: Wenn du "Categories [ 0]" siehst, ist es ein Array.

Bernhard
« Letzte Änderung: 01.03.05 - 18:47:07 von koehlerbv »

Offline TMC

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.660
  • Geschlecht: Männlich
  • meden agan
Re: [LotusScript] Type Mismatch
« Antwort #2 am: 01.03.05 - 18:38:20 »
Du schreibst leider nicht, in welcher Zeile der Fehler auftritt.

Aber StrToken (also @Word in LS) erwartet ein String.

docOld.Categories (als Kurzform von docOld.GetItemValue("Categories")) ist aber immer ein Array. Ich schätze also, dass das der Grund ist.
Matthias

A good programmer is someone who looks both ways before crossing a one-way street.


Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: [LotusScript] Type Mismatch
« Antwort #3 am: 01.03.05 - 18:48:19 »
Matthias, Du hast wahr, und ich habe Blödsinn geschrieben (abgesehen davon, dass die Angabe der explosiven Zeile mir abging).

Bernhard

Offline DaWutz

  • Senior Mitglied
  • ****
  • Beiträge: 253
  • Geschlecht: Männlich
Re: [LotusScript] Type Mismatch
« Antwort #4 am: 01.03.05 - 18:50:44 »
Hallo zusammen,

also, die Zeile ist (natürlich) eben jene die Matthias identifiziert hat. Ich dachte meine Ausführung auf eben jenes Item würde das schon "erschlagen".
Viel mehr Code existiert in dem Agenten bis jetzt auch nicht, ausser halt den Deklarationen usw..

Das mit dem splitten habe ich nun so gelöst, das ich ihn einfach den ersten Wert des Arrays, also Categories(0), nehmen lasse.

Genau:
      splitPart1 = Strtoken(docOld.Categories(0), "\", 1)
      splitPart2 = Strtoken(docOld.Categories(0), "\", 2)
      If splitPart2 = "" Then
         splitPart2 = splitPart1
         splitPart1 = "!! Kontrollieren !!"
      End If
      docNew.Category = splitPart1
      docNew.SubCategory = splitPart2

Warum ist das aber ein Array, der da ankommt? Ich weiß nu wie´s gemacht wird, aber ich verstehe nicht, warum.

Danke auch schonmal für die wirklich prompten Antworten!!

PS:
Der nächste Böller kommt aber noch, denn ich muss ihn noch dazu bringen auch Attachments mitzuschleppen, aber das schaffe ich auch noch...  ;)
« Letzte Änderung: 01.03.05 - 18:55:54 von DaWutz »
Grüße aus Bonn,

Daniel!

Domino 6.5.3 auf Win2k
Clients ab 6.01 CF2

>>... es ist mir scheißegal wer Dein Vater ist! Solange ich hier angele, wird NICHT über´s Wasser gelaufen!! <<

Offline TMC

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.660
  • Geschlecht: Männlich
  • meden agan
Re: [LotusScript] Type Mismatch
« Antwort #5 am: 01.03.05 - 19:04:27 »
Warum ist das aber ein Array, der da ankommt? Ich weiß nu wie´s gemacht wird, aber ich verstehe nicht, warum.

Liest Du per LotusScript mit der GetItemValue - Methode ein Item aus, so bekommst Du IMMER ein Array. Auch wenn das Item ein SingleValue-Feld ist.
Das ist definiert in der NotesDocument-Klasse.
Matthias

A good programmer is someone who looks both ways before crossing a one-way street.


Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: [LotusScript] Type Mismatch
« Antwort #6 am: 01.03.05 - 19:08:06 »
Jo, jedes NotesItem ist par definitionem ein Array, wenn es (im Backend) ausgelesen wird. Weil: Es könnte ja eines sein. Es wäre ja andererseits übel, wenn Du bei jedem Zugriff selber prüfen müsstest: "Was habe ich jetzt bekommen ?".

Auch "andersherum" macht das Sinn: Du definierst in einer Maske ein Feld als "Text", "Mehrfachwerte zulassen" ist nicht erlaubt.
Was Dich (oder andere) nicht hindern würde, dort im backend ein Array 'reinzuschreiben  ;D

Wenn Dui da noch Fragen hast, stelle sie: Das sind Dinge, die anfangs übel verwirren könne, bis sie dann doch ganz klar erscheinen.

Bernhard

Marinero Atlántico

  • Gast
Re: [LotusScript] Type Mismatch
« Antwort #7 am: 01.03.05 - 19:13:14 »
es gibt allerdings die leicht kryptische Abkürzung:
doc.getItemValue("feldName")(0)
Durch die (0) am Ende kommt der erste Wert zurück.
Kann den code übersichtlicher machen, wenn man sicher weiss, dass man es hier sowieso mit Einfach-Werte-Feldern zu tun hat. Was oft der Fall ist.

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: [LotusScript] Type Mismatch
« Antwort #8 am: 01.03.05 - 19:16:18 »
Naja, Axel, das hat Daniel ja schon gemacht  ;)

Bernhard

Offline TMC

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.660
  • Geschlecht: Männlich
  • meden agan
Re: [LotusScript] Type Mismatch
« Antwort #9 am: 01.03.05 - 19:20:22 »
Und noch zur Ergänzung:
Wenn Du per Script auf Felder zugreifst (also über Frontend-Klassen), bekommst Du Strings (völlig egal, ob das Feld auf 'Mehrfachwerte' etc. eingestellt ist).
Wenn Du auf Itemebene (also Backend-Dokumentenseitig) zugreifst, bekommst Du immer ein Array - auch wenn das ursprünglich zugrunde liegende Feld z.B. vom Typ "Zahl, ohne Mehrfachwerte" war.

Ich würde immer doc.GetItemValue nehmen, und die "Extended class" Syntax (doc.Itemname) mir gar nicht erst angewöhnen, auch wenn es bequemer erscheint.
Grund:
  • Performanceeinbußen (soll massiv sein, hab ich zumindest mal gelesen, leider keine Quelle mehr parat)
  • Probleme, wenn der Itemname = einer Notes-internen Bezeichnung entspricht
  • Du kannst den Itemnamen auch als String (Variable oder Konstante) übergeben.
Matthias

A good programmer is someone who looks both ways before crossing a one-way street.


Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: [LotusScript] Type Mismatch
« Antwort #10 am: 01.03.05 - 19:37:55 »
Und noch zur Ergänzung:
Ich würde immer doc.GetItemValue nehmen, und die "Extended class" Syntax (doc.Itemname) mir gar nicht erst angewöhnen, auch wenn es bequemer erscheint.
Grund:
  • Performanceeinbußen (soll massiv sein, hab ich zumindest mal gelesen, leider keine Quelle mehr parat)
  • Probleme, wenn der Itemname = einer Notes-internen Bezeichnung entspricht
  • Du kannst den Itemnamen auch als String (Variable oder Konstante) übergeben.

Dazu folgende Anmerkungen:
- Die Quelle würde mich auch interssieren !
- NotesItem = Intern verwendete Konstante: Das sollte man sowieso und immer vermeiden.
- Itemname als Variable: Jo, das hat was.

Wegen den Performance-Einbrüchen: Da der Zugiff auf Items von Dokumenten ja immer das Lesen von Platte bedeutet, ist diese Umsetzung (die sowieso schnell bei der selben API-Routine wie GetItemValue landen wird) im RAM eine vernachlässigbare Grösse. Ich habe dazu (als das auch hier im Forum schon mal hochkochte) mal Tests gemacht: Die Ergebnisse waren nicht signifikant (mal war das eine etwas (!) schneller, mal das andere. Und da ging es um Zugiffe auf Items aus > 50.000 Docs.

Bernhard

EDIT: Es sei aber auch darauf hingewiesen, dass von Lotus / IBM gelieferte Schablonen in der Regel mit GetItemValue etc. hantieren und nicht mit der Kurznotation.
« Letzte Änderung: 01.03.05 - 19:41:09 von koehlerbv »

Offline TMC

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.660
  • Geschlecht: Männlich
  • meden agan
Re: [LotusScript] Type Mismatch
« Antwort #11 am: 01.03.05 - 19:53:14 »
- NotesItem = Intern verwendete Konstante: Das sollte man sowieso und immer vermeiden.

Ich denke Du meinst NotesItemName. Unter manchen Umständen kann das durchaus praktikabel sein, den Namen eines Items als Konstante zu definieren, z.B. innerhalb einer ScriptLibrary, die z.B. auf (Teil-)Masken verweist, welche immer wiederkehrende Items enthält (Lösch-Flag, Historie, etc. etc.). Sollte sich der Itemname ändern: -> Anpassung an 1 zentralen Stelle.

Ich muss nochmal wühlen bezügl. des Performance-Problems. Aber der Artikel den ich dazu mal gelesen hatte, klang sehr überzeugend. Es ging speziell um das Auflösen (Also die Abfrage: "ist das nun ein Itemname oder passiert da was mit einer Methode/Property. Wenn Itemname, dann kippen wir das ganze mal in GetItemValue").

Erwähnenswert für DaWutz ist auch noch in dem Kontext, dass bei Itemnamen, die ein vorangestelltes $ haben (z.B. $REF), ein ~ vorangestellt werden muss bei der Extended Class Syntax (z.B. doc.~$REF).
Matthias

A good programmer is someone who looks both ways before crossing a one-way street.


Marinero Atlántico

  • Gast
Re: [LotusScript] Type Mismatch
« Antwort #12 am: 01.03.05 - 20:06:01 »
Bzgl. der Performance stimme ich mit Bernhard überein.
Die Literatur rät dazu, dass Performance-Optimierungen immer auf ein Ziel hin gerichtet sein sollen.
Also für Notes: Das Querysave dieser Maske darf auf der und der Standardhardware nicht länger als sagen wir 0.5 Sek. dauern. Wenn ja, muss optimiert werden.
Hier nicht unbedingt aber performance-optimierter code kann schnell auch gleichzeitig nicht so übersichtlicher code sein. Und man sollte nur dort optimieren, wo es einen Mehrwert für den Anwender verspricht.
Ob ein Skript jetzt 0.680 oder 0.681 sek dauert, ist nicht so interessant.

Aber - wie Mathias schon im Kontext von "Konstante" angedeutet hat - hat getItemValue den Vorteil, dass es parametrisierbarer ist. Ich benutz das oft, wenn es darum geht eine Reihe von Feldern eines docs zugreifen muss. Nur dann schreib ich es in einen Array und tue diesen nach oben im Skript.
Es gibt auch manchmal Situationen, wo man diese Feldnamen sinnvoll in ein externes Konfigurationsdokument externalisieren kann. Nur kann man es damit auch übertreiben.

Offline TMC

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.660
  • Geschlecht: Männlich
  • meden agan
Re: [LotusScript] Type Mismatch
« Antwort #13 am: 01.03.05 - 20:30:50 »
Bzgl. der Performance stimme ich mit Bernhard überein.
Die Literatur rät dazu, dass Performance-Optimierungen immer auf ein Ziel hin gerichtet sein sollen.
Also für Notes: Das Querysave dieser Maske darf auf der und der Standardhardware nicht länger als sagen wir 0.5 Sek. dauern. Wenn ja, muss optimiert werden.
Hier nicht unbedingt aber performance-optimierter code kann schnell auch gleichzeitig nicht so übersichtlicher code sein. Und man sollte nur dort optimieren, wo es einen Mehrwert für den Anwender verspricht.
Ob ein Skript jetzt 0.680 oder 0.681 sek dauert, ist nicht so interessant.

Guter Einwand, Axel.
Zumal ich ja auch sehr oft die Extended Class Syntax verwende  :P
Aber ich will DaWutz gleich mal in die richtige Richtung weisen, sonst haben wir noch morgen einen Thread von ihm, warum {doc.Authors = "Hans Huber/Org"} nicht funktioniert  ;D

Den Artikel hab ich leider jetzt nicht gefunden, aber der Performance-Einbruch klang bemerkenswert.

Feldnamen in Konfig-Dokumenten: Wenn dann nur vorgegeben: nicht änderbare Liste mit festen Vorgabewerten. Keinesfalls sollte man das frei definierbar machen, da IMHO Konfig-Doks nicht für Entwickler, sondern für Admins und/oder Endanwender sind. Da würde ich allerhöchstens auswählen lassen: Schreibe XY in Item A oder Item B.
Matthias

A good programmer is someone who looks both ways before crossing a one-way street.


Glombi

  • Gast
Re: [LotusScript] Type Mismatch
« Antwort #14 am: 01.03.05 - 20:38:28 »
Leider finde ich den Artikel auch nicht, aber ich kann mich erinnern, dass die Performance der Extended Class Syntax signifikant schlechter ist.

Im net habe ich das hier bei der ersten Suche gefunden:
http://www.martinscott.com/home.nsf/0/C7F5B845A9E6C76385256C180007FBEF?opendocument

einiges davon stammt wohl hieraus:
http://www-12.lotus.com/ldd/doc/bp/46bpg.nsf/

Bemerkenswert u.a.:
Using the ColumnValues property is about 10 percent faster than getting a handle to a document and using the extended class syntax-- e.g., x=doc.fieldname.


Andreas
« Letzte Änderung: 01.03.05 - 20:45:50 von Glombi »

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Re: [LotusScript] Type Mismatch
« Antwort #15 am: 01.03.05 - 20:53:19 »
Leider finde ich den Artikel auch nicht, aber ich kann mich erinnern, dass die Performance der Extended Class Syntax signifikant schlechter ist.

Komisch, keiner findet den Artikel  ;D

Bemerkenswert u.a.:
Using the ColumnValues property is about 10 percent faster than getting a handle to a document and using the extended class syntax-- e.g., x=doc.fieldname.

Bemerkenswert finde ich hier eher die Aussage, dass der Zugriff via ColumnValues nur 10% schneller sein soll, als das Dokument selber auszulesen - immerhin greift man hier auf den ViewIndex zu. Auch mit dieser Aussage wäre ich vorsichtig.

Das wäre was für einen BP-Artikel. In das Thema Massendatenverarbeitung spielt ja noch viel mehr hinein. Wenn es nur um ein Dokument geht, lohnt wegen Millionstel Sekunden die Diskussion sowieso nicht.

Bernhard

Marinero Atlántico

  • Gast
Re: [LotusScript] Type Mismatch
« Antwort #16 am: 01.03.05 - 21:10:27 »
Bemerkenswert u.a.:
Using the ColumnValues property is about 10 percent faster than getting a handle to a document and using the extended class syntax-- e.g., x=doc.fieldname.

Fragt sich natürlich 10% von was.
Wenn in einem Skript die Zugriffe auf Items insgesamt nur 10% der Zeit ausmachen, ist der Performance-Gewinn insgesamt nur ungefähr 1%.

Offline TMC

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.660
  • Geschlecht: Männlich
  • meden agan
Re: [LotusScript] Type Mismatch
« Antwort #17 am: 01.03.05 - 21:17:32 »
Gesucht, und was gefunden, meinte aber einen anderen Artikel.

Code
Although we prefer to use the "GetItemValue" method of the NotesDocument object to retrieve a field value, we know that many developers prefer to use the extended syntax to retrieve a field value. If you aren't familiar with the extended syntax, these two statements are equivalent:
result = doc.GetItemValue("MyField")(0)
result = doc.MyField(0)

The true difference between the above statements is performance. The first line will be slightly faster than the second line. In the first line, the LotusScript interpreter knows that "GetItemValue" is a method so it immediately finds the method and runs it. The second line looks to the interpreter like a property, so it tries to find the property. When that isn't found, it says, "oh, it must be a field" and then finds the field. So the first statement is just a little faster. One trial we did ended up with a 4% time savings, but that's not the point of this tip.

If you still would like to use the extended syntax, and have a need to access some reserved fields (like $UpdatedBy or $Ref), if you try to put this statement in your script:
result = doc.$UpdatedBy(0)
The compiler will immediately give you an error:
Unexpected: $UpdatedBy; Expected: Identifier

To access a reserved field with the extended syntax, there's a little trick you can use:
result = doc.~$UpdatedBy(0)

The tilde character in front of the dollar sign satisfies the compiler and the interpreter knows to ignore that tilde when it's going through the code. So it gets the "$UpdatedBy" field off the document.

Quelle: http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256BD6004B7868

BreakingPar meint: 4%.
Meist also zu vernachlässigen.

Aber aufgrund o.g. Vorteile von GetItemValue IMHO ein kleiner weiterer Grund, GetItemValue immer auszuschreiben. Geht ja auch um Pflege des Codes. Was, wenn sich doch z.B. der Itemname von "Autoren" auf "Authors" ändert? Bei konsequent verwendetem GetItemValue 2 Mausklicks (Suchen/Ersetzen), bei Extended Class Syntax: u.U. sehr viel zu tun. Natürlich sollte man "Authors" eh nicht als Itemname nehmen.
Matthias

A good programmer is someone who looks both ways before crossing a one-way street.


Glombi

  • Gast
Re: [LotusScript] Type Mismatch
« Antwort #18 am: 01.03.05 - 21:24:02 »
Fragt sich natürlich 10% von was.
Von der Zeit denke ich  ;)

Zitat
Natürlich sollte man "Authors" eh nicht als Itemname nehmen.
Warum nicht? Nur interesse halber.

Natürlich sollte man in R5 auch kein Feld Lock nennen  ;D
Tja leider kann man nicht in die Zukunft blicken. Was IBM da so veranstaltet mit reservierten Feldnamen, die kein $$ vorangestellt haben, ist schon sehr nachlässig wenn nicht fahrlässig.

Andreas
« Letzte Änderung: 01.03.05 - 21:26:13 von Glombi »

Offline TMC

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 3.660
  • Geschlecht: Männlich
  • meden agan
Re: [LotusScript] Type Mismatch
« Antwort #19 am: 01.03.05 - 21:32:03 »
Da hast Du Recht Andreas: Warum nicht? Eben da Authors auch gleichzeitig eine Property von NotesDocument ist  :P

Schwierig abzuschätzen, welche internen Bezeichnungen IBM in der Zukunft noch einsetzen wird.

Also noch ein Grund für GetItemValue, eben um sicher zu gehen.  :)
Matthias

A good programmer is someone who looks both ways before crossing a one-way street.


 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz