Options

Event Subscriber works when debugging and otherwise not

Manifold78Manifold78 Member Posts: 7
Hi!

I have created a new event subscriber codeunit in NAV 2018 (CU08 / W1). This subsciber should give me default values for a new sales order. Default values are stored in config template "TEMP". See code below.

What is strange here is that this works fine when using the debugger BUT not when the debugger is not running...

Have you faced something similar? Any ideas what is wrong? Or is this perhaps a bug in NAV?

________________________________________________________________________________________

Documentation()

OnRun(VAR Rec : Record "Sales Header")

LOCAL [EventSubscriber] InsertSalesDocDefaultValues(VAR Rec : Record "Sales Header";RunTrigger : Boolean)
IF (Rec."Document Type" = Rec."Document Type"::Order) THEN
InsertDefaultValues('TEMP',Rec);

LOCAL InsertDefaultValues(ConfigTemplateName : Code[10];Rec : Record "Sales Header")
ConfigTemplateHeader.RESET;
ConfigTemplateHeader.SETRANGE("Table ID",DATABASE::"Sales Header");
ConfigTemplateHeader.SETRANGE(Enabled,TRUE);
ConfigTemplateHeader.SETRANGE(Code,ConfigTemplateName);
IF ConfigTemplateHeader.FIND('-') THEN BEGIN
SalesOrderRecRef.GETTABLE(Rec);
ConfigTemplateMgmt.UpdateRecord(ConfigTemplateHeader,SalesOrderRecRef);
END;

Best Answers

  • Options
    Manifold78Manifold78 Member Posts: 7
    Answer ✓
    Good point. I changed the latter Rec to VAR also.

    I checked this on the Sales Order page (i.e. saw that after I create a new record, I got the value in the field as defined in the Config Template. The Event Subscriber subscribes to Sales Header OnAfterInsertEvent.

    I noticed that this is actually the whole problem (i.e. this is SOLVED): The event subscriber itself works, BUT the difference is that by using debugger the page is naturally refreshed after I get back to the Sales Order page. When I'm on the page (without debugger) the value will be changed correctly, BUT the page itself isn't refreshed so if I e.g. update some information manually on the Sales Order, I get the "An attempt was made to change an old version of Sales Header record...".

    I guess I can't use Event Subscriber to change the record which is currently selected (Sales Order page). Or this could be done by using e.g. this: https://suraj-nav.blogspot.com/2016/06/refresh-page.html

Answers

  • Options
    vaprogvaprog Member Posts: 1,130
    You are not modifying the Rec parameter of the event subscriber but the database or a copy of the Rec in memory.

    I don't think this code works in the debugger. Don't get fooled by the code being run in the debugger.
  • Options
    Manifold78Manifold78 Member Posts: 7
    Ok. I added "IF Rec.ISTEMPORARY THEN EXIT;" in the beginning which in my understanding should exit the function if the Rec is not the "real" Rec...? I also added a MESSAGE just after this to be sure that we won't exit even if the debugger is not running.

    I still have the same issue though. The code really works only when debugger is running: If I place a break point in the beginning and have the debugger running and I press F5 to continue, I will get e.g. "Currency Code" field filled with the value I have defined in the Config Template. In other words, I have not only checked whether the code runs but also checked that I really get the needed information in fields defined in the "TEMP" Config Template.

    If you have clean Cronus DB installed, please try this. I'm quite sure you will face the same behavior.
  • Options
    vaprogvaprog Member Posts: 1,130
    Where did you check it? in the final result? in the result at the end of your event?
    The following Rec variable needs to change:
    LOCAL [EventSubscriber] InsertSalesDocDefaultValues(VAR Rec : Record "Sales Header";RunTrigger : Boolean)
    
    This is not the case, because the Rec parameter in this function is not VAR:
    LOCAL InsertDefaultValues(ConfigTemplateName : Code[10];Rec : Record "Sales Header")
    
    Your modification to the database will likely be overwritten by the event caller.
  • Options
    Manifold78Manifold78 Member Posts: 7
    Answer ✓
    Good point. I changed the latter Rec to VAR also.

    I checked this on the Sales Order page (i.e. saw that after I create a new record, I got the value in the field as defined in the Config Template. The Event Subscriber subscribes to Sales Header OnAfterInsertEvent.

    I noticed that this is actually the whole problem (i.e. this is SOLVED): The event subscriber itself works, BUT the difference is that by using debugger the page is naturally refreshed after I get back to the Sales Order page. When I'm on the page (without debugger) the value will be changed correctly, BUT the page itself isn't refreshed so if I e.g. update some information manually on the Sales Order, I get the "An attempt was made to change an old version of Sales Header record...".

    I guess I can't use Event Subscriber to change the record which is currently selected (Sales Order page). Or this could be done by using e.g. this: https://suraj-nav.blogspot.com/2016/06/refresh-page.html

  • Options
    Mark_SmartMark_Smart Member Posts: 16
    Does your event subscribe to OnBeforeModify or OnAfterModify?

    If you are trying to make changes to the sales header before the modify occurs, then by all means make the parameter VAR all the way and use OnBeforeModify. The OnBeforeModify will accept changes make to the sales header before saving it from your functions. Do not call a MODIFY to the record.

    Otherwise, if wanting to change values after the fact, use OnAfterModify. Be sure to avoid a loop of modifying.
  • Options
    Manifold78Manifold78 Member Posts: 7
    I'm trying to set default values for a new sales order by using the Config Templates (and only for a new sales order). The event subscribes to OnAfterInsertEvent.
  • Options
    Mark_SmartMark_Smart Member Posts: 16
    You can modify field values using OnBeforeInsert. This will save having to so a MODIFY after the record is inserted.
  • Options
    Manifold78Manifold78 Member Posts: 7
    But I guess if I use OnBeforeInsert I don't even have the Rec...? In other words, the record doesn't even exist at that point.
  • Options
    Slawek_GuzekSlawek_Guzek Member Posts: 1,690
    During OnBeforeInsert execution you have your Rec but in memory only, not in the database, and before any C/AL code in the OnInsert trigger is executed. Since the record is not in the database at this point you cannot call MODIFY on it, and neither INSERT - but any changes changes to the Rec you make in the OnBeforeInsert event handler will be stored in the database when OnInsert trigger code finishes execution and NAV inserts new record (unless of course, the code in OnInsert trigger or another OnBeforeInsert event handler overwrites your changes).

    OnAfterInsert, on the other hand, is executed after the OnOnsert trigger code has been executed and after NAV stored the record in the database. Therefore if you make changes to the record in OnAfterInsert event handler you have to call MODIFY on it in order get your changes flushed to the database.

    The drawback of OnAfterInsert is that the record is physically written twice, but your changes will not be overwritten by OnInsert trigger code - but they still may be overwritten by another OnAfterInsert, if there is any.

    Slawek Guzek
    Dynamics NAV, MS SQL Server, Wherescape RED;
    PRINCE2 Practitioner - License GR657010572SG
    GDPR Certified Data Protection Officer - PECB License DPCDPO1025070-2018-03
  • Options
    Manifold78Manifold78 Member Posts: 7
    Changing the Rec in memory is understandable. However, it seems that if using OnBeforeInsert the problem will be the function call ConfigTemplateMgmt.UpdateRecord (codeunit 8612), which expects the Rec is already in DB? It gives error "The value for the key filed Document Type is not filled for the instance"...

    If using the OnAfterInsert the record is stored correctly in the database (in this case even with or without the MODIFY). BUT... The problem here is that I need to refresh the page (F5) to get the value visible (i.e. re-read it from DB, since it was changed by the above mentioned function). If I don't refresh the page and continue editing, the system gives me an error "An attempt was made to change an old version of a Sales Header record.".
  • Options
    Manifold78Manifold78 Member Posts: 7
    Thanks for the hint :). Now it seems to work!
Sign In or Register to comment.