[Gelöst] Update Record mit C/FRONT

28. Juli 2009 15:39

Hallo nochmal,

ich habe folgendes Problem, ich möchte einen gefunden Datensatz ändern und das ganze mit C/FRONT, dazu habe ich folgenden Code erzeugt:
Code:
            CurrentTable                = CFrontDotNet.Instance.OpenTable(18); //set current table
            CurrentRecord               = CFrontDotNet.Instance.AllocRecord(CurrentTable); //allocate record in current table
            int FiledNoID               = CFrontDotNet.Instance.FieldNo(CurrentTable, "search name");
                 //fetch No. of field "search name" - hack for problem while using field "id"
            int FieldNoName             = CFrontDotNet.Instance.FieldNo(CurrentTable, "name"); //fetch No. of field "name"
            bool recordFound            = false;
            bool transactionSuccessful  = false;
               
                try
                {
                    CFrontDotNet.Instance.SetFilter(CurrentTable, FiledNoID, customer.Id.ToString());
                    recordFound = CFrontDotNet.Instance.FindFirstRecord(CurrentTable, CurrentRecord);
                }
                catch (CFrontException cfrontEx)
                {
                    recordFound = false;
                }
                CFrontDotNet.Instance.BeginWriteTransaction();
                if (recordFound == true)
                {
                    Console.WriteLine("recordfound true für: " + customer.Id);
                    CFrontDotNet.Instance.InitRecord(CurrentTable, CurrentRecord);
                    CFrontDotNet.Instance.StringToField(CurrentTable, CurrentRecord, FieldNoName, "peter");
                    transactionSuccessful = CFrontDotNet.Instance.InsertRecord(CurrentTable, CurrentRecord);
                    if (transactionSuccessful == true) Console.WriteLine("success");
                }
                else
                {     
                    Console.WriteLine("recordfound false für: " + customer.Id); 
                }
           
            if (transactionSuccessful == false)
            {
                CFrontDotNet.Instance.AbortWriteTransaction();
            }
            else
            {
                CFrontDotNet.Instance.EndWriteTransaction();
            }
            CFrontDotNet.Instance.FreeRecord(CurrentRecord);
            CFrontDotNet.Instance.CloseTable(CurrentTable);
            CFrontDotNet.Instance.CloseCompany();
            CFrontDotNet.Instance.CloseDatabase();
            CFrontDotNet.Instance.DisconnectServer();
            CFrontDotNet.Instance.Dispose();

Eigentlich sollte es doch damit gehen. Ich führe den oberen try block in einer foreach schleife aus, in der die Daten aus einem unserer Webservices kommen. Der matched bei derzeit einem user. Also müsste er an der stelle bei dem customer den namen auf peter ändern. Tut er aber nicht :-)

Sorry aber ich bin noch Einsteiger in c/front. Das mit dem Search Name hängt mit nem anderen Post zusammen und ist einfach nur nen minihack für die dauer bis ich das andere Problem gelöst habe. In Search Name steht bei einem customer in der tabele seine customer id drin. Später wird das natürlich über nen nummernkreis in id gelöst.

Gruß
René
Zuletzt geändert von kockiren am 29. Juli 2009 14:46, insgesamt 1-mal geändert.

Re: Update Record mit C/FRONT

28. Juli 2009 22:36

Hallo René,

ich habe leider keine Erfahrung mit der .net- Version von C/Front, kann aber sicherlich zu C/Front im allgemeinen was sagen.

Zu Anfang frage ich mich, warum du am Anfang einen Filter auf 'Search name' setzt, ohne vorher einen SetCurrenkey durchzuführen, das bringt bei großen Tabellen einiges.

Wenn du das Feld 'Name' änderst, kannst du den Datensatz immer nur ändern aber nicht einfügen, da der Primärschlüssel nicht geändert wurde.

Gruß, Fiddi

Re: Update Record mit C/FRONT

28. Juli 2009 22:49

Hallo Fiddi,

danke für die Antwort. Also erstmal vorweg, ist mein erstes C/FRONT Script und ich finde nur spärliche Informationen zur Erstellung eines solchen Programms. Zu deinen Anmerkungen.
Also wenn ich das richtig verstehe dann setz ich mit der Funktion setcurrentkey nen Zeiger auf das Feld welches ich auslesen möchte, also müsste ich dann ne 4 für das 5. Feld in der Tabelle setzen. Weiß jetzt nicht genau an welcher Stelle search name steht. Gut aber das sollte sich ja nur bei großen Tabellen auswirken, ich habe ja nur 10 Einträge in meiner Customer Table. Er findet ja auch die korrekten Datensätze (was ich durch meine kleine Debugausgabe sehe) aber er speichert sie nicht.

Gut also das mit dem Ändern aber nicht Einfügen versteh ich nicht. Ich habe einen Wert eines Datensatzes geändert, befindet sich ja alles noch im Buffer und nicht in der Datenbank. Wenn ich dann aber
Code:
CFrontDotNet.Instance.EndWriteTransaction();
aufrufe dann sollte er doch den Buffer in die Datenbank schreiben. Dachte ich.

Was meinst du mit dem geänderten Primärschlüssel? Der Ändert sich ja nicht da es ja die Kundennummer ist. Es gibt zwei Systeme in denen Daten geändert werden können, im Webportal(eigenentwicklung) durch den Kunden oder durch einen Kundenbetreuer bei uns im Hause. Also die Kundennummer ändert sich ja in keinem Fall. Ich dachte nun das wenn ich nen Datensatz änder und mit der selben No_ inserte dann macht er nen Update? Gibt es für nen Update ne eigene Funktion, ich konnte bisher noch nix finden.

Gruß
René

Re: Update Record mit C/FRONT

28. Juli 2009 23:13

Hallo René,

Setcurrentkey definiert, wie der Name schon sagt, über welchen Schlüssel du auf die Tabelle sortieren willst. Setfilter und Setrange können schneller Daten finden, wenn die Felder auf die man Filtert auch Bestandteil des aktiven Schlüssels sind.

Da du den Primärschlüssel der Customer-Tabelle 'No.' nicht änderst, würde der Datensatz an der gleichen Stelle eingefügt werden, wie der allte, das geht aber nicht. Deshalb musst du den Datensatz ändern, und nicht einfügen.

Gru

Re: Update Record mit C/FRONT

29. Juli 2009 09:47

Hey Fiddi,

nochmal Danke für deine Antwort. Also ich hab es jetzt mal mit modifyRec probiert, muss mal noch nen bissel probieren bekomme derzeit ne Fehlermeldung das der Debitor mit Nr. nicht existiert, aber liegt wahrscheinlich daran das der Datensatz nicht komplett in den Buffer geschrieben ist und somit bei Modify die leeren Felder eingefügt werden sollen, was natürlich nicht geht. Ich probier mal noch nen bissel dran rum. Falls meine Einschätzung völlig falsch ist dann bitte bescheid sagen :-)

Das mit dem setcurrentkey hab ich nun verstanden. Ansonsten nochmal danke.

Gruß
René

Re: Update Record mit C/FRONT

29. Juli 2009 10:03

du hast natürlich vollkommen Recht. Du musst vorher nochmal sowas wie Find ausführen, damit dein Datensatz auch im Buffer ist, damit er verändert werden kann.

Gruß, Fiddi

Re: Update Record mit C/FRONT

29. Juli 2009 10:32

Hey Fiddi,

also das hab ich nun auch so gemacht aber es will immer noch gehen, ich hab jetzt folgendes gemacht:
Code:
int[] key = {0,1};
key[0] = FieldNoID;
key[1] = 0;
CFrontDotNet.Instance.SetCurrentKey(CurrentTable, key);
CFrontDotNet.Instance.SetFilter(CurrentTable, FieldNoID, customer.Id.ToString());
recordFound = CFrontDotNet.Instance.FindFirstRecord(CurrentTable, CurrentRecord);
if (recordFound == true )
{
CFrontDotNet.Instance.BeginWriteTransaction();
CFrontDotNet.Instance.StringToField(CurrentTable, CurrentRecord, FieldNoName, customer.Company.ToString());
transactionSuccessful = CFrontDotNet.Instance.ModifyRecord(CurrentTable, CurrentRecord);
CFrontDotNet.Instance.EndWriteTransaction();
}
...

Es sollte doch nun in den 10 Customer Datensätzen in meiner Customer Tabelle der Name bei den Matches mit der ID geändert werden.

Da tut sich aber nix, kein Fehler aber auch keine geänderten Datensätze, in den if Zweig springt er rein, hab mir da nen kleines Console.write reingepackt. Ich komm einfach nicht weiter, wenn jemand ne Idee hat wie ich das vielleicht debuggen kann um den Fehler näher zu kommen, würd ich mich sehr freuen :-)

Gruß
René

Re: Update Record mit C/FRONT

29. Juli 2009 11:12

Hallo René,

NAV ist kein SQL, du musst bitteschön jeden Datensatz einzeln ändern (repeat until next=0).
Außerdem benötigt SETFILTER eine Filteranweisung , die dann mit den übergebenen Parametern fütterst, (Schau dir mal Setfilter im C/SIDE- Referenceguide an (NAV-Hilfe)).

Wie ich schon sage ohne C/AL-Kenntnisse bist du auch in C/Front aufgeschmissen :-( .

Gruß, Fiddi

Re: Update Record mit C/FRONT

29. Juli 2009 11:25

Okay also bin ich da völlig falsch ran gegangen. Wenn ich dich nun richtig verstanden hab, muss ich alle Felder einzeln durchgehen auch wenn ich nur den Namen ändern möchte? Wie funktioniert denn das einlesen eines Datensatzes in den Buffer. Ich glaube ich hab gerade massive Verständnissprobleme :-) Ich wüsste mein C/FRONT verständniss dennoch erhöhen da ich sonst den Datenwrapper für unseren Webservice nicht schreiben kann. Dazu würde ich einfach nur Testweie eine Bidirektionale Verbindung herstellen, wenn das klappt kann ich dann das CSV so schreiben das nur Änderungen auftauchen und dann ... naja das und dann kommt dann später wenn ich mit C/AL weiter bin :-)

Also nochmal zu meinem Problem, du sagtest ich müsste jeden einzeln Datensatz ändern. Also ich geh jetzt mal von einem Minimalbeispiel aus. Ich habe in NAV einen Customer mit ID 123 angelegt, Name ist Musterfirma und Kontakt Max Mustermann. Nun möchte ich per C/FRONT den Namen auf Malkasten GbR ändern.

Mein vorgehen sollte doch dann folgendermaßen aussehen:
- setze Key auf FeldID von No.
- setze filter auf No. = 123
- finde ersten Datensatz auf den Filter passt
- initialisiere Schreib Zugriff
- schreibe neuen Wert in spalte fieldNo des Feld Name in gepufferten Datensatz
- schreibe gepufferten Datensatz in Tabelle (NAV)

An welcher stelle sollte denn nun "repeat until next = 0" erfüllt sein. Muss ich alle Felder der Tabelle customer durchlaufen? Irgendwie komm ich nicht dahinter.


Gruß
René

Re: Update Record mit C/FRONT

29. Juli 2009 12:06

Das st nur nötig, wenn du mehr als einen Datensatz ändern willst. Dann kommt die Schleife um die beiden Schreibzugriffe.

Gruß, Fiddi

Re: Update Record mit C/FRONT

29. Juli 2009 14:45

Hallo Fiddi,

nochmals danke für deine Hilfe, nun klappt alles. Und nun seh ich auch wo die von dir beschriebenen Probleme liegen, aber bin schon froh nen Schritt weitergekommen zu sein.

Das hab ich bei dem Minimalbeispiel vergessen:
Code:
CFrontDotNet.Instance.EndWriteTransaction();


Gruß
René