NAV2015 C/AL - How do i pass parameters from a table to a user function

MagicmanMagicman Member Posts: 13
Hi all and a happy new year :-) I'm by no means new to NAV but i'm just beginning with application development and as such i am 'fighting' with C/AL. :-)
I have an easy question which i cant seem to solve no matter what I do.

I have a function 'Addnums' that has two parameters 'NrIn1' and 'NrIn2' and a result 'NrOut'. The function is simply 'NrOut := (NrIn1+NrIn2);'. This function resides in a codeunit. I also have a table that contains three integer fields 'NrI1', 'NrI2' and 'NrO'. The OnValidate trigger of Field 'NrI2' contains the function call 'NrO := Nums.AddNums(NrI1,NrI2);' - 'Nums' represents the variable (type Codeunit, Subtype Addnums) for the function 'Addnums'.

My problem is, that the integers i enter in NRI1and NrI2 are not being passed to the function and i can't for the life of me see what i am doing wrong :-(

Can someone kindly put me on the right track?

Thanks in advance :-)

M.

Best Answer

  • ShaiHuludShaiHulud Member Posts: 228
    Answer ✓
    Ah, there's your answer - in OnValidate trigger of field NrI2 you have local variables NrI1 and NrI2. So, you end up passing those variables (which have default value of 0) into the function, not the field values.
    Delete the local variables from the trigger and you should be good to go.

Answers

  • lubostlubost Member Posts: 628
    What your function AddNums looks like?
  • MagicmanMagicman Member Posts: 13
    Hi lubost :-)

    The function consists only of the following:

    NrOut := (NrIn1+NrIn2);

    If I replace NrIn1 and NrIn2 with integers (e.g. 1 and 2) then the correct return value is passed back to the call and the field NrO is updated to '3'.....
    I just can't seem to join the fields of the table with the input parameters of the function:-(
  • lubostlubost Member Posts: 628
    - Function header is important too, not only content
    - If codeunit contains Rec assigned, parameters can interfere with columns with same names
  • MagicmanMagicman Member Posts: 13
    hi lubost.

    Ah ok. The header is:

    AddNums(NrIn1 : Integer;NrIn2 : Integer) Nrout : Integer

    Other than that there is nothing in the cu.....
  • lubostlubost Member Posts: 628
    With this pattern all should be done properly.
    Share a lines of code where you call this function - where parameters come from.
    Codeunit shoud not be singleinstance.
  • MagicmanMagicman Member Posts: 13
    Hi lubost.

    Thank you for your time :-)

    Here the code including trigger:

    NrI2 - OnValidate()
    NrO := Nums.AddNums(NrI1,NrI2);

    I cannot seem to get access to codeunit properties to see whether singleinstance is yes. No is default and i haven't changed anything so i assume it would be no....
  • lubostlubost Member Posts: 628
    I assume then Nrl1 is colum of Rec table same as Nrl2. All seems to be properly arranged and NrO would be sum of Nrl1 and Nrl2 after returning from Nums codeunit.
  • MagicmanMagicman Member Posts: 13
    Your assumption is correct :-) I have no idea why it doesn't work either.

    Maybe something with the global/local settings?
  • ShaiHuludShaiHulud Member Posts: 228
    Have you tried debugging/adding MESSAGE right before calling your Addnums function to see that the values of NrI1 and NRI2 are actually set?
  • MagicmanMagicman Member Posts: 13
    Good morning ShaiHulud.

    I should have mentioned that! - Yes, I debugged the process the moment I realised it wasn't working. The field values are being set and the call to the codeunit works. From that moment on the values are gone - they are not transitioning from the fields NrI1 and NrI2 to the parameters NrIn1 and NrIn2.....
  • ShaiHuludShaiHulud Member Posts: 228
    Can you post your entire codeunit code here? Maybe you have global variables there called NrIn1 and NrIn2?
  • MagicmanMagicman Member Posts: 13
    Of course :-)

    Here the CU:

    OBJECT Codeunit 50050 Addnums
    {
    OBJECT-PROPERTIES
    {
    Date=08.01.21;
    Time=11:16:25;
    Modified=Yes;
    Version List=;
    }
    PROPERTIES
    {
    CFRONTMayUsePermissions=No;
    OnRun=BEGIN
    END;

    }
    CODE
    {

    PROCEDURE AddNums@1(NrIn1@1000 : Integer;NrIn2@1001 : Integer) Nrout : Integer;
    BEGIN
    Nrout := (NrIn1+NrIn2);
    END;

    BEGIN
    END.
    }
    }


    and here the table:

    OBJECT Table 50008 Datumsformel Test 2
    {
    OBJECT-PROPERTIES
    {
    Date=07.01.21;
    Time=16:19:48;
    Modified=Yes;
    Version List=;
    }
    PROPERTIES
    {
    }
    FIELDS
    {
    { 10 ; ;PK ;Integer }
    { 20 ; ;Referenzdatum fr Berechnung;Date ;OnValidate=BEGIN
    Ergebnis := CALCDATE(Datumsformel,"Referenzdatum fr Berechnung");
    END;
    }
    { 30 ; ;Datumsformel ;DateFormula ;OnValidate=BEGIN
    Ergebnis := CALCDATE(Datumsformel,"Referenzdatum fr Berechnung");
    END;
    }
    { 40 ; ;Ergebnis ;Date }
    { 50 ; ;NrI1 ;Integer }
    { 60 ; ;NrI2 ;Integer ;OnValidate=VAR
    NrI1@1000 : Integer;
    NrI2@1001 : Integer;
    BEGIN
    NrO := Nums.AddNums(NrI1,NrI2);
    END;
    }
    { 70 ; ;NrO ;Integer }
    }
    KEYS
    {
    { ;PK ;Clustered=Yes }
    }
    FIELDGROUPS
    {
    }
    CODE
    {
    VAR
    Nums@1000 : Codeunit 50050;

    BEGIN
    END.
    }
    }
  • ShaiHuludShaiHulud Member Posts: 228
    Answer ✓
    Ah, there's your answer - in OnValidate trigger of field NrI2 you have local variables NrI1 and NrI2. So, you end up passing those variables (which have default value of 0) into the function, not the field values.
    Delete the local variables from the trigger and you should be good to go.
  • MagicmanMagicman Member Posts: 13
    That was it! So to pass values to a function doesn't require them to be in a variable...ok :)

    Thankyou both for the help :)

    I'm still trying to wrap my old brain around the global/local construct in C/AL. Can you point me to any clear and concise description...preferably for dummies :smiley:
  • lubostlubost Member Posts: 628
    Global variables are established for all code inside object. Local variables acts only in trigger (function) where defined.
    - all table object has implicitly defined global Rec variable defined as actual table object
    - all page object has implicitly defined global Rec variable when based on table - defined as base table object
    - codeunit has implicitly defined global Rec variable when defined TableNo property
    - all dataitem in Report, XMLPort and Query implicitly acts as global variable
  • MagicmanMagicman Member Posts: 13
    Wait...so a global Variable is not really global? It is only global to the object it is defined within? And a local variable is local to the trigger not to the object....
  • lubostlubost Member Posts: 628
    - NAV doesn't allow to define real user defined global variables valid for whole environment. Only NAV defined global variables exist
    - Global variables defined in objects are global only inside object are visible from all triggers
    - Local variables defined in triggers are visible only inside trigger

    You have to assign variable names to avoid conflict with global-local-base record columns. Conflict can lead to unpredictable results (as you had seen).
Sign In or Register to comment.