Doppelter Schlüssel bei Beleg.Save()

bseidel

Neues Mitglied
Hallo liebe Foren-Mitglieder.

Ich habe eine DLL vorliegen, bei der ein Beleg mit sämtlichen Eigenschaften auf einen anderen Kunden kopiert wird.
Allerdings bekomme ich immer einen Fehler bei der Save-Methode des Beleg-Objekts. Fehler ist folgender:

Es ist eine Ausnahme beim Datenzugriff aufgetreten: Sagede.OfficeLine.Data.CommandExecutionException: Es ist ein Fehler bei der Ausführung eines Commands aufgetreten.
Fehler: Verletzung der PRIMARY KEY-Einschränkung "PK_KHKVKVorgaengePositionen". Ein doppelter Schlüssel kann in das dbo.KHKVKVorgaengePositionen-Objekt nicht eingefügt werden. Der doppelte Schlüsselwert ist (0, 1).

Das heißt für mich so viel wie: Eins der beiden Primärschlüssel der Tabelle VorPosID oder Mandant werden doppelt befüllt.
Wie kann ich das verhindern? Eigentlich generiert die Methode doch selbst im Hintergrund den Vorgang und die Vorgangspositionen, oder? Zumindest greife ich hier nicht selber ein und gebe ihm irgendwelche Werte mit.
 

GlanS

Neues Mitglied
Hallo,

die Fehlermeldung sagt aus, dass beim Einfügen von neuen Datensätzen in die Tabelle KHKVKVorgaengePositionen zu einer Schlüsselverletzung kommt. Der Primärschlüssel besteht aus VorPosID und Mandant. Es ist nicht möglich neue Datensätze mit VorPosID = 0 und Mandant = 1 hinzuzufügen.

In der DLL ist anscheinend beim Hinzufügen von kopierten Positionen zum neuen Beleg ein Fehler passiert.
Ich tippe mal, dass im Beleg eine Textposition ist und die Textposition beim Initialisieren der Belegposition als Artikelposition definiert wurde.
Aber Näheres kann man nur durch die Einsicht in den Quellcode sagen. Ist es möglich den Quellcode von der Stelle hochzuladen?

Beste Grüße
 

bseidel

Neues Mitglied
Hi, danke für die schnelle Antwort. Eigentlich füge ich alle Positionen anhand des Ursprungsbeleg-Handles hinzu:

C#:
neuerBeleg.AddBelegPositionen(ursprungBeleg.Handle, true);

                foreach (var belPos in neuerBeleg.Positionen)
                {
                    if (belPos.Positionstyp == Positionstyp.Alternativ)
                    {
                        belPos.Positionstyp = Positionstyp.Artikel;
                    }
                }

                neuerBeleg.PrepareForDataService();

                if (neuerBeleg.Validate() == false)
                {
                    throw new Exception($"Validate gescheitert!\n {neuerBeleg.Errors.GetDescriptionSummary()}");
                }

                if (neuerBeleg.Save(true) == false)
                {
                    throw new Exception($"Fehler beim Speichern\n {neuerBeleg.Errors.GetDescriptionSummary()}");
                }

                return neuerBeleg.BelegnummerFormatiert;
 

GlanS

Neues Mitglied
probiere mal nachdem die Positionen gesetzt wurden die Vorgangspositionen neu zu ermitteln:

neuerBeleg.SetVorgangsHandleWithCheck(0, false);


und ich würde noch die Vorgangspositionsreferenzen zurücksetzen:
foreach (Sagede.OfficeLine.Wawi.BelegEngine.BelegPosition belegPosition in (Collection<Sagede.OfficeLine.Wawi.BelegEngine.BelegPosition>) neuerBeleg.Positionen)
{
if (belegPosition.Positionstyp == Sagede.OfficeLine.Wawi.Tools.Positionstyp.Artikel | belegPosition.Positionstyp == Sagede.OfficeLine.Wawi.Tools.Positionstyp.Alternativ)
belegPosition.VorgangspositionsReferenzen = new BelegVorgangspositionsReferenzCollection();
}
 

bseidel

Neues Mitglied
probiere mal nachdem die Positionen gesetzt wurden die Vorgangspositionen neu zu ermitteln:

neuerBeleg.SetVorgangsHandleWithCheck(0, false);


und ich würde noch die Vorgangspositionsreferenzen zurücksetzen:
foreach (Sagede.OfficeLine.Wawi.BelegEngine.BelegPosition belegPosition in (Collection<Sagede.OfficeLine.Wawi.BelegEngine.BelegPosition>) neuerBeleg.Positionen)
{
if (belegPosition.Positionstyp == Sagede.OfficeLine.Wawi.Tools.Positionstyp.Artikel | belegPosition.Positionstyp == Sagede.OfficeLine.Wawi.Tools.Positionstyp.Alternativ)
belegPosition.VorgangspositionsReferenzen = new BelegVorgangspositionsReferenzCollection();
}
Das hat leider nichts bewirkt.
Komischerweise kommt der Fehler nur beim Übernehmen von Angeboten. Andere Belege funktionieren.
 

GlanS

Neues Mitglied
bei der Übernahme werden die Positionen kopiert, was zur Folge hat, dass die Angebotspositionen in dem neuen Beleg die VorgangspositionsHandleNew = 0 hat
-> Kopie von Angebotsbeleg auf Angebotsbeleg sollte mit der o. a. Funktion klappen
-> Kopie von Angebotsbeleg auf eine andere Belegart (also kein Vorverkaufsbeleg) klappt es nicht
probiere mal die VorPosID in dem Fall neu zu setzen
belPos.VorgangspositionsHandleNew = _mandant.MainDevice.GetTan(BelegeTable.get_VorgaengePositionen(neuerBeleg.Erfassungsart), _mandant.Id);
 

bseidel

Neues Mitglied
probiere mal die VorPosID in dem Fall neu zu setzen
belPos.VorgangspositionsHandleNew = _mandant.MainDevice.GetTan(BelegeTable.get_VorgaengePositionen(neuerBeleg.Erfassungsart), _mandant.Id);
Der VorgangspositionsHandleNew ist schreibgeschützt und kann leider nicht gesetzt werden.

[Edit]
Verzeihung bitte. Natürlich sollte ich das über die SetVorgangsPositionsHandleNew - Methode machen. Es scheint so auch zu funktionieren.
Ich werde noch weitere Tests durchführen, aber das sieht gut aus.

Vielen Dank @GlanS . Sie haben mir sehr geholfen.
 
Zuletzt bearbeitet:
Oben