Autor Thema: Formel für Evaluate() aus Profildokument lesen  (Gelesen 8466 mal)

Offline Dynadrate

  • Frischling
  • *
  • Beiträge: 6
Formel für Evaluate() aus Profildokument lesen
« am: 24.08.11 - 16:01:48 »
Hallo zusammen,

ich habe folgendes Problem: Wenn ich einen Feldinhalt mit Lotusscript aus einem Dokument lese, bei der der Feldinhalt doppelte Anführungszeichen hat, werden doppelte Anführungszeichen "hinzuerfunden".

Aber lasst mich das Problem von vorne beschreiben:

Wir nutzen eine Funktion in einer Script-Bibliothek die nichts anderes tut als Werte aus Dokumenten in Excel auszugeben. Nachfolgend der Code:

Code
Sub ExportToExcel(viewname As String, flds As Variant, sheetname As String)
	' Definitions
	Dim uiws As New NotesUIWorkspace
	Dim ns As New NotesSession
	Dim db As NotesDatabase
	Set db = ns.CurrentDatabase
	
	' Open Excel
	Dim xl As Variant
	Set xl = CreateObject("Excel.Application")
	
	Dim i%, j%
	
	Dim xlbook As Variant
	Dim sheetprj As Variant
	
	Set xlbook = xl.Workbooks.Add
	Set sheetprj = xlbook.Sheets(1)
	sheetprj.Name = sheetname
	
	' First Row
	For i% = 0 To Ubound(flds)
		sheetprj.Range(colrow(i%,1)).Value = flds(i%)
	Next
	
	Dim vw As NotesView
	Set vw = db.GetView(viewname)
	Dim doc As NotesDocument
	
	Set doc = vw.GetFirstDocument
	
	Dim v As Variant
	Dim value$
	Dim row As Long
	row = 0
	
	xl.Visible = True	
	
	
	While Not (doc Is Nothing)
		For i% = 0 To Ubound(flds)
			value$ = ""	
			v = flds(i%)
			
			If Trim(Left(v,1))="@" Then
				Dim var As Variant
				var = Evaluate(v)	
			Else
				v = doc.GetItemValue(v)
				For j% = 0 To Ubound(v)
					If j% > 0 Then
						value$ = value$ + "; "
					End If
					value$ = value$ + Cstr(v(j%))
				Next
			End If				
			sheetprj.Range(colrow(i%,row+2)).Value = value$			
		Next
		
		row = row + 1
		
		Set doc = vw.GetNextDocument(doc)
	Wend
	
	xl.Visible = True	
	
End Sub


Nun rufe ich den oben beschriebenen Sub in einer Aktion in einem View auf:
Code
Sub Click(Source As Button)
	
	' Definitions
	Dim uiws As New NotesUIWorkspace
	Dim ns As New NotesSession
	Dim db As NotesDatabase
	Set db = ns.CurrentDatabase
	
	' Feature Profile contains additional field names in the fields:
	' FPR_QueryComp and FPR_QueryCont
	Dim fprof As NotesDocument	
	Set fprof = db.GetProfileDocument("(FeatureProfile)")
	
	Dim fldnames As Variant
	fldnames = fprof.FPR_ExportFields
	
	Call ExportToExcel("Main",fldnames,"Projekte")	
	
End Sub

Funktioniert soweit super, wenn das Feld "FPR_ExportFields" im sogenannten FeatureProfile eine Liste von Feldern enthält, die in dem Dokument enthalten sind.

Nun würde ich den Code gerne erweitern, sodass anstatt der Feldnamen auch Formeln angegeben werden können, die vom Sub ExportToExcel "evaluated" werden. (Ich habe im Sub ExportToExcel diese Anpassung schon angefangen).

Der Formelbefehl sieht wie folgt aus:
Code
@DbLookup( "" : "NoCache" ; "" : "" ; "(LookupStakeholdersByREF)" ; @Text(@DocumentUniqueID);2)

Wenn dieser Befehl nun aus dem Feld gelesen wird, werden Anführungszeichen hinzuerfunden. Siehe Screenshot der den Debugger zeigt.
Das Lotusscript diese Zeichenkette nicht "evaluaten" kann ist klar.


Wie bekomme ich es also hin, das der Feldinhalt gelesen wird ohne das die Anführungszeichen hinzuerfunden werden?

Danke fürs Lesen dieses langen Beitrags!!  :D

Markus
« Letzte Änderung: 24.08.11 - 16:05:42 von Dynadrate »

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.885
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #1 am: 24.08.11 - 16:15:47 »
Da wird nichts "dazuerfunden", das ist schlicht und ergreifend die Art und weise wie der Debugger die Anführungszeichen maskiert.

Dein Fehler ist an einer ganz anderen Stelle:

Code
If Trim(Left(v,1))="@" Then
				Dim var As Variant
				var = Evaluate(v)	
			Else

Der Evaluate braucht, wenn er auf Dokumentenwerte zugreifen soll (in Deinem Fall @DocumentUniqueID) einen Parameter, der ihm das Dokument mitliefert.

Ohne den ist @DocumentUniqueID leer und damit liefert Dein @DBLookup einen Error...

In Deinem Fall also so:
Code
If Trim(Left(v,1))="@" Then
				Dim var As Variant
				var = Evaluate(v,doc)	
			Else

Ach ja: Natürlich fehlt noch der Teil, der aus dem Variant var (evaluate liefert IMMER ein Array) einen String macht, den man auch in ein Excel- Feld schreiben kann...kann
« Letzte Änderung: 24.08.11 - 16:18:40 von Tode »
Gruss
Torsten (Tode)

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

Offline ata

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 5.092
  • Geschlecht: Männlich
  • drenaiondrufflos
    • Anton Tauscher Privat
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #2 am: 24.08.11 - 16:23:40 »
... Torsten hat das exact beschrieben, du musst den Evaluate zwingend auf ein doc anwenden. Ansonsten weiß der Evaluate ja nicht, wie es die Felder des Dokumentes verwenden soll. Deine Bedingung zur Erkennung der Formel ist etwas schwach, da damit deine Formel zwingend mit @ beginnen muß - und das muß nicht sein...

Toni
« Letzte Änderung: 24.08.11 - 16:25:19 von ata »
Grüßle Toni :)

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.885
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #3 am: 24.08.11 - 16:33:13 »
@Toni: Die Liste der "Schwächen" dieses Codes liesse sich noch um einige erweitern (kein Error- Handling, Dim var as Variant innerhalb der Schleife, keine Prüfung, ob Variablen überhaupt initialisiert wurden, etc... ), deshalb habe ich auf diesen Hinweis mal verzichtet...
Gruss
Torsten (Tode)

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

Offline ata

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 5.092
  • Geschlecht: Männlich
  • drenaiondrufflos
    • Anton Tauscher Privat
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #4 am: 24.08.11 - 16:42:18 »
@Torsten

... da hast du sicherlich recht ;) - stilistisch ist da einiges zu verbessern - mein Hinweis sollte nur inhaltlich die Eingrenzung der Formel nennen. Es findet auch keine Validierung der Formel statt - da liese sich noch viel dran machen, um das sauber zu handeln :) - schade - denn damit sind mächtige Operationen möglich...

Toni
Grüßle Toni :)

Offline TRO

  • Senior Mitglied
  • ****
  • Beiträge: 296
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #5 am: 24.08.11 - 16:50:40 »
@Toni: Die Liste der "Schwächen" dieses Codes liesse sich noch um einige erweitern ...., Dim var as Variant innerhalb der Schleife, ...

Was ist daran falsch? Dim als Code-Element wird zur Compile-Zeit und nicht zur Runtime ausgeführt. Damit ist es völlig unerheblich ob das Dim in einer millionenfachen Schleife steht oder außerhalb aller Schleifen --> es wird immer nur einmal ausgeführt (und initialisiert).
Es gibt sogar Programmierphilosophien, die schreiben eine möglichts verwendungsnahe Variablendeklaration vor.

Thomas

Offline Dynadrate

  • Frischling
  • *
  • Beiträge: 6
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #6 am: 24.08.11 - 16:52:42 »
@Tode: Danke, das wars! Ich wat vollig fixiert darauf, das Evaluate() zu keinem richtigen Ergebnis kommen kann, weil die Anführungszeichen "vermurkst" sind.

Deine Bedingung zur Erkennung der Formel ist etwas schwach, da damit deine Formel zwingend mit @ beginnen muß - und das muß nicht sein...

Das stimmt! Mir ist nur keine bessere Methode eingefallen, um Formelcode zu erkennen. Wüsstest Du was besseres? Schlimmstenfall müsste man einen Indikator zu Beginn einer jeden Zeile einführen, der klar macht ob es ein Feldname oder ein Formelbefehl ist. Toll wäre aber schon, wenn man es erkennen könnte ;)

Es findet auch keine Validierung der Formel statt - da liese sich noch viel dran machen, um das sauber zu handeln :) - schade - denn damit sind mächtige Operationen möglich...

Wie kann ich die Formel validieren?


@Toni: Die Liste der "Schwächen" dieses Codes liesse sich noch um einige erweitern (kein Error- Handling, Dim var as Variant innerhalb der Schleife, keine Prüfung, ob Variablen überhaupt initialisiert wurden, etc... ), deshalb habe ich auf diesen Hinweis mal verzichtet...

Danke für den Hinweis! Kurze "Rechtfertigung" meinerseits.
  • "Dim var as Variant" kommt zustande weil ich quasi noch in der Erprobungsphase stecke. Natürlich wird das sofort ordentlich typisiert, wenns funktioniert ;)
  • kein Error- Handling: völlig Richtig. Ich verspreche brav, mir bei nächster Gelegenheit diesen Thread: http://atnotes.de/index.php?topic=11980.0 zur Gemüte zu führen.
  • keine Prüfung, ob Variablen überhaupt initialisiert wurden: An welchen Stellen würdest Du eine solche Prüfung mit einbauen?
  • etc.: Ich bin offen für jede Art von Verbesserungsvorschlag! Ich würde mich freuen, wenn Du mir weitere Kritikpunkte nennen würdest
« Letzte Änderung: 24.08.11 - 16:54:24 von Dynadrate »

Offline TRO

  • Senior Mitglied
  • ****
  • Beiträge: 296
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #7 am: 24.08.11 - 17:25:53 »
Deine Bedingung zur Erkennung der Formel ist etwas schwach, da damit deine Formel zwingend mit @ beginnen muß - und das muß nicht sein...

Das stimmt! Mir ist nur keine bessere Methode eingefallen, um Formelcode zu erkennen. Wüsstest Du was besseres? Schlimmstenfall müsste man einen Indikator zu Beginn einer jeden Zeile einführen, der klar macht ob es ein Feldname oder ein Formelbefehl ist. Toll wäre aber schon, wenn man es erkennen könnte ;)


Ich mach das immer mit einem @ als Kenner und werfe ihn dann mittels Mid( sFormula, 1 ) weg. Ein Evaluate-String, der mit einem Formelbefehl startet hat dann zwei @@ am Anfang, z.B. @@Text( Datumswert ).

Auch einen Feldnamen kannst Du mit einem Evaluate auswerten:
vEval = Evaluate( "Feldname", doc ) liefert Dir den Inhalt des Feldes (genauer: des Items) mit dem Namen Feldname.
Schwieriger (und das meinte wohl Anton) sind solche Evaluate-Formeln, die z.B. mit einer Zeichenkette beginnen:
"Firma: " + CompanyName




Danke für den Hinweis! Kurze "Rechtfertigung" meinerseits.
  • "Dim var as Variant" kommt zustande weil ich quasi noch in der Erprobungsphase stecke. Natürlich wird das sofort ordentlich typisiert, wenns funktioniert ;)

"Dim var as Variant" ist vollkommen korrekt deklariert (event. könnte man den Variablen-Namen noch etwas aussagekräftiger machen).

Evaluate liefert Daten vom Typ Variant zurück (immer als Array).

hth

Thomas

Offline ata

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 5.092
  • Geschlecht: Männlich
  • drenaiondrufflos
    • Anton Tauscher Privat
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #8 am: 25.08.11 - 07:53:47 »
Hallole

@TRO (Thomas)
Zitat
Es gibt sogar Programmierphilosophien, die schreiben eine möglichts verwendungsnahe Variablendeklaration vor.
... das mag sein - falsch ist es nicht, aber für eine bessere Übersichtlichkeit bei größerem Code ist sicherlich dienlicher die Deklaration im Kopf der Funktion vorzunehmen. Ich habe mir das so angewöhnt und fahre sehr gut damit. Dort kann man dann zusammengehörige Variablen miteinander deklarieren.
Zitat
Ich mach das immer mit einem @ als Kenner und werfe ihn dann mittels Mid( sFormula, 1 ) weg. Ein Evaluate-String, der mit einem Formelbefehl startet hat dann zwei @@ am Anfang, z.B. @@Text( Datumswert ).
... das ist schon ein guter Ansatz. Bleibt noch die Validierung der Formel. Die kann man über Formelbefehle validieren - also einen weiteren Evaluate mit dem entsprechenden Formelstring...


@Dynadrate (Markus)
Zitat
keine Prüfung, ob Variablen überhaupt initialisiert wurden: An welchen Stellen würdest Du eine solche Prüfung mit einbauen?
... getProfileDocument(...) => Bei NotesProfileDoument überprüfe ich immer, ob ich es auch habe. Die können durchaus verloren gehen - leider - ich versuche auf NotesProfileDocuments so weit wie möglich zu verzichten...
... flds => Hat das Array members - es könnte auch leer sein
... v => beim Einlesen deiner Werte werden Mehrfachwerte mit einem Semikolon verkettet - da muß sichergestellt sein, daß keine Semikolon's in deinen Quellfeldern enthalten sind, das hätte Auswirkungen auf die Anzahl der Werte

Das wären mal auf die schnelle die Auffälligsten ;)

Bei deinem Export gehst du pro Zeile auf ein Feld und schreibst in den Range die Werte, soweit ich das erkenne. Ich splitte Mehrfachwerte in neue Zeilen, da der Range erst nach Office 2003 mehr als 256 Spalten haben kann...

Toni

*** edit ***
Im Fehlerfall bleibt dir die Excel-Instanz unsichtbar geöffnet. Du solltest das Excel im Fehlerfall schließen...
« Letzte Änderung: 25.08.11 - 08:02:49 von ata »
Grüßle Toni :)

Offline ata

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 5.092
  • Geschlecht: Männlich
  • drenaiondrufflos
    • Anton Tauscher Privat
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #9 am: 25.08.11 - 07:59:36 »
... die Formel zur Prüfung der Syntax ist @CheckFormulaSyntax( _code ) und liefert ein True oder False

Toni
Grüßle Toni :)

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.885
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Re: Formel für Evaluate() aus Profildokument lesen
« Antwort #10 am: 25.08.11 - 10:47:46 »
xlbook und sheetprj sind für mich auch wichtige Variablen, die es zu testen gibt: Was wenn Excel nicht sauber installiert ist, oder Berechtigungen nicht stimmen?

Ach ja: Ganz wichtig ist das aufräumen eben dieser Variablen, wie Toni schon geschrieben hat, sonst müllst Du Deinen Task- Manager mit Excel- Instanzen zu...

Was ebenfalls fehlt ist dir Prüfung, ob Dein Dokument, das Du da aus Deiner Collection hast, ein gültiges Dokument ist (doc.isValid, doc.isDeleted, IsArray(doc.Items) und doc.HasItem( "$Conflict" )... denn unter Umständen bekommt man da Deletion- Stubs, Replication Conflicts oder einfach nur "Kaputte" Dokumente zurück, und dann bricht die Routine einfach ab...

Ach ja: FPR_ExportFields würde ich schon beim befüllen im Profil via @CheckFormulaSyntax prüfen und ein speichern gar nicht erst zulassen, wenn da keine korrekte Formal drinsteht, in Deinem Script ist das definitiv zu spät.

Das mit dem führenden "@" zur Erkennung von Formeln scheint ein "pseudo"- Standard zu sein, das habe ich schon so oft gesehen (und verwende es selbst auch)...

Ansonsten: Prüfung des Wertes auf Länge, ob der überhaupt in die Zelle passt (wirft keinen Fehler, sondern schneidet einfach Inhalt ab, ich weiss nicht, was blöder ist...)

das wärs erst mal von meiner Seite... Nix wirklich neues, die Kollegen hier haben das meiste ja schon erwähnt.
Gruss
Torsten (Tode)

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

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz