Error while trying to update a sales order

poppinspoppins Member Posts: 647
edited 2015-08-02 in NAV Three Tier
Hi everyone,

For some particular customers(I added a flag blnXXX in tab 18 to differentiate them), I need to do the following:
In a Sales Order, when typing the sell-to Customer code, a page pops up with some values from the customer card (name, address,etc). When I modify them in the pop up page, the Sales Order must get updated with the values I introduced.
I placed the following code in the OnValidate trigger of Sell-to Customer No. in tab 36:
IF blnXXX THEN BEGIN
  CLEAR(pageXXX);
  pageXXX.SETTABLEVIEW(Rec);
  pageXXX.LOOKUPMODE :=TRUE;
  pageXXX.RUNMODAL;
END;
and the following code in the OnClose page trigger of the pop up page:
SalesHeader.GET(SalesHeader."Document Type"::Order,"No.");
SalesHeader."Sell-to Customer Name" :=NewCustName;
SalesHeader."Sell-to Customer Name 2" := NewCustName2;
.
.
.
IF SalesHeader.MODIFY THEN;
COMMIT;
When I run the Sales order, do a change in the pop up page and then click OK, I get the following erro message:
An attempt was made to change an old version of a Sales Header record.The record should be first reread from the database.This is a programming error.
The debugger stops at the following instruction in trigger OnValidate of Sell- to Customer No.(function SelltoCustomerNoOnAfterValidat) in Sales Order page:
CurrPage.UPDATE;
I can't figure out how to modify my code to make it work.
Any suggestions?

Thanks in advance :mrgreen:

Comments

  • jglathejglathe Member Posts: 639
    Hi poppins,

    it's a typical case of concurrently modifying the same record you're working on. The dialog window commits the changes to the database... but you're still in the C/AL context of the table (and the record) that was modified. This leads to an error when you try to write back to the database yourself, because you were modifying an outdated version of the record.

    How to do it correctly:

    - invoke your dialog on a temporary record (you give the record on the call)
    - close it with lookupok
    - use the changed fields from the temporary record to do what you want to do.

    in pseudocode:
    TempRec := Rec;
    TempRec.insert;
    if Page.runmodal(database::PageXXX,TempRec) = Action::LookupOK then begin
      //do your assignments
    end;
    

    There are some catches with temporary records. You should not use validation because you don't know where the code is executing on. So, in this case, I would probably have a look of what needs to be entered/selected, and either build a table for it (costly, should be justified) or use SetData/GetData methods on the page. You would need to write them yourself of course. With SetData/GetData the code would look like this:
    clear(PageXXX);
    PageXXX.SetData(your variables)
    PageXXX.lookupmode := true; //might be not necessary
    if PageXXX.runmodal = action::lookupok then begin
      PageXXX.GetData(your other variables);
      //do the modifications
    end;
    

    with best regards

    Jens
Sign In or Register to comment.