Cursor einer Tablebox auf einen bestimmten Datensatz setzen

17. Mai 2006 20:32

Jetzt brauch ich mal Eure Hilfe:

Ich habe in der Tabelle 168 ein zusätzliches Feld namens Index eingefügt, und mit der Job No´. zusammen einen Key erstellt, damit man in der Form 212 danach sortieren kann.
In der Form ist dieses Feld an erster Stelle zu sehen.
Wenn man nun in dieses Feld als erstes was einträgt, wird der Datensatz mit leeren Primärschlüsselfeldern angelegt. Da ein umbenennen in dieser Tabelle nicht möglich ist, kommt man nicht weiter, ohne den Arbeitsfluss zu stören.
Abhilfe ist die Eigenschaft delayed insert, die erst beim verlassen des Datensatzes speichert.
Nur wenn der Kunde aus Versehen auf die Cursor Up oder down Taste drückt, kann er wieder von vorne anfangen.
Aus diesem Grund hab ich im OnNewRecord Trigger eine InputForm für die Primärschlüsselfelder und das Indexfeld mit

Code:
if inputform.runmodal=action::OK then inputform.getrecord(rec)

gestartet und dieser auch schon die Jobnummer übergeben.
In dieser Form muss der Kunde zwar nochmal f3 drücken um einen neuen Datensatz anzulegen, aber das ist noch nicht so tragisch.
Jetzt mein Problem:
Wenn diese Form mit OK geschlossen wird, wird der Datensatz in die Tabelle eingefügt, gleichzeitig erscheint an Cursorposition der gleiche Datensatz nochmal, mit der *-Anzeige eines neuen Datensatzes, wo nur die Schlüsselfelder gefüllt sind.
wenn man nun die Zeile verläßt kommt die Meldung mit dem Rename.
Wenn man ESC drückt, ist man auf der Zeile, von der aus man F3 gedrückt hatte.

Wie bekomme ich nun den Cursor in den neuen Datensatz?
darin dann auf das erste zu editierende Feld zu springen ist mit currform.description.activate kein Problem, aber die richtige Zeile ist das Problem.
ein getrecord ist genausowenig erfolgreich wie ein get(Feld1,feld2, usw....)
der Cursor bleibt einfach in der Zeile wo er war.
Ein currform.update im Trigger führt zu einem internen Fehler 101 in Modul 60 (ist sogar in der doku als erste Ursache für diesen Fehler angegeben). Ein currform.update(false) also ohne speichern, führt zum völligen Absturz von Navision.

HILFE!!!
mein Chef braucht das morgen mittag um die Lösung dem Kunden zu zeigen..... ich befürchte, das wird nix, ....

17. Mai 2006 20:45

Ohne es jetzt direkt auszuprobieren kann ich dir folgende Tipps geben, welche du mal ausprobieren kannst:
  1. Du hast im Rec bereits den richtigen Datensatz.
    Versuche mal mit Rec.GET(); bzw. Rec.FIND(); herum.
  2. Probiere (sofern möglich) verschiedene Trigger aus, von denen du den FORM.RUNMODAL aufrufst.
    (Das Ganze am besten auch noch in Kombination mit CurrForm.UPDATE(FALSE); und CurrForm.UPDATE(TRUE);

Ich weiß, ist jetzt nicht sehr vielversprechend, aber das sind auch bei mir immer die ersten Schritte, die ich bei derartigen Problemen ausprobiere.

17. Mai 2006 20:51

ich muss schon den onNewRecord zum Aufruf nehmen, denn bei f3 oder Klick in eine leere Zeile oder bei Neuanlage eines Projekts muss die Form aufgehen , also jedesmal wenn ein neuer Datensatz angelegt werden soll.
Dass rec.get nicht geht, hab ich ja gerade schon erwähnt, find hab ich aber auch schon probiert. und update führt in diesem Trigger zum Absturz

17. Mai 2006 20:55

ich hab auch schon überlegt, die Form 212 danach nochmal zu öffnen nachdem ich den Tableview gesetzt habe und dann die ursprüngliche zu schliessen. aber dann wird ja auch die neu geöffnete mit geschlossen, das bringts also nicht.

17. Mai 2006 21:00

jetzt hab ich gerade rec.get statt nur get im Trigger versucht und schon wollte Navision wieder was an Microsoft melden und nach Hause gehen.
Sche....
Das Rec.get() im OnActivateForm führt auch zum Absturz, genau wie nur get().

17. Mai 2006 21:12

Hat vielleicht überhaupt nichts mit deinem Problem zu tun, aber vielleicht hilft dir das auf den richtigen Weg:
(Bei der Kürze der Zeit kann man ja nur "in's Blaue schießen".)

Ich hatte mal die Anforderung, dass ein Debitor nur nach einem Klick auf einen [OK]-Button in der Datenbank gespeichert werden darf.
Dies hatte ich dann wie folgt gelöst:
Code:
TempCust.INIT;  // Temporary = TRUE
TempCust."No." := '';
TempCust.<Field4711> := [...];  // Vorbelegung einiger Felder
TempCust.INSERT(FALSE);  // Nicht den OnInsert-Trigger ausführen
IF Form.RUNMODAL(Form::"21",TempCust) = ACTION::LookupOK THEN BEGIN
  Cust := TempCust;
  Cust.INSERT(TRUE);
  Rec := Cust;

  // Alternativ könnte vielleicht auch folgendes funktionieren:
  // Rec := TempCust;
  // Rec.INSERT(TRUE);
END;

Da der Datensatz nun bereits angelegt wurde, muss der OnInsert()-Trigger (durch ein EXIT(FALSE);) abgebrochen werden.

17. Mai 2006 21:17

selbst im Timer stürzt Navision bei get() ab....
ICh habe nach rückkehr des Runmodal eine Boolean auf true gesetzt, im Ontimer bei gesetzer Boolean den get gemacht und dann die Boolean zurückgesetzt.
Absturz!
Ich glaube ich reboote mal eben....

Workaround

18. Mai 2006 03:17

Auch der Reboot hat nicht wirklich geholfen.
Ich habe das jetzt anders gelöst:
Ich öffne eine Form ohne Tabellenbezug, auf der ich die 7 Felder des primary keys mit entsprechenden Variablen abbilde.
Den Textxboxen weise ich die entsprechende Tablerelation zu, damit man auch hier mittels Lookup die Werte holen kann.
In Abhängigkeit des Typs blende ich dann eine von 4 Textboxen für das Feld "No." ein, das mit der jeweiligen Tablerelation verknüpft ist.
Das Feld Variantencode wird nur eingeblendet, wenn die Art "Artikel" ist.
Tablerelation für dieses Feld ist "Variant code".code, leider kann ich bei einer Variablen nicht die Syntax verwenden, die bei einem Tabellenfeld möglich ist, ich kann also hier nicht auf die Artikelnummer filtern. Also hab ich in der Lookuptabelle kurzerhand das Feld Artikelnummer mit eingeblendet, so dass der Anwender die richtige Variante heraussuchen kann.
Nach rückkehr aus der Runmodal-Funktion mit Action::ok rufe ich von der Form 212 eine Funktion auf der Inputform auf, die mir die Werte der Variablen zurückgibt, die ich dann in den neuen Datensatz schreibe.

Da das positionieren des Cursors auf ein bestimmtes Feld mit currform.<Feld>.activate nicht funktioniert (Befehle im onActivate-Trigger des Feldes werden zwar aufgerufen, Cursor landet trotzdem im ersten Primärschlüsselfeld), habe ich im onActivate-Trigger des 2. Schlüsselfeldes den Befehl currform.Startdatum.activate eingetragen, so dass durch einmaliges drücken der TAB-Taste der Cursor sofort auf das Feld Startdatum weiterspringt.
Im OnActivate-Trigger dieses Feldes steht dann currform.saverecord, so dass der Datensatz gespeichert wird und das editieren ganz normal weitergehen kann.
Dass der activate Befehl innerhalb des onNewRecord-Triggers die Befehle im Trigger des Zielfeldes ausfüllt, habe ich daran gemerkt, dass Navision wieder abschmiert, wenn direkt das Startdatum angesprungen wird.

26. Mai 2008 11:03

Hallo,

ich hab ein ähnliches Problem gehabt - bei mir ging es darum, den Cursor beim Öffnen des Formulars auf eine Default-Zeile zu setzen und danach einem Button den Focus zu geben. Im OnOpenForm mache ich dafür folgendes:

Code:
//Quick'n Dirty auf Urlaub setzen
Rec.FINDFIRST;
REPEAT
  IF Arbeitszeittyp = 'U' THEN BEGIN
    CurrForm.btnEintragen.ACTIVATE;

    EXIT;
  END;
UNTIL (Arbeitszeittyp = 'U') OR (Rec.NEXT = 0);



Rec ist hierbei nicht gefiltert, ich suche einfach nach einem Wert 'U' (für Urlaub ^^) in der dem Form zugrunde liegenden SourceTable. Bei mir funktioniert das so einwandfrei.

Vielleicht bringt dich das irgendwie näher ran.

Gruß

Carsten
Zuletzt geändert von CaddyM am 26. Mai 2008 17:06, insgesamt 1-mal geändert.

26. Mai 2008 11:07

Bei deinem eigentlichen Problem müsste ich raten, aber was ich noch einwerfen wollte:
FINDFIRST niemals mit REPEAT...UNTIL! Nutze statt dessen FIND('-').

26. Mai 2008 11:49

@Natalie
wieso denn find('-')?
gerade ist doch fast der gesamte Standard von find('-') auf Findset umgestellt?

26. Mai 2008 11:53

tba hat geschrieben:@Natalie
wieso denn find('-')?
gerade ist doch fast der gesamte Standard von find('-') auf Findset umgestellt?

Aber nicht in jeder Version von 4.0 :-)

26. Mai 2008 14:13

ok, war in der "falschen Version" :oops: