Options

reason behind the code

dsatriadsatria Member Posts: 80
many posting codeunits (with RunWithCheck function) are using the following code format:

GlobalRec.COPY(ParamRec);
Code;
ParamRec:=GlobalRec;

What is the purpose of the THIRD line?
I tried to comment out that line (in CU 22) and succesfully posted an item journal line without problem (as far as I can see)

Comments

  • Options
    ara3nara3n Member Posts: 9,256
    Well it all depends on what you do with ParamRec. If you are not doing anything with it then the third line has no meaning, but if you expect to do something with the variable then the third line make sense.
    Remember the parameter is passed by reference.
    Ahmed Rashed Amini
    Independent Consultant/Developer


    blog: https://dynamicsuser.net/nav/b/ara3n
  • Options
    krikikriki Member, Moderator Posts: 9,090
    And in some cases, some fields contain info on the posted record.
    E.g. posting an invoice in Table 36 with codeunit 80. In the "Last Posting No." you will have the posted invoice number. BUT the original record in table 36 will NOT exist anymore in the DB. So without this, you cannot retrieve the posted invoice no.
    And Navision put that code everywhere to make it uniform, even if it isn't always necessary.
    Regards,Alain Krikilion
    No PM,please use the forum. || May the <SOLVED>-attribute be in your title!


  • Options
    David_SingletonDavid_Singleton Member Posts: 5,479
    The history of this is a little odd. In the DOS version of Navision a "WITH MyRecordVar DO" command could only be done with the passing variable (REC). And RECs were passed slightly differently than they are now with regards to filters.

    When Financials was released, they wanted to keep the code basically identical to the DOS code, so in all the calling routines, this precalling funciton was used really just to translate (say) SalesHeader to rec. This made it much easier to use the code conversion tools, especially if you had Add-Ons.

    As it become part of the product, it just found it self everywhere, and was used by developers like you could set filters in the code unit without causing big problems etc.

    When I did Navision training on version 1.00 Financials we were told that they would be left in the release version, but eventually removed in a later version.

    For those upgrading from DOS to Windows, it was a great time saver since youdid not need to make big modifications to how your mods handled filtering and changing records. In really thouh, by now it should have been removed. Though saying that, there are so many people acutally using it as a feature that we will probably see it for many versions to come.
    David Singleton
  • Options
    DenSterDenSter Member Posts: 8,304
    The actual reason is that the record parameter is local to the OnRun trigger, and most of those codeunits are written in such a way that the record that is passed in needs to be accessed throughout the codeunit. In order to be able to do anything with the parameter it is then copied into a global variable.

    Then the 'Code' trigger executes, and it will use the global variable throughout the code. Because some of the field values might change in that code, and the parameter is by reference (which means that it is the actual record that is passed into the codeunit, not a copy of it), ou want to have the current values in the code that calls the codeunit. So, after the 'Code' trigger is done, the global record is copied back into 'Rec', which is the parameter, so the right values are passed back to the calling object.
  • Options
    David_SingletonDavid_Singleton Member Posts: 5,479
    DenSter wrote:
    The actual reason is that the record parameter is local to the OnRun trigger, and most of those codeunits are written in such a way that the record that is passed in needs to be accessed throughout the codeunit. In order to be able to do anything with the parameter it is then copied into a global variable.

    ...

    What you are saying is technically correct. I was just trying to give background as to WHY it was done that way.

    In DOS, the REC variable was global to the entire codeunit, and the only trigger was the ONRUN. The code could have been written differently, but was kept this way to make it easier to upgrade users from DOS to Windows.

    Basically when you took a 3.56 Codeunit and ran it throught the converter, it added that bit of code at the top. Though its some time since I did a conversion, so I can't remember the exact details. (Maybe we had to add that bit in manually).
    David Singleton
  • Options
    DenSterDenSter Member Posts: 8,304
    I was just trying to give background as to WHY it was done that way.
    That is exactly how I took it. I always appreciate and enjoy the historical background that you provide, it puts some of the funky things we see into its proper perspective, and many times it provides very valuable insight :mrgreen:

    My post was intended to be an addition to yours rather than a replacement.
  • Options
    dsatriadsatria Member Posts: 80
    DenSter wrote:
    Then the 'Code' trigger executes, and it will use the global variable throughout the code. Because some of the field values might change in that code, and the parameter is by reference (which means that it is the actual record that is passed into the codeunit, not a copy of it), ou want to have the current values in the code that calls the codeunit. So, after the 'Code' trigger is done, the global record is copied back into 'Rec', which is the parameter, so the right values are passed back to the calling object.

    But my testing showed otherwise (perhaps my testing method was incorrect?):

    Using RunWithCheck on CU 22
    Input data on Item Journal form: Qty=1 "Qty Base"=72

    Adding some codes to see what happen while posting:
    ItemJnlLine.COPY(ItemJnlLine2);
    ...
    WHILE SplitJnlLine(ItemJnlLine,PostItemJnlLine) DO
      IF PostItemJnlLine THEN BEGIN
        MESSAGE('Before Code: %1',ItemJnlLine2.Quantity);
        Code;
        MESSAGE('After Code: %1',ItemJnlLine2.Quantity);
        END;
    ItemJnlLine2 := ItemJnlLine;
    MESSAGE('After Copied back: %1',ItemJnlLine2.Quantity);
    

    Result:
    Before Code: 1
    After Code: 1
    After Copied back:72

    It seemed that:
    - "Code" did change ItemJnlLine but did NOT change ItemJnlLine2
    - the assigment line changed ItemJnlLine2 instead of keeping its original
    value
Sign In or Register to comment.