Need help with posting shipment in C/AL code.

ALopez27ALopez27 Member Posts: 42
I'm writing a routine that will post sales order shipments in code, I have it working, however, if there are any errors in the posting of the order, my program terminates.

I would like to trap errors, however, C/AL does not allow me to put conditions to check (IF codeunit90.run(SalesHdrRec) etc..) if the posting routine completes successfully.

Can someone tell me how I can do this so that I can trap any errors and not allow my routine to terminate? Thanks much.....

A.L.

Comments

  • kinekine Member Posts: 12,562
    what do you mean with "C/AL does not allow me to put conditions to check"?
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • crisnicolascrisnicolas Member Posts: 177
    Codeunit.RUN
    Use this function to load and execute the unit of C/AL code you specify. See also RUN (codeunit).

    [Ok] := Codeunit.RUN(Number [, Record])
    Ok

    Data type: boolean

    If you do not include the optional return value, and an error occurs while the system is executing the codeunit, it terminates the execution of the C/AL code that called this codeunit.

    If you include the return value and there's an error, the system continues to execute the calling C/AL code. This means you must handle any errors. The possible values are shown below.

    If Ok is...
    It means that...

    TRUE
    No errors occurred

    FALSE
    An error occurred during the execution of the codeunit


    If you include the return value, the system automatically clears the variables used in the codeunit object before and after it executes the object.

    If you use the return value in an IF statement which is inside a write transaction, a run-time error occurs unless you commit your data updates before you call Codeunit.RUN
  • kitikkitik Member Posts: 230
    From NAV 5.0 you can catch errors if the error is produced in the OnRun function of a codeunit.

    Whenever I need to run a routine and catch the errors I use a 50000 codeunit that has this code on the OnRun() trigger:
    CASE FunctionNumber OF
     0: ERROR(Txt0001);
     1: MyFunction1;
     2: MyFunction2;
     3: MyFunction3;
     4: MyFunction4;
     [..]
     ELSE ERROR(STRSUBSTNO(Txt0002,FunctionNumber));
    END;
    

    I can call this codeunit from any other object, wrting code like this one:
    MyCodeunit.setFunctionToCall(1);
    IF MyCodeunit.RUN THEN
      // No errors
    ELSE BEGIN
      // Errors
      MyErrorTxt := GETLASTERRORTEXT
      CLEARLASTERROR;
    END;
    

    I use the MyErrorTxt variable to write the error in a log file, send an e-mail, or any other log system you may use.

    Salut!
    Laura Nicolàs
    Author of the book Implementing Dynamics NAV 2013
    Cursos Dynamics NAV (spanish) : http://clipdynamics.com/ - A new lesson released every day.
  • ALopez27ALopez27 Member Posts: 42
    Hello All,

    Thanks for your responses, maybe I did not explain my issue correctly, I'll make another attempt at this.

    Below as my code:

    SalesHdr.Ship := TRUE;
    SalesHdr.Invoice := FALSE;
    SalesHdr.VALIDATE("Posting Date",TODAY);
    IF SalesPost.RUN(SalesHdr) THEN BEGIN
    inEDIHeader."Document Posted" := TRUE;
    inEDIHeader."Doc. Posted Date Time" := CURRENTDATETIME;
    inEDIHeader.MODIFY;
    COMMIT;
    END
    ELSE
    ...... display error (or something else)... and continue executing this routine....

    Where SalesHdr is the Sales Order table and Sales Post is the Sales-Post routine (std. codeunit 80).

    If I try to execute the above code, I get the below error message. From what I understand it does not like the conditional run check (IF) when running a codeunit when there are write transactions in that codeunit where tables will be locked.

    Can someone tell me how I can write the code in such a way that will allow me to do what I need to do, that is, to know and trap any errors and not have the code terminate? I'm using NAV 2009 Classic. Thanks again.

    error i get.....
    The following C/AL functions can be used only to a limited degree during write transactions because one or more tables will be locked.

    Form.RunModal is not allowed in write transactions.

    CodeUnit.Run is allowed in write transactions only if the return value is not used. For example, 'OK := CodeUnit.Run()' is not allowed.

    Report.RunModal is allowed in write transactions only if 'RequestForm = FALSE'. For example, 'Report.RunModal(...,FALSE)' is allowed.

    DataPort.RunModal is allowed in write transactions only if 'RequestForm = FALSE'. For example, 'DataPort.RunModal(...,FALSE)' is allowed.

    Use the COMMIT function to save the changes before this call, or structure the code differently.

    OK
  • MBergerMBerger Member Posts: 413
    You could also check if there is a creditlimit or stock warning with the shipment, those can cause these errors too when having a transaction open, because they open a modal form.
  • kinekine Member Posts: 12,562
    The probem is that you need to commit running transaction before the IF statement or not to start writing transaction (VALIDATE could start it or some code before it).
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • ALopez27ALopez27 Member Posts: 42
    Thanks Kamil !!

    That's what the problem was, thanks all for you help.

    A.L.
  • kinekine Member Posts: 12,562
    Of course, you need to be sure that the commit will not break your process in case of error. It must be really as separate transaction from the meaning itself.
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
Sign In or Register to comment.