Autor Thema: "Notes-Fehler: Ein anderer Benutzer hat dieses Dokument zur gleichen Zeit..."  (Gelesen 6086 mal)

Offline Bruce Willis

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.002
  • Geschlecht: Männlich
  • Wer nicht wagt...
"Notes-Fehler: Ein anderer Benutzer hat dieses Dokument zur gleichen Zeit geändert (namesKOPIE.nsf)"

Hallo,

die o.g. Meldung kommt beim Versuch, die Dokumente aus einer Datenbank in eine andere zu kopieren.
Bzw. alle Dokumente werden zum ersten Mal problemlos kopiert, aber wenn danach ein zu kopierendes Dokument geändert wurde, geht es nicht mehr wegen der Fehlermeldung.

Weiß jemand, wie das Problem gelöst werden könnte?

Gruß
Leo

Code


	Dim session As New NotesSession
	Dim db As NotesDatabase		'aktuelle Datenbank
	Dim dbN As NotesDatabase	'NAB Datenbank
	Dim dbK As NotesDatabase	'FIRMA Kontakte Datenbank
	Dim viewN As NotesView
	Dim viewK As NotesView
	
	'Name des aktuellen Servers emitteln
	Set db = session.CurrentDatabase
	Dim serverName As String
	serverName = db.Server	
	
	Set dbN = session.GetDatabase(ServerName,"namesKOPIE.nsf", False)
	Set dbK = session.GetDatabase(ServerName,"FIRMA//SysAdm//Entwicklung//FIRMA-kontakte.ntf", False)
	Set viewN = dbN.GetView("Mitarbeiterliste")
	Set viewK = dbK.GetView("FIRMA-MA")
		
	Dim numDocsN As Long	
	numDocsN = viewN.AllEntries.Count	'Anzahl der Dokumente in der View/Ordner
	Print "Insgesamt " & numDocsN & " MA-Dokumente im NAB"
	
	Dim numDocsK As Long	
	numDocsK = viewK.AllEntries.Count	'Anzahl der Dokumente in der View/Ordner
	Print "Insgesamt " & numDocsK & " MA-Dokumente in FIRMA Kontakten"
		
	'09.01.2012 NAB Lauf----------------------------------------------------
	Dim docN As NotesDocument
	Dim docK As NotesDocument


	
	'Schleife über alle NAB Dokumente
	Set docN = viewN.GetFirstDocument()
	Dim nN As Long 'Anzahl der aus NAB kopierten Dokumente
	nN = 0
	Dim result As String 
	While Not docN Is Nothing
'	Call viewN.Refresh()	'bringt nichts
		
		'Schleife über alle FIRMA Kontakte Dokumente
		Set docK = viewK.GetFirstDocument()
		
		While Not docK Is Nothing 
'			Call viewK.refresh()	'bringt nichts
			If docN.FirstName(0) & docN.LastName(0) = docK.FirstName(0) & docK.LastName(0) Then
				result = "OK"	
				GoTo weiter			
			End If
			Set docK = viewK.GetNextDocument(docK)
		Wend
		
		'Dokument aus NAB wird kopiert
		If result <> "OK" Then
			Print docN.FirstName(0) & " " & docN.LastName(0) & " muss kopiert werden."
'			Call docN.CopyToDatabase(dbK) 'wegen Fehlermeldung bei einem modifizierten Dokument anders realisiert
			Dim newDoc As NotesDocument
			Set newDoc = docN.CopyToDatabase( dbK )
			newDoc.FIRMANAB = "FIRMANAB" 'setzten um danach newDoc's zu finden
			
			Print docN.FirstName(0) & " " & docN.LastName(0) & " kopiert"
			nN = nN +1			
		End If
		
weiter:			
		Set docN = viewN.GetNextDocument(docN)
		result = ""
	Wend 

' es geht noch weiter...
« Letzte Änderung: 10.01.12 - 13:23:13 von Bruce Willis »
nobody is perfect but i'm pretty close 

Offline Bruce Willis

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.002
  • Geschlecht: Männlich
  • Wer nicht wagt...
Das Problem scheint schon 10 Jahre lang bei IBM zu bestehen...

"Someone else modified this document at the same time"

http://www-10.lotus.com/ldd/46dom.nsf/dfcbf9e2586b6dce852569fc0075882b/4279dd325a4b9e2585256a420051c049?OpenDocument

 :-:

« Letzte Änderung: 10.01.12 - 09:32:08 von Bruce Willis »
nobody is perfect but i'm pretty close 

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Was willst Du mit dem Kopieren des Dokuments nach Modifikation erreichen? Vielleicht scheitert Notes daran, weil das schon vorhandene Dokument (gleiche UniversalID) noch einmal kopiert werden soll. Offiziell soll in dem Fall eine neue UniversalID vergeben werden, aber vielleicht klappt das in Deinem Umfeld nicht korrekt (habe da keine Erfahrung, da ich nicht NotesDocument.CopyToDatabase verwende).

Die dargestellte Routine taugt eigentlich nur zur einmaligen Befüllung einer Datenbank, zum Abgleich ist sie erstens nicht geeignet und zweitens wenig performant.

Zur Perfomance bei schon vorhandenen Dokumenten:

Angenommen Du hast in beiden Datenbanken 100 Dokumente, die keine Abweichung haben. Du durchläufst in der Quelldatenbank eine Ansicht mit 100 Dokumenten. Zu jedem Dokument durchläufst Du in der Zieldatenbank ebenfalls eine Ansicht mit 100 Dokumenten, um das passende Dokument zu finden. Im Schnitt wirst Du nach jeweils 50 Dokumenten fündig, das bedeutet, Du liest 5000 (100 x 50) Dokumente, um festzustellen, dass die Dokumente identisch sind.

Zum Abgleich bei vorhandenen Dokumenten:

Du prüfst, ob ein Dokument mit dem Namen der Person schon vorhanden ist. Wenn nicht, wird das Dokument aus der Quelldatenbank in die Zieldatenbank kopiert. Bei Änderung des Namens hast Du danach in der Zieldatenbank ein Dokument mit dem alten Namen und eines mit dem neuen. Das ist sicher nicht gewollt. Was machst Du mit Dokumenten, die seit dem letzten Abgleich aus der Quelldatenbank gelöscht wurden? Sollen die erhalten bleiben oder gelöscht werden? Auch Dein Vergleich mit Vorname und Name ist recht wackelig, was passiert, wenn zwei Personen den gleichen Namen haben?

Lösungsansatz:

Ich würde mir einen eindeutigen Schlüssel zum Mitarbeiterdokument schaffen, das kann entweder direkt die UniversalID sein, oder Du erzeugst in dem neuen Dokument ein Item, in das du die UniversalID des Quelldokuments aufnimmst, eventuell, falls Du mit mehreren Quellen abgleichst, auch noch einen Schlüssel zur Quelle, z.B. die ReplicaID.
Beim Abgleich liest Du die bereits vorhandenen Zieldokumente in eine Liste ein (List As NotesDocument), Identifier ist der eindeutige Schlüssel (dazu brauchst Du nur einmal die Dokumente im Ziel zu lesen). Dann gehst Du durch die Quelldokumente und prüfst, ob in der Liste ein Dokument mit gleichem Schlüssel vorhanden ist (If IsElement (Liste (Identifier))). Wenn ja, vergleichst Du die relevanten Felder und korrigierst ggf. deren Inhalt. Danach entfernst Du das Dokument aus der Liste. Wenn nein, kopierst Du das Dokument in die Zieldatenbank. Schließlich hast Du in der Liste alle die Dokumente übrig, die nicht mehr in der Quelle vorhanden sind und kannst die löschen, falls das der Anforderung entspricht.

Offline Bruce Willis

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.002
  • Geschlecht: Männlich
  • Wer nicht wagt...
Zur Fehlermeldung:

http://www-01.ibm.com/support/docview.wss?uid=swg21096316

This issue was reported to Quality Engineering as SPR# ASHW4X9P8R and was fixed in Lotus Notes®/Domino 6.0.4, 6.5.2, 7.0, and later releases, by the addition of an optional notes.ini parameter. The following notes.ini parameter forces a new UNID to be created for a document after being copied to the destination database:

    CopyToDatabase_New_UNID=1


Workaround for versions prior to 6.5.2 and 6.0.4:
If the CopyToDatabase method is used to copy the same document (to the same database) more than once, the additional document copies will be given entirely unique UNIDs which will not repeat if the process itself is repeated. This fact can be used to work around this issue by calling the method twice and then removing the first document copied. The only possible detriment to the example below is the additional deletion stubs that are created. This method is still recommended as it is very straightforward and reliable.

    Set tempdoc=doc.copytodatabase(db)
    Set newdoc=doc.copytodatabase(db)
    Call tempdoc.remove(True)
nobody is perfect but i'm pretty close 

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Das ändert aber nichts daran, dass Dein Verfahren m.E. an der Stelle falsch ist

Offline Bruce Willis

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.002
  • Geschlecht: Männlich
  • Wer nicht wagt...
Das ändert aber nichts daran...

Hallo Peter,

das ist mir klar, ich wollte zuerst mein Feedback liefern und dann bei Dir bedanken. Konnte aber nicht rechtzeitig, da ich unerwartete eilige Probleme fixen musste.

Vielen Dank für Deine ausführlichen Erklärungen und Deinen interessanten Vorschlag !

Ich probiere ihn heute oder morgen zu implementieren.

Gruß
Leo
nobody is perfect but i'm pretty close 

Offline ea234

  • Frischling
  • *
  • Beiträge: 1
Moin,

alternative Lösung: In der Zieldatenbank ein neues Notesdokument erstellen und das zu kopierende Dokument dort reinschreiben.


Private Function notesCopyToDatabdaseV2( pNotesDokument As NotesDocument, pNotesDatenbank As NotesDatabase, pNotesOrdner As String ) As Boolean

On Error Goto errNotesCopyToDatabdaseV2:
    '
    ' Dokument in Ziel-DB
    ' Die Variable fuer das zu erstellende Ziel-Dokument ist Funktionsglobal, da
    ' dieses Dokument bei einem Fehler aus der Ziel-Datenbank geloescht wird.
    '
    Dim neues_notes_dokument As NotesDocument

    set neues_notes_dokument = Nothing

    notesCopyToDatabdaseV2 = false

    If ( pNotesDatenbank Is Nothing ) Then
        '
        ' Zieldatenbank nicht gesetzt. Es wird keine Kopie erstellt.
        '
    Else

        call print( "CopyToDatabaseV2: Erstellung des Zieldokumentes " )

        '
        ' Notesfunktion "Copytodatabase"
        '
        ' Fehler: "Someone else modified this document at the same time"
        '         "Ein anderer Benutzer hat dieses Dokument zur gleichen Zeit geändert"
        '
        ' http://atnotes.de/index.php?action=printpage;topic=53412.0
        '>
        '>   Zur Fehlermeldung:
        '>
        '>   http://www-01.ibm.com/support/docview.wss?uid=swg21096316
        '>
        '>   This issue was reported to Quality Engineering as SPR# ASHW4X9P8R and was fixed
        '>   in Lotus Notes/Domino 6.0.4, 6.5.2, 7.0, and later releases, by the addition of
        '>   an optional notes.ini parameter. The following notes.ini parameter forces a new
        '>   UNID to be created for a document after being copied to the destination database:
        '>
        '>       CopyToDatabase_New_UNID=1
        '>
        '>   Workaround for versions prior to 6.5.2 and 6.0.4:
        '>   If the CopyToDatabase method is used to copy the same document ( to the same database )
        '>   more than once, the additional document copies will be given entirely unique UNIDs
        '>   which will not repeat if the process itself is repeated. This fact can be used to
        '>   work around this issue by calling the method twice and then removing the first document
        '>   copied. The only possible detriment to the example below is the additional deletion
        '>   stubs that are created. This method is still recommended as it is very straightforward
        '>   and reliable.
        '>
        '>       set  tempdoc  = doc.CopyToDatabase( db )
        '>
        '>       set  newdoc   = doc.CopyToDatabase( db )
        '>
        '>       Call tempdoc.Remove( true )
        '>
        '
        ' FAZIT: Die Funktion "Copytodatabase" von Lotus-Notes bereitet nur mehr Probleme als
        '        was sie hilft.
        '
        '        Sich auf eine Einstellung in der INI-Datei zu verlassen ist eine schlechte Loesung
        '
        '        Das zweimalige kopieren schlug fehl. Das ist wahrscheinlich auf eine zerspielte Umgebung
        '        zurueckzufuehren, aber zeigt, dass man sich auch darauf nicht verlassen sollte.
        '
        '
        ' LOESUNG: Es wird in der Zieldatenbank ein neues Notesdokument erstellt, welches
        '          die Notesfelder des zu kopierenden Dokumentes bekommt.
        '
        'set neues_notes_dokument = pNotesDokument.CopyToDatabase( pNotesDatenbank )
        '


        set neues_notes_dokument = pNotesDatenbank.CreateDocument()

        If ( neues_notes_dokument Is Nothing ) Then

            call print( "CopyToDatabaseV2: neues_notes_dokument Is Nothing - Es konnte kein Dokument in der Zieldatenbank erstellt werden. CTDF1" )

        Else

            call print( "CopyToDatabaseV2: neues_notes_dokument gesetzt - Neues Dokument wurde in der Zieldatenbank erstellt. CTDOK1" )

            '
            ' Kopieren der Inhalte
            ' Alle Notesfelder aus dem Quelldokument werden in das neu erstellte
            ' Dokument in der Zieldatenbank kopiert. Die Universal-ID wird vor
            ' dem Kopieren gesichert, damit diese ID nach dem kopieren wieder
            ' restauriert werden kann.
            '
            ' Ziel ist es hier, alle Items kopiert zu haben, aber die neue ID zu behalten.
            '
            Dim dokumenten_id_ziel_dok As String

            dokumenten_id_ziel_dok = neues_notes_dokument.UniversalID

            Call pNotesDokument.CopyAllItems( neues_notes_dokument, true )

            neues_notes_dokument.UniversalID = dokumenten_id_ziel_dok

            Call neues_notes_dokument.save( true, true )

            DoEvents

            '
            ' Optionales verschieben in einen Ordner
            '
            If ( pNotesOrdner = "" ) Then

                '
                ' Wurde kein Ordner uebergeben, wird das Funktionsergebnis
                ' auf TRUE gestellt.
                '
                notesCopyToDatabdaseV2 = true

            Else

                '
                ' Wurde ein Ordner uebergeben, wird das Dokument in den
                ' Order ueberstellt. Wird die Funktion "PutInFolder" ohne
                ' Fehler ausgefuehrt, wird das Funktionsergebnis auf
                ' TRUE gestellt.
                '
                Call neues_notes_dokument.PutInFolder( pNotesOrdner, true )

                call print( "CopyToDatabaseV2: neues_notes_dokument in Ordner verschoben. CTDOK3" )

                notesCopyToDatabdaseV2 = true

            End If

        End If

    End If

EndFunktion:

    On Error Resume Next

    '
    ' Dokumenteninstanz auf Nothing setzen
    '
    set neues_notes_dokument = Nothing

    DoEvents

    Exit Function

errNotesCopyToDatabdaseV2:

    call print( "Fehler: errNotesCopyToDatabdaseV2: " & Err & " " & Error  & " " & Erl )


    '
    ' Fehlerbehandlung
    ' Ist es bei der Funktion "PutInFolder" zu einem Fehler gekommen, wird das
    ' kopierte Notes-Dokument in der Zieldatenbank geloescht.
    '
    ' Die Fehlerbehandlung wird auf "On Error Resume Next" gestellt.
    ' Es wird nur ein Versuch gemacht, das kopierte Dokment zu loeschen.
    '
    If ( neues_notes_dokument Is Nothing ) Then

        call print( "CopyToDatabaseV2: Fehler CTDF1B: neues_notes_dokument Is Nothing - Dokument wurde nicht in die Zieldatenbank kopiert. " )

    Else

        On Error Resume Next

        If ( neues_notes_dokument.Remove( true ) ) Then

            call print( "CopyToDatabaseV2: Fehler CTDF2A: neues_notes_dokument.Remove() = OK " )

        Else

            call print( "CopyToDatabaseV2: Fehler CTDF2B: Das schon kopierte Notesdokument konnte nicht aus der Zieldatenbank entfernt werden. DOPPELTES_DOKUMENT_IN_ZIELDATENBANK" )

        End If

    End If

    Resume EndFunktion

End Function

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz