Another user has modified this record...

tompynationtompynation Member Posts: 398
Hi,

I got a question:

On the sales order, i added a button Process. When you click on this button a "Packing Order" gets created and opened.

In this new "Packing Order" i fill in some data, and then i Approve this "Packing Order" and close it.

When i close the "Packing Order" and see my "Sales Order" again then i receive the Error:

Another user has modified the record for this Sales Header after you retrieved it from the database...

Now i guess this is because of the following:

When i approve the new "Packing Order" following gets executed:


IF lv_SalesHeader.GET(lv_SalesHeader."Document Type"::Order,Ordernumber) THEN BEGIN
lv_SalesHeader.TESTFIELD("Linked Packing Order","Packinglist No.");
lv_SalesHeader.VALIDATE("No. Of Pallets",lv_NoOfPallets);
lv_SalesHeader."Packing List Current" := lv_SalesHeader."Packing List Current"::Completed;
lv_SalesHeader.MODIFY;
END;

So this modifies the sales header, for the order that is still open under the "Packing Order"

How could i solve this so i dont get this error message?

Comments

  • kapamaroukapamarou Member Posts: 1,152
    On your form, after the call you can add a Currform.UPDATE(FALSE);

    This will update the form without saving the record...
  • tompynationtompynation Member Posts: 398
    after which call should i place that Update(FALSE)?
  • kapamaroukapamarou Member Posts: 1,152
    After the Button process.

    Which means after the
    lv_SalesHeader.MODIFY;

    If your button is like this:

    OnPush:

    ..Some code here which leads to
    lv_SalesHeader.MODIFY;


    then at the end of the OnPush and after everything is completed place your update.
  • DenSterDenSter Member Posts: 8,304
    If lv_SalesHeader points to the current sales header record, why don't you just use Rec? If you have to use a different object, I would personally program that in such a way that I can pass Rec into it by reference, so that this new object is using the same record that I am looking at from my current object.
  • tompynationtompynation Member Posts: 398
    No, you guys dont understand me...

    This piece of code is on the "Packing Form", not on the Sales Order

    IF lv_SalesHeader.GET(lv_SalesHeader."Document Type"::Order,Ordernumber) THEN BEGIN
    lv_SalesHeader.TESTFIELD("Linked Packing Order","Packinglist No.");
    lv_SalesHeader.VALIDATE("No. Of Pallets",lv_NoOfPallets);
    lv_SalesHeader."Packing List Current" := lv_SalesHeader."Packing List Current"::Completed;
    lv_SalesHeader.MODIFY;
    END;

    But this Packing Form is modifying the "Sales Header" that is opened on the Sales Order, under the Packing Order..

    So on the "Sales Order" i just press a button "Process". Then it opens the "Packing Form" for that Sales order
    without closing the Sales Order... So "Packing Form" is now above the "Sales Order".

    Now we fill in some data in the "Packing Form" and Press approove in the "Packing Form".
    The approove button execute the code to modify the "Sales Header". After pressing approove i close the "Packing Form"
    And now my "Sales Order" is back actived. But because the "Packing Form" has modified the "Sales Header" i get the error...
  • kapamaroukapamarou Member Posts: 1,152
    Did you try the UPDATE(FALSE) code?

    Also there is a situation where this will not work. If your code call a form or a report like Form.RUN and NOT Form.RUNMODAL (or report.RUNMODAL) then the UDPATE(FALSE) will be executed before the change of the record. So I think we need to see exactly the code on your button to help you with this.
  • tompynationtompynation Member Posts: 398
    OK, i show all my code then:

    This is the code of the Button "Process" on the "Sales Order" which will create and open the "Packing Form":
    <Control1000000041> - OnPush()
    CreatePackingOrder;
    CreateProductionOrders;
    // Afdrukken documenten:
    // OrderConfirmation
     lv_SalesHeader.RESET;
     lv_SalesHeader.SETFILTER("No.",Rec."No.");
     REPORT.RUNMODAL(205,FALSE,TRUE,lv_SalesHeader);
     "Order Confirmation Current" := "Order Confirmation Current"::Completed;
    [b]CurrForm.UPDATE(FALSE);[/b]
    

    CreatePackingOrder:
    // Nakijken of Packing Order al bestaat
    IF "Linked Packing Order" <> '' THEN
      IF CONFIRM(Text007,TRUE,"Linked Packing Order") THEN BEGIN
        IF lv_PackingHeader.GET("Linked Packing Order") THEN
          FORM.RUNMODAL(FORM::"Packing order", lv_PackingHeader);
        EXIT;
      END;
    
    IF "Linked Packing Order" = '' THEN BEGIN
      // Aanmaken van Packing Order Header
      lv_PackingHeader.INIT;
      lv_PackingHeader.VALIDATE("Packinglist No.",'');
      lv_PackingHeader.INSERT(TRUE);
    
      lv_PackingHeader.TRANSFERFIELDS(Rec,FALSE);
      lv_PackingHeader.VALIDATE(lv_PackingHeader."Sell-to Customer No.");
      lv_PackingHeader.Ordernumber := "No.";
      lv_PackingHeader.MODIFY(TRUE);
    
      //Ophalen Customer, Max Weight Pallet
      lv_Customer.GET("Sell-to Customer No.");
      lv_MaxWeight := lv_Customer."Max. Weigth Pallet";
      IF lv_MaxWeight = 0 THEN
        lv_MaxWeight := 1000;
    
      // Aanmaken van Packing Order Line
      lv_SalesLine.RESET;
      lv_SalesLine.SETRANGE("Document No.","No.");
      lv_SalesLine.SETRANGE(Type,lv_SalesLine.Type::Item);
      IF lv_SalesLine.FINDSET THEN BEGIN
         REPEAT
          //Controleren of Max Weight Pallet niet overschreden worden
            lv_Item.GET(lv_SalesLine."No.");
            IF ((lv_Item."Net Weight" * lv_SalesLine.Quantity) <= lv_MaxWeight) THEN BEGIN
               lv_PackingLine.INIT;
               lv_PackingLine."Document No." := "No.";
               lv_PackingLine."Line No." := GetNextLineNumber(lv_PackingHeader."Packinglist No.");
               lv_PackingLine."Doc. Line No." := lv_SalesLine."Line No.";
               lv_PackingLine."No." := lv_SalesLine."No.";
               lv_PackingLine.Description := lv_SalesLine.Description;
               lv_PackingLine.Quantity := lv_SalesLine.Quantity;
               lv_PackingLine."Quantity (Base)" := lv_SalesLine."Quantity (Base)";
               lv_PackingLine."Unit of Measure Code" := lv_SalesLine."Unit of Measure Code";
               lv_PackingLine."Packing No." := lv_PackingHeader."Packinglist No.";
               lv_PackingLine."UN Code" := lv_SalesLine."UN Code";
               lv_PackingLine."Sidec No." := lv_SalesLine."Sidec No.";
               lv_PackingLine.INSERT;
            END
            ELSE BEGIN
               SplitsSalesLine(lv_SalesLine,lv_MaxWeight,lv_PackingHeader."Packinglist No.",lv_SalesLine.Quantity);
            END;
         UNTIL lv_SalesLine.NEXT = 0;
      END;
    
      Rec."Linked Packing Order" := lv_PackingHeader."Packinglist No.";
      Rec.MODIFY(TRUE);
    
        COMMIT;
        FORM.RUNMODAL(50003,lv_PackingHeader);
    END;
    

    Then after the FORM.RUNMODAL(50003,lv_PackingHeader);
    has been executed the users now fill in some data and Approove the "Packing Order"

    When he approoves following code gets executed (This code is in the Packing Order):
    Status - OnValidate()
    
    IF (Status = Status::Approved) THEN BEGIN
     // Invullen goedkeurder
     Goedkeurder := USERID;
     // Berekenen van aantal pallettenaantal kopieren naar het Sales Order
     lv_FirstTime := TRUE;
     lv_NoOfPallets := 0;
     lv_PackingLine.RESET;
     lv_PackingLine.SETCURRENTKEY("Packing No.",Pallet);
     lv_PackingLine.SETRANGE("Packing No.","Packinglist No.");
     IF lv_PackingLine.FINDSET THEN BEGIN
        REPEAT
          IF lv_FirstTime THEN BEGIN
              lv_NoOfPallets := 1;
              lv_Pallet := lv_PackingLine.Pallet;
          END
          ELSE BEGIN 
             IF lv_Pallet <> lv_PackingLine.Pallet THEN BEGIN
               lv_NoOfPallets += 1;
               lv_Pallet := lv_PackingLine.Pallet;
             END;
          END;
         lv_FirstTime := FALSE;
        UNTIL lv_PackingLine.NEXT = 0;
    
        // Aantal palletten kopieren naar Sales Order
        lv_SalesHeader.RESET;
        IF lv_SalesHeader.GET(lv_SalesHeader."Document Type"::Order,Ordernumber) THEN BEGIN
          lv_SalesHeader.TESTFIELD("Linked Packing Order","Packinglist No.");
          lv_SalesHeader.VALIDATE("No. Of Pallets",lv_NoOfPallets);
          lv_SalesHeader."Packing List Current" := lv_SalesHeader."Packing List Current"::Completed;
          lv_SalesHeader.MODIFY;
        END;
     END;
    END;
    
  • kapamaroukapamarou Member Posts: 1,152
    It's a bit hard to tell from your code... If you use the debugger where does your code stop with an error?
  • tompynationtompynation Member Posts: 398
    it doesnt stop... everything works fine.

    But its just that message saying that another user has modified the record in the sales order which annoys me
  • DenSterDenSter Member Posts: 8,304
    No, you guys dont understand me...
    Unlikely, me not understanding things happened only once in my life :mrgreen:

    That error message happens when two processes try to MODIFY the same record, without refreshing the record with what the other process is doing. What you need to do is one of two things:
    1 - you pass the sales header by reference, so that the modified record comes back into your code
    2 - you retrieve the record from the database after the call to the other process

    You said you added a button, and that the code on the button is causing the error message. To me that sounds like something in that code needs to be changed so that the error doesn't occur, not the object that is called from that button. Maybe that other object needs to be changed to accommodate this new process, but I think it is reasonable to assume that it is the custom code that causes the error.

    My first reaction would be to add a line to your code, right after the other object is done, that retrieves the sales header from the database.
    REPORT.RUNMODAL(205,FALSE,TRUE,lv_SalesHeader);
    Rec.GET(lv_SalesHeader."Document Type",lv_SalesHeader."No."); //new line of code
    

    The cause of the error message is that you are on Sales Order X, which is sent into this report. This report then changes the same sales order, ,and writes the change to the database (MODIFY does that). Then when it comes back to the form that you are on, it is still looking at the sales order from before the change was made. The form then tries to modify the record (which at that point is an old version), and you get that error.
Sign In or Register to comment.