Autor Thema: NotesItem cannot be set to array of mixed data type bei doc.RemoveItemValue  (Gelesen 6467 mal)

Offline Christian Kröll

  • Aktives Mitglied
  • ***
  • Beiträge: 197
  • Geschlecht: Männlich
Hallo liebe Gemeinde,


ich brauche Eure Hilfe und Rat - ich sehe den Hund vor lauter Bäumen nicht mehr - oder so ähnlich?

Folgendes: In einem Dokument werden Produkte und mögliche Varianten erfasst. Früher war die Notesmaske so aufgebaut, dass maximal fünf Varianten hinterlegt werden konnten. Für jede Eigenschaft des Produktes gab es fünf Felder. Über 200 Eigenschaften können theoretisch zum tragen kommen. Machte bei fünf Varianten schnell 1.000 und mehr Felder, deren Anzeige großteils voneinander abhing und daher häufige Refreshs des Dokumentes bedeutete.

Das "Ungeheuer" habe ich neu gebaut: Die Varianten werden nun als Listen in jeweils einem Item gespeichert. Funktioniert einwandfrei, wesentlich performanter und ich renne nicht mehr in eine Begrenzung (32k für Feldnamen).

Für das Bearbeiten von den Items werden die Werte einer Variante in eine Dialogmaske geholt, bearbeitet und zurückgeschrieben. Beim Zurückschreiben muß ich prüfen, ob die Items auch vorhanden sind, da es ja mal neue Eigenschaften geben könnte und da hakt es.

Erläuterung: In einem gespeicherten Dokument wird aus einem Config-Dokument das Feld "Fields" und "NumberFields" befüllt mit den Eigenschaften. Die Eigenschaften entsprechen den Feldnamen einer Dialogmaske.
Es wird ein temp_doc mit den Werten der zu ändernden Variante gefüllt, die Dialogmaske aufgerufen und dann nach Validierung der Eingaben alles wieder in die Listen zurückgeschrieben. Die Items sind nach Text und Zahl aufgeteilt, da ich in den Listen ja einen entsprechenden Platzhalter bei leeren Eigenschaften benötige (~ bzw. 0).


Code
	Dim ws As New NotesUIWorkspace
	Dim s As New Notessession
	Dim db As NotesDatabase
	Dim doc As NotesDocument
	Set db = s.CurrentDatabase
	Set doc = ws.CurrentDocument.Document                                  'doc ist gespeichert, da nach jedem Erstellen, Bearbeiten o. Löschen einer Variante das Dokument gespeichert wird.
	If uidoc.EditMode=False Then uidoc.EditMode = True
	Dim temp_doc As New Notesdocument(db)

hier schnippi schnappi, Code weg - da nur temp_doc mit Werten der Variante z aus doc gelesen wird und die Dialogmaske aufgerufen wird.

'Nun schreiben wir die Werte zurück
	If x = 1 Then                                                                              'x enthält die Angabe, ob es in dem Dokument erst eine oder schon mehrere Varianten des Produktes enthält
		Forall f In doc.Fields
			itemvalue = temp_doc.GetItemValue(f)(0)
			If itemvalue = "" Then itemvalue = Chr(126)             'Tilde für den Fall, dass aus der Dialogmaske doch mal ein Feld leer zurückkommt
			Call doc.ReplaceItemValue(f,itemvalue)
		End Forall
		Forall f In doc.NumberFields
			itemvalue = temp_doc.GetItemValue(f)(0)
			If itemvalue = "" Then itemvalue = 0
			Call doc.ReplaceItemValue(f,itemvalue)
		End Forall
	Else	' hier Schleifen, wenn bereits Varianten existieren und nun eine Variante (z) in den Listen ersetzt werden muß
		Forall f In doc.NumberFields
'schnipp schnapp, bei Textfeldern funktioniert alles!!!!
                End Forall

		Forall f In doc.NumberFields
			If Not doc.HasItem(f) Then                        'Ist das Item schon vorhanden?
				Redim arr_Temp(y)                            'y ist die Anzahl der erstellten Varianten -1, Schleife liesst vorhandene Werte aus anderen Varianten
				For i = 0 To y
					If i = z Then                               'wenn i = z bedeutet, dass hier jetzt die Werte aus der Dialogmaske eingefügt werden
						itemvalue = temp_doc.GetItemValue(f)(0)
						If itemvalue = "" Then itemvalue = 0
						arr_Temp(i) = itemvalue
					Else
						arr_Temp(i) = 0
					End If	
				Next
				Call doc.ReplaceItemValue(f,arr_Temp)             '!!!!!!! hier knallt's mit der Fehlermeldung 
				Erase arr_Temp
			Else
				Redim arr_Temp(y)
				For i = 0 To y
					If i = z Then
						itemvalue = temp_doc.GetItemValue(f)(0)
						If itemvalue = "" Then itemvalue = 0
						arr_Temp(i) = itemvalue
					Else
						arr_Temp(i) = doc.GetItemValue(f)(i)
					End If
				Next
				Call doc.ReplaceItemValue(f,arr_Temp)                                                 
				Erase arr_Temp
			End If
		End Forall
	End If

Der Code läuft für neue Items vom Typ Text problemlos. Bei der Schleife für die Number-"Felder" kommt die Fehlermeldung "NotesItem cannot be set to array of mixed data type". Es geht dabei um das Feld bzw. die Eigenschaft "vk_Spezialfracht".

Was ich nicht verstehe:
arr_Temp enthält 0 - siehe Debugger-Screenshot. Vom temp_doc (Dialogmaske) kommt 0 (Double) zurück. Warum funktioniert weder RemoveItemValue oder auch das versuchte AppendItemValue nicht? Ich sehe es nicht und sicher habt Ihr einen unverstellten Blick.

Vielen Dank für Eure Mühe schonmal vorab!
« Letzte Änderung: 18.04.12 - 16:13:42 von Christian Kröll »
Christian Kröll

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Arr_Temp (0) ist ein Variant und Arr_Temp (1) auch, auch wenn beide den Wert 0 haben.

Hast Du mal

Redim arr_Temp(y) As Integer

(oder Long, oder Double, je nachdem, was Du brauchst) versucht? Ist nur eine Idee ...

Offline Christian Kröll

  • Aktives Mitglied
  • ***
  • Beiträge: 197
  • Geschlecht: Männlich
ich wusste doch, dass ein Dritter sofort den Finger auf die Wunde legt! So klappt's - Danke!

Die Dialogmaske gibt 0 (Double) zurück. Wenn das Item nicht existiert, fülle ich die Lücke mit 0 und das ist eben nicht Double. Das im Debugger alles als Variant angezeigt wird, bedeutet ja nicht, dass es nicht unterschiedliche Datentypen sein können. Klar - ist verstanden.
Christian Kröll

Offline koehlerbv

  • Moderator
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 20.460
  • Geschlecht: Männlich
Mich wundert, dass das hier funktioniert:
Code
itemvalue = temp_doc.GetItemValue(f)(0)
If itemvalue = "" Then itemvalue = 0

Ist das Item nicht gefüllt, gibt es einen String zurück. Steht aber doch eine Zahl zurück, dann ist Zahl = "" ein typischer type mismatch ...

Verwundert,
Bernhard

PS: Ich würde wenigstens ein
itemvalue = Cstr (temp_doc.GetItemValue (f)(0)) zur Normierung einsetzen. Und wenn es ein Frontend-Dokument ist, aus dem im Backend die Daten gelesen werden, funktioniert das gar nicht, da dann auch mal ein Error State aus einem Number- oder DT-Feld zurückkommen kann.

Offline Christian Kröll

  • Aktives Mitglied
  • ***
  • Beiträge: 197
  • Geschlecht: Männlich
Hallo Bernhard,

es funktioniert auch nicht  ;) Danke. Allerdings sind Eingaben in der Dialogmaske im QueryClose komplett geprüft. Da habe ich die Routine auch anders geschrieben:
Code
Forall f In doc.NumberFields
	If Cstr(doc.GetItemValue(f)(0)) = "" Then 
		Call doc.ReplaceItemValue(f,0)
	End If
End Forall
So konnte mir mein Fehler auch nie auffallen.
Christian Kröll

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz