Seek advice on working with temp rec on page

zeonzeon Member Posts: 130
edited 2014-10-26 in NAV Three Tier
Hi,

I seek some advice and/or code examples for working with temporary rec's on a page. (NAV2013R2)

I have created a new page, let's call this MyPage and this shows some temporary records. These records are based on a new table MyTable that has fields "Document Type", "Document No.", "Line No." and some other fields like length, width and quantity. MyPage has set SourceTableTemporary=Yes, and DelayedInsert=Yes.

Scenario:
In a codeunit I have found a subset of records from MyTable. These I have put into a temporary table. I then call a function on my new page to insert these in a temp rec, before lauching the page, and displaying the temp records.
The user might modify the displayed records, and should have the possibility to create new records.

In codeunit:
IF SalesLineSpec.FINDSET(FALSE,FALSE) THEN BEGIN
  SalesLineSpecPage.SetTempRecord(SalesLineSpec);
  COMMIT;
  IF SalesLineSpecPage.RUNMODAL = ACTION::OK THEN BEGIN
    SalesLineSpecPage.GetTempRecord(ReturnSalesLineSpec);

Function in page:
SetTempRecord(VAR RecIn : TEMPORARY Record "Sales Specification Line")
RecTemp.DELETEALL;
IF RecIn.FINDSET(FALSE) THEN
  REPEAT
    RecTemp.COPY(RecIn);
    IF RecTemp.INSERT THEN;
  UNTIL RecIn.NEXT = 0;
CurrPage.UPDATE;

Triggers in page:
OnFindRecord(Which : Text) : Boolean
RecTemp.COPY(Rec);
IF RecTemp.FIND(Which) THEN BEGIN
  Rec := RecTemp;
  EXIT(TRUE);
END ELSE
  EXIT(FALSE);

OnNextRecord(Steps : Integer) : Integer
RecTemp.COPY(Rec);
locResultSteps := RecTemp.NEXT(Steps);
IF locResultSteps <> 0 THEN
  Rec := RecTemp;
EXIT(locResultSteps);

OnAfterGetRecord()

OnNewRecord(BelowxRec : Boolean)
IF RecTemp.FINDLAST THEN
  NextLineNo := RecTemp."Line No." + 10000
ELSE
  NextLineNo := 10000;

RecTemp := xRec;
RecTemp."Line No." := NextLineNo;
RecTemp."Quantity (pcs)" := 0;
RecTemp."Length (mm)" := 0;
RecTemp.INSERT;
Rec := RecTemp;

OnInsertRecord(BelowxRec : Boolean) : Boolean

OnModifyRecord() : Boolean
RecTemp := Rec;
RecTemp.MODIFY;
EXIT(FALSE);

OnDeleteRecord() : Boolean

This works somewhat ok, but with a few problems:

1. When the user modifies some of the displayed records, error message "The view is filtered, and the view is outside the filter. Some actions may not work.". This does not happen when the user modifies one of the rec's he has entered.

2. I cannot differentiate whether the user hits ok or presses Esc when leaving the page, so cannot detect whether I should process the data entered in the page or not.

3. Whats is the "best practice" code for working with pages and temporary records. I have only found examples where it is not possible to enter new data, so insertallowed, modifyallowed are set No.

Source code:
OBJECT Page 50008 Sales Specification Lines
{
  OBJECT-PROPERTIES
  {
    Date=26-10-14;
    Time=14:11:20;
    Modified=Yes;
    Version List=;
  }
  PROPERTIES
  {
    CaptionML=[DAN=Salgsspecifikatioslinjer;
               ENU=Sales Specification Lines];
    SourceTable=Table50008;
    DelayedInsert=Yes;
    PageType=List;
    SourceTableTemporary=Yes;
    OnFindRecord=BEGIN
                   RecTemp.COPY(Rec);
                   IF RecTemp.FIND(Which) THEN BEGIN
                     Rec := RecTemp;
                     EXIT(TRUE);
                   END ELSE
                     EXIT(FALSE);
                 END;

    OnNextRecord=VAR
                   locResultSteps@1161021000 : Integer;
                 BEGIN
                   RecTemp.COPY(Rec);
                   locResultSteps := RecTemp.NEXT(Steps);
                   IF locResultSteps <> 0 THEN
                     Rec := RecTemp;
                   EXIT(locResultSteps);
                 END;

    OnNewRecord=BEGIN
                  NewRec;
                END;

    OnModifyRecord=BEGIN
                     ModifyRec;
                     EXIT(FALSE);
                   END;

    OnQueryClosePage=VAR
                       salesline@1161021000 : Record 37;
                     BEGIN
                     END;

  }
  CONTROLS
  {
    { 1161021000;0;Container;
                ContainerType=ContentArea }

    { 1161021001;1;Group  ;
                Name=Group;
                GroupType=Repeater }

    { 1161021002;2;Field  ;
                SourceExpr="Document Type" }

    { 1161021003;2;Field  ;
                SourceExpr="Document No.";
                Editable=false }

    { 1161021004;2;Field  ;
                SourceExpr="Line No.";
                Editable=false }

    { 1161021005;2;Field  ;
                SourceExpr=Type }

    { 1161021006;2;Field  ;
                SourceExpr="No." }

    { 1161021007;2;Field  ;
                SourceExpr="Quantity (pcs)";
                StyleExpr=TRUE }

    { 1161021008;2;Field  ;
                SourceExpr="Length (mm)";
                StyleExpr=TRUE }

    { 1161021009;2;Field  ;
                SourceExpr="Width (mm)";
                Visible=FALSE }

    { 1161021011;2;Field  ;
                SourceExpr=Quantity;
                Editable=false;
                Style=Strong;
                StyleExpr=TRUE }

    { 1161021010;2;Field  ;
                Name=<Quantity>;
                SourceExpr="Related to Line No.";
                Visible=FALSE }

  }
  CODE
  {
    VAR
      RecTemp@1161021000 : TEMPORARY Record 50008;

    PROCEDURE SetTempRecord@1108600000(VAR RecIn@1108600000 : TEMPORARY Record 50008);
    BEGIN
      RecTemp.DELETEALL;
      IF RecIn.FINDSET(FALSE) THEN
        REPEAT
          RecTemp.COPY(RecIn);
          IF RecTemp.INSERT THEN;
        UNTIL RecIn.NEXT = 0;
      CurrPage.UPDATE;
    END;

    PROCEDURE GetTempRecord@1161021001(VAR RecIn@1108600000 : TEMPORARY Record 50008);
    BEGIN
      RecIn.DELETEALL;
      IF RecTemp.FINDSET(FALSE) THEN
        REPEAT
          RecIn.COPY(RecTemp);
          IF RecIn.INSERT THEN;
        UNTIL RecTemp.NEXT = 0;
      CurrPage.UPDATE;
    END;

    PROCEDURE NewRec@1161021000();
    VAR
      NextLineNo@1161021000 : Integer;
    BEGIN
      IF RecTemp.FINDLAST THEN
        NextLineNo := RecTemp."Line No." + 10000
      ELSE
        NextLineNo := 10000;

      RecTemp := xRec;
      RecTemp."Line No." := NextLineNo;
      RecTemp."Quantity (pcs)" := 0;
      RecTemp."Length (mm)" := 0;
      RecTemp.INSERT;
      Rec := RecTemp;
    END;

    PROCEDURE ModifyRec@1108600001();
    BEGIN
      RecTemp := Rec;
      RecTemp.MODIFY;
    END;

    BEGIN
    END.
  }
}

Answers

  • ara3nara3n Member Posts: 9,256
    the issue with not knowing if user clicks ok or not. YOu need to change the code

    IF SalesLineSpecPage.RUNMODAL = ACTION::OK THEN BEGIN


    to

    SalesLineSpecPage.lookupmode;
    IF SalesLineSpecPage.RUNMODAL = ACTION::LookupOK THEN BEGIN
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • ara3nara3n Member Posts: 9,256
    I Don't think there is a best practices for temporary table.
    The only example is the form that is used to enter serial or lot no. Form/Page 6510 Item Tracking Lines.

    And that page is not a great example.
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • zeonzeon Member Posts: 130
    You are probably right...I have already looked at that page, and it is a bit complicated... :shock:
  • ara3nara3n Member Posts: 9,256
    For your first issue. Add code on insert trigger to insert the record into the temporary and exit false. just like the Page 6510
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • zeonzeon Member Posts: 130
    I cannot see that should help.
    E.g if I have found two rec's in the codeunit and I display them in the page these are the ones that cause the problem in 1). Not new records that the user enteres.

    Even though I move the
    RecTemp.INSERT
    
    code to OnInsertRecord, this problem persists. But thanks!
  • zeonzeon Member Posts: 130
    Oh, and...
    IF SalesLineSpecPage.RUNMODAL = ACTION::OK THEN BEGIN
    

    MS have changed the behavior for RUNMODAL, so there is now no difference between the user pressing OK or hitting Esc regarding return value.

    The return value is OK, if user upon closing page:

    - Chooses the OK button.

    - Chooses the X button when there was no Cancel button on the window.

    - Presses the Esc key when there is no Cancel button on the window.
  • zeonzeon Member Posts: 130
    Finally found a solution to work this out...

    The solution was to simplify the code I had borrowed from the how-to on mibuso' site.

    The handling of the Line No. is done by controlling a global variable LastLineNo, as done in Page 6510.

    To know whether or not the user hits ok or Esc is done by this code:
      SalesSpecLinePage.SetTempRecord(SalesLineSpec);
      SalesSpecLinePage.LOOKUPMODE(TRUE);
      IF SalesSpecLinePage.RUNMODAL = ACTION::LookupOK THEN BEGIN
        SalesSpecLinePage.GetTempRecord(ReturnSalesLineSpec);
    

    Even if the Page is set to LOOKUPMODE(TRUE) the page is editable as it is set to PageType=Worksheet.

    Source code below if useful for anyone:

    All this may be common knowledge to most of you, but I still learned new stuff :thumbsup:
    OBJECT Page 50008 Sales Specification Lines
    {
      OBJECT-PROPERTIES
      {
        Date=26-10-14;
        Time=22:17:45;
        Modified=Yes;
        Version List=;
      }
      PROPERTIES
      {
        CaptionML=[DAN=Salgsspecifikatioslinjer;
                   ENU=Sales Specification Lines];
        SourceTable=Table50008;
        DelayedInsert=Yes;
        PageType=Worksheet;
        SourceTableTemporary=Yes;
        OnFindRecord=BEGIN
                       IF Rec.FIND(Which) THEN
                         EXIT(TRUE)
                       ELSE
                         EXIT(FALSE);
                     END;
    
        OnNextRecord=VAR
                       locResultSteps@1161021000 : Integer;
                     BEGIN
                       locResultSteps := Rec.NEXT(Steps);
                       IF locResultSteps <> 0 THEN
                         EXIT(locResultSteps);
                     END;
    
        OnNewRecord=BEGIN
                      Rec := xRec;
                      "Line No." :=  NextLineNo;
                      "Quantity (pcs)" := 0;
                      "Length (mm)" := 0;
                    END;
    
      }
      CONTROLS
      {
        { 1161021000;0;Container;
                    ContainerType=ContentArea }
    
        { 1161021001;1;Group  ;
                    Name=Group;
                    GroupType=Repeater }
    
        { 1161021002;2;Field  ;
                    SourceExpr="Document Type" }
    
        { 1161021003;2;Field  ;
                    SourceExpr="Document No.";
                    Editable=false }
    
        { 1161021004;2;Field  ;
                    SourceExpr="Line No.";
                    Editable=false }
    
        { 1161021005;2;Field  ;
                    SourceExpr=Type }
    
        { 1161021006;2;Field  ;
                    SourceExpr="No." }
    
        { 1161021007;2;Field  ;
                    SourceExpr="Quantity (pcs)";
                    StyleExpr=TRUE }
    
        { 1161021008;2;Field  ;
                    SourceExpr="Length (mm)";
                    StyleExpr=TRUE }
    
        { 1161021009;2;Field  ;
                    SourceExpr="Width (mm)";
                    Visible=FALSE }
    
        { 1161021011;2;Field  ;
                    SourceExpr=Quantity;
                    Editable=false;
                    Style=Strong;
                    StyleExpr=TRUE }
    
        { 1161021010;2;Field  ;
                    Name=<Quantity>;
                    SourceExpr="Related to Line No.";
                    Visible=FALSE }
    
      }
      CODE
      {
        VAR
          LastLineNo@1161021000 : Integer;
    
        PROCEDURE SetTempRecord@1108600000(VAR RecIn@1108600000 : Record 50008);
        BEGIN
          IF RecIn.FINDSET(FALSE) THEN
            REPEAT
              Rec.TRANSFERFIELDS(RecIn);
              LastLineNo := "Line No.";
              IF Rec.INSERT THEN;
            UNTIL RecIn.NEXT = 0;
          CurrPage.UPDATE;
        END;
    
        PROCEDURE GetTempRecord@1161021001(VAR RecIn@1108600000 : Record 50008);
        BEGIN
          RecIn.DELETEALL;
          IF Rec.FINDSET(FALSE) THEN
            REPEAT
              RecIn.TRANSFERFIELDS(Rec);
              IF RecIn.INSERT THEN;
            UNTIL Rec.NEXT = 0;
          CurrPage.UPDATE;
        END;
    
        LOCAL PROCEDURE NextLineNo@9() : Integer;
        BEGIN
          LastLineNo += 10000;
          EXIT(LastLineNo);
        END;
    
        BEGIN
        {
        }
        END.
      }
    }
    
    
Sign In or Register to comment.