Form closing automatically after showing ERROR dialog

rmpatel22rmpatel22 Member Posts: 80
Hi All,

I have added some validations as below on OnInsert Trigger of one form, but when "Direct Unit Cost" is zero, it is showing ERROR message and closing form automatically.

I searched this forum for same problem, and found that if validation is there on Form this problem can happen, but for me its on Table. And I need to validate on OnInsert Trigger not on Field's OnValidate trigger.

IF Quantity <= 0 THEN
ERROR(Text037,Quantity);

IF "Direct Unit Cost" <= 0 THEN BEGIN
ERROR(Text038,"Direct Unit Cost");
END;

I don't want to close form after ERROR, is there any way to do that ?
Rakesh Patel
Navision Developer
«1

Comments

  • chengalasettyvsraochengalasettyvsrao Member Posts: 711
    I am not a techie , but u can try to put code in Form - OnCloseForm()
  • ShedmanShedman Member Posts: 194
    Coding it in OnCloseForm() will also result in closing the form. You could put it OnQueryCloseForm(), then your form will remain open even after an error.
  • BeliasBelias Member Posts: 2,998
    or you can set the MinValue property of the textbox (or of the field if you want this check on all your forms) to 0...no code, no problems, no text constants to translate... :wink:
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • DenSterDenSter Member Posts: 8,307
    When developing data validation logic, you should stick with one very important rule: NEVER program data validation code on forms, ALWAYS program this code in table triggers.

    Your form closes because you've programmed the form to cause an error. When a form causes an error, the system closes it. You will not be able to change this behavior. Data validation code belongs in tables, not in forms.
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Its Navision, do it the Navision way, if the client does not want Navision, why did they buy it?
    David Singleton
  • SavatageSavatage Member Posts: 7,142
    Belias wrote:
    or you can set the MinValue property of the textbox (or of the field if you want this check on all your forms) to 0...no code, no problems, no text constants to translate... :wink:

    He can try MinValue 0.00000001 8)
    But they have to enter it into the field for the message to appear
  • rmpatel22rmpatel22 Member Posts: 80
    Thanks all for your replies.

    As advised by some users I am not putting validation on Form but putting on OnInsert trigger of Table but its not working (I think if I put it on OnValidate event of field it will work, but in my case user may not go to this field, then it will not trigger Validation). MinValue I can't use because user may not go to this field.
    Rakesh Patel
    Navision Developer
  • SavatageSavatage Member Posts: 7,142
    So it sounds like you want this field to be mandatory. If so search the forum for "Mandatory field" for many posts.

    On insert of the table, you are talking about the entire record not just that field. what & where is the code you put on the table?
  • rmpatel22rmpatel22 Member Posts: 80
    I am trying to put this validation on Purchase Oorder form, here we have team who enters cost for items and another team who creates PO.
    We are calculating cost automatically when user enters barcode/item code and quantity. So no need for user to go on that field and enter cost manually. But sometimes they are trying to create PO without entering cost in system and its creating with zero cost. So to avoid this we want to put validation OnInsert to stop them adding record if cost is zero.

    Savatage,

    I have added following code on OnInsert trigger of table,

    IF "Direct Unit Cost" <= 0 THEN BEGIN
    ERROR(Text038,"Direct Unit Cost");
    END;

    and when user trying to enter record with 0 value in "Direct Unit Cost" field, it is closing for after giving error. We need to keep form open after showing error.
    Rakesh Patel
    Navision Developer
  • SavatageSavatage Member Posts: 7,142
    Would a message be enough for you?

    IF "Direct Unit Cost" <= 0 THEN BEGIN
    MESSAGE(Text038,"Direct Unit Cost");
    END;

    Or are you looking for a message and the line to clear?
  • rmpatel22rmpatel22 Member Posts: 80
    Hi Savatage, Thanks for your replay.

    My code is there in OnInsert, so if i am trying to put MESSAGE, it is showing message and inserting record, i don't want to insert record if value is zero.
    Rakesh Patel
    Navision Developer
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Savatage wrote:
    So it sounds like you want this field to be mandatory. If so search the forum for "Mandatory field" for many posts.

    rmpatel22 did you read this?
    David Singleton
  • rmpatel22rmpatel22 Member Posts: 80
    Thanks David Singleton,

    I will try to search solution with "Mandatory field" keyword now.
    Rakesh Patel
    Navision Developer
  • SavatageSavatage Member Posts: 7,142
    edited 2010-02-04
    rmpatel22 wrote:
    it is showing message and inserting record, i don't want to insert record if value is zero.

    It still requires user intervention, if they choose to ignore it then that's another story.

    2nd, I'm assuming these are items your inserting into an order or PO or recipt. So if the cost is never supposed to be zero then why isn't that addressed when the item is being entered to begin with, instead of trying to stop it in different parts of the system?

    3rd, today zero might not be acceptable, how about in the future? Perhaps a CONFIRM would be better therefore giving the choice to the user.
    ex message/
    "This Item has a unit cost of Zero. Is this correct?" user intervention required for y/n
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Savatage wrote:
    ...
    2nd, I'm assuming these are items your inserting into an order or PO or recipt. So if the cost is never supposed to be zero then why isn't that addressed when the item is being entered to begin with, instead of trying to stop it in different parts of the system?

    I will bet it started with a conversation that started something like :

    "But our old system did it this way..."
    David Singleton
  • DaveusDaveus Member Posts: 8
    Hi All

    I have the exact same problem than RMPATEL22: On the "OnInsert" trigger of my table, I need to validate couple fields BEFORE allowing the insertion, and if one or more of these fields are not valide, well I need to ROLLBACK, and as far as I know, the only way to rollback is by using the ERROR() fonction. I do not want my form to close right away after the error message since I need the user to correct his line before trying again. I don't get the logique of why my form is closing while the trigger is on my table.

    The solutions proposed here so far in this blog don't apply to my case: Anyone has a REAL solution please, AND/OR can explain why a form is closing by itself right after an Error called on the "OnInsert" trigger of its table?

    Thanx
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Daveus wrote:
    Hi All

    I have the exact same problem than RMPATEL22: On the "OnInsert" trigger of my table, I need to validate couple fields BEFORE allowing the insertion, and if one or more of these fields are not valide, well I need to ROLLBACK, and as far as I know, the only way to rollback is by using the ERROR() fonction. I do not want my form to close right away after the error message since I need the user to correct his line before trying again. I don't get the logique of why my form is closing while the trigger is on my table.

    The solutions proposed here so far in this blog don't apply to my case: Anyone has a REAL solution please, AND/OR can explain why a form is closing by itself right after an Error called on the "OnInsert" trigger of its table?

    Thanx


    Forget about the code, and instead explain what you are trying to do. Explain the business need.
    David Singleton
  • DaveusDaveus Member Posts: 8
    When adding an Item ( ...to Sales Lines) to an Order (Sales Order), I need to validate that this Item is valide for that order, like being available at a certain date, date that appears in the header (...and specified by the user) and other validations that have to be checked before inserting that item. If the validation fails, the insertion as to be refused, than the user would have to correct the header details, or use another item.

    In other words, I need the Error() fonction to behave in the OnInsert trigger of my table like it behaves everywhere else.

    Thanx
  • DaveusDaveus Member Posts: 8
    ...or is there a ROLLBACK fonction?
  • SavatageSavatage Member Posts: 7,142
    The closest thing we have added is that we %99.999 of the time should not have the same item number on an sales order. So we have a check in place to see if it already exists on an order and if it does it gives a message. If you say no to the message the item number is cleared.
    No. - OnValidate()
    SalesLineChk.SETCURRENTKEY("Document Type", "Document No.");
    SalesLineChk.SETRANGE("Document Type", "Document Type");
    SalesLineChk.SETRANGE("Document No.", "Document No.");
    SalesLineChk.SETRANGE(Type,SalesLineChk.Type::Item);
    Existed := FALSE;
    IF NOT ("Document Type" IN ["Document Type"::"Return Order","Document Type"::"Credit Memo"])
    THEN BEGIN
    IF SalesLineChk.FIND('-') THEN REPEAT
        IF SalesLineChk."No." = "No." THEN
          IF NOT CONFIRM ('Item Already on order. Do you want to add item again?') THEN BEGIN
              MESSAGE('Item disregarded.');
              "No." := '';
              SalesLineChk.NEXT := 0;
            END ELSE
            Existed := TRUE;
      UNTIL (SalesLineChk.NEXT = 0) OR Existed;
    END;
    

    -Another idea is to run a check with similar code as above. It runs thru the lines with FIND checking your fields on "Release" of your order. If errors exist then it will not allow you to release the order. What makes this easier is that the data is already entered therefore easily verified. The problem lies when the data is typed but not inserted. This is where you problem is.
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Daveus wrote:
    When adding an Item ( ...to Sales Lines) to an Order (Sales Order), I need to validate that this Item is valide for that order, like being available at a certain date, date that appears in the header (...and specified by the user) and other validations that have to be checked before inserting that item. If the validation fails, the insertion as to be refused, than the user would have to correct the header details, or use another item.

    In other words, I need the Error() fonction to behave in the OnInsert trigger of my table like it behaves everywhere else.

    Thanx

    Put the validation in the OnValidate of the "No." field.

    If you for soe reason can't accept this as a solution you need to really think about why you bought Navision. If your old system did it the way you want to do it, why did you change to Navision?
    David Singleton
  • DenSterDenSter Member Posts: 8,307
    Daveus wrote:
    I need to validate couple fields BEFORE allowing the insertion, and if one or more of these fields are not valide, well I need to ROLLBACK, and as far as I know, the only way to rollback is by using the ERROR() fonction.
    Your validation code should go into the OnValidate trigger of the field itself. The trigger is called "OnValidate" for a good reason. Any error in the OnValidate trigger of the field in the table object WILL NOT cause the form to close. If your form closes due to an ERROR in an OnValidate trigger, that means that the trigger is the one on the form object, not in the table.
    Daveus wrote:
    I do not want my form to close right away after the error message since I need the user to correct his line before trying again. I don't get the logique of why my form is closing while the trigger is on my table.
    Again, an ERROR in a table trigger DOES NOT cause the form to close. If your form closes when you get an error that means that the ERROR is caused by something on the form.
    Daveus wrote:
    The solutions proposed here so far in this blog don't apply to my case: Anyone has a REAL solution please
    <snip>
    explain why a form is closing by itself right after an Error called on the "OnInsert" trigger of its table?
    I don't think you are really listening to the solutions, or you are not working your way through the entire problem, because forms simply do not close when an ERROR is caused in a table trigger. Again, an ERROR in the OnInsert trigger WILL NOT cause the form to close. If your form closes due to an ERROR, that means that the error is caused by something on the form itself.
    Daveus wrote:
    When adding an Item ( ...to Sales Lines) to an Order (Sales Order), I need to validate that this Item is valide for that order, like being available at a certain date, date that appears in the header (...and specified by the user) and other validations that have to be checked before inserting that item. If the validation fails, the insertion as to be refused, than the user would have to correct the header details, or use another item.
    So you want the value that is entered into the "No." field to be validated. Put the validation code for this functionality into the OnValidate trigger (not the OnInsert trigger) of the "No." field in the table object (NOT the form object), and the form will never close as a result of the error.
    Daveus wrote:
    In other words, I need the Error() fonction to behave in the OnInsert trigger of my table like it behaves everywhere else.
    You need the code to be in the OnValidate trigger of the field, not the OnInsert trigger.
    Daveus wrote:
    ...or is there a ROLLBACK fonction?
    No there is no ROLLBACK function. ERROR will roll the transaction back automatically to the last COMMIT point, which is either where you started the manual transaction or if the code contains an explicit COMMIT statement..
  • DenSterDenSter Member Posts: 8,307
    Here's an example. A table number 50000 with errors in the description field's OnValidate trigger and the table's OnInsert trigger, and a form number 50000 with an error in the field OnValidate.

    Run the form, and do the following:
    • enter a description with the word "field" in it. You will notice that you get an ERROR, which is programmed in the OnValidate trigger of the table object. Note that the form does not close, because the error happens in the table.
    • Then enter a description with the word "insert" and see how you get an ERROR, this time programmed in the table object's OnInsert trigger. Note that again the form remains open, because the error is not on the form but in the table.

    I've tried copying the code that causes the error into the form's OnValidate and OnInsert triggers, in 4.0SP3 and in 2009SP1 and it is not even closing the form then for me. ERRORS should only close forms when they happen on the form. When ERRORs happen in tables, they should NEVER close the form.
    OBJECT Table 50000 test table
    {
      OBJECT-PROPERTIES
      {
        Date=02/05/10;
        Time=11:08:22 PM;
        Modified=Yes;
        Version List=;
      }
      PROPERTIES
      {
        OnInsert=BEGIN
                   IF STRPOS(description,'insert') <> 0 THEN
                     ERROR('error in OnInsert - table');
                 END;
    
      }
      FIELDS
      {
        { 1   ;   ;code                ;Code10         }
        { 2   ;   ;description         ;Text30        ;OnValidate=BEGIN
                                                                    IF STRPOS(description,'field') <> 0 THEN
                                                                      ERROR('error in Description field OnValidate - table');
                                                                  END;
                                                                   }
      }
      KEYS
      {
        {    ;code                                    ;Clustered=Yes }
      }
      CODE
      {
    
        BEGIN
        END.
      }
    }
    
    OBJECT Form 50000 test form
    {
      OBJECT-PROPERTIES
      {
        Date=02/05/10;
        Time=11:08:41 PM;
        Modified=Yes;
        Version List=;
      }
      PROPERTIES
      {
        Width=9790;
        Height=6710;
        TableBoxID=1000000000;
        SourceTable=Table50000;
        DelayedInsert=Yes;
      }
      CONTROLS
      {
        { 1000000000;TableBox;220 ;220  ;9350 ;5500 ;HorzGlue=Both;
                                                     VertGlue=Both }
        { 1000000001;TextBox;0    ;0    ;1700 ;0    ;ParentControl=1000000000;
                                                     InColumn=Yes;
                                                     SourceExpr=code }
        { 1000000002;Label  ;0    ;0    ;0    ;0    ;ParentControl=1000000001;
                                                     InColumnHeading=Yes }
        { 1000000003;TextBox;0    ;0    ;4400 ;0    ;HorzGlue=Both;
                                                     ParentControl=1000000000;
                                                     InColumn=Yes;
                                                     SourceExpr=description;
                                                     OnValidate=BEGIN
                                                                  IF STRPOS(description,'form') <> 0 THEN
                                                                    ERROR('error in Description field OnValidate - form');
                                                                END;
                                                                 }
        { 1000000004;Label  ;0    ;0    ;0    ;0    ;ParentControl=1000000003;
                                                     InColumnHeading=Yes }
        { 1000000005;CommandButton;2530;5940;2200;550;
                                                     HorzGlue=Right;
                                                     VertGlue=Bottom;
                                                     Default=Yes;
                                                     PushAction=LookupOK;
                                                     InvalidActionAppearance=Hide }
        { 1000000006;CommandButton;4950;5940;2200;550;
                                                     HorzGlue=Right;
                                                     VertGlue=Bottom;
                                                     Cancel=Yes;
                                                     PushAction=LookupCancel;
                                                     InvalidActionAppearance=Hide }
        { 1000000007;CommandButton;7370;5940;2200;550;
                                                     HorzGlue=Right;
                                                     VertGlue=Bottom;
                                                     PushAction=FormHelp }
      }
      CODE
      {
    
        BEGIN
        END.
      }
    }
    
    
    <edit>removed FIELDGROUPS, so you can use it with other versions than NAV2009</edit>
  • DaveusDaveus Member Posts: 8
    DenSter wrote:
    Again, an ERROR in the OnInsert trigger WILL NOT cause the form to close.


    ...I beg you pardon, but YES, it does!!


    Thanx anyways: I'll try to with the OnValidate trigger
  • DenSterDenSter Member Posts: 8,307
    Daveus wrote:
    DenSter wrote:
    Again, an ERROR in the OnInsert trigger WILL NOT cause the form to close.


    ...I beg you pardon, but YES, it does!!


    Thanx anyways: I'll try to with the OnValidate trigger
    No it really doesn't. The form is closed by something else.

    Perhaps there is an INSERT(TRUE) call in some logic on the form.
  • David_SingletonDavid_Singleton Member Posts: 5,479
    I just created this form and table, and the form does NOT close on error:
    OBJECT Table 98788 Test insert error
    {
      OBJECT-PROPERTIES
      {
        Date=02/08/10;
        Time=20:37:33;
        Modified=Yes;
        Version List=;
      }
      PROPERTIES
      {
        OnInsert=BEGIN
                   IF Code IN ['Z','X'] THEN
                     ERROR('Will this close the form (Code on table)');
                 END;
    
      }
      FIELDS
      {
        { 1   ;   ;Code                ;Code10         }
        { 2   ;   ;Text                ;Text30         }
      }
      KEYS
      {
        {    ;Code                                    ;Clustered=Yes }
      }
      CODE
      {
    
        BEGIN
        END.
      }
    }
    
    OBJECT Form 98788 Test insert close
    {
      OBJECT-PROPERTIES
      {
        Date=02/08/10;
        Time=20:37:20;
        Modified=Yes;
        Version List=;
      }
      PROPERTIES
      {
        Width=9790;
        Height=6160;
        SourceTable=Table98788;
        OnInsertRecord=BEGIN
                         IF Code IN ['T','S'] THEN
                           ERROR('Will this close the form(code on form)');
                       END;
    
      }
      CONTROLS
      {
        { 1   ;Frame        ;220  ;220  ;9350 ;4950 ;HorzGlue=Both;
                                                     VertGlue=Both;
                                                     ShowCaption=No }
        { 2   ;TextBox      ;3850 ;440  ;2750 ;440  ;ParentControl=1;
                                                     InFrame=Yes;
                                                     SourceExpr=Code }
        { 3   ;Label        ;440  ;440  ;3300 ;440  ;ParentControl=2 }
        { 4   ;TextBox      ;3850 ;990  ;5500 ;440  ;ParentControl=1;
                                                     InFrame=Yes;
                                                     SourceExpr=Text }
        { 5   ;Label        ;440  ;990  ;3300 ;440  ;ParentControl=4 }
        { 6   ;CommandButton;7370 ;5390 ;2200 ;550  ;HorzGlue=Right;
                                                     VertGlue=Bottom;
                                                     PushAction=FormHelp }
      }
      CODE
      {
    
        BEGIN
        END.
      }
    }
    
    

    Daveus maybe try the debugger to see where the form is closing. Though it may be impossible, since the debugger will probably trap on the first error message, not necessarily the one closing the form.

    But try this form and table above, you will see that it does not close, so there must be something else in your code.
    David Singleton
  • DaveusDaveus Member Posts: 8
    I just created this form and table, and the form does NOT close on error:

    You're right, but for a reason that I can't explain, if I put an Error() right on the very first line of the OnInsert trigger of the "36-Sales Line" table, before any other line of codes, and then run the "42-Sales Order" form, then attempting to create a new sales line, the error will pop-up, then the "42-Sales Order" form will close by itself. The mentionned form and table involved had never been modified before.

    But anyways, you told me to use the OnValidate trigger rather than the OnInsert trigger, and I now believe it's a better pratice, except that a line is created, then it is validated, wich means that a line is created even dough it's validation had failed! I would have liked to validate, then create the line after a successfull validation.

    Sorry about the confusion: You're right that an Error() does not close a form, except for the case I just described.

    Thanx for your time...
  • DenSterDenSter Member Posts: 8,307
    Daveus wrote:
    But anyways, you told me to use the OnValidate trigger rather than the OnInsert trigger, and I now believe it's a better pratice, except that a line is created, then it is validated, wich means that a line is created even dough it's validation had failed! I would have liked to validate, then create the line after a successfull validation.

    Sorry about the confusion: You're right that an Error() does not close a form, except for the case I just described.
    The record doesn't have to be inserted for OnValidate to run successfully. It runs just fine for records that have not yet been inserted. OnValidate and OnInsert are two separate events. If your form inserts a sales line before "No." is validated on a new line, it is probably modified.

    By the way, I took a standard NAV2009SP1 US database, modified the Sales Line table like you suggested, and the sales order form does not close as a result of this error. I don't think you are working with unmodified objects, but you'd have to run the debugger to make sure what happens at what time. Which version are you on?
  • DaveusDaveus Member Posts: 8
    I'm using NAV 5.0 SP1, maybe it's a bit outdated compare with NAV 2009 ( ...we're using that version because of a particular add-on module made by a third party company, Pebblestone, and they're not yet ready, as of today (2010-02-08), to release their module updated and compatible with NAV 2009 ).

    Again, thanx
  • DenSterDenSter Member Posts: 8,307
    I took a standard 5.0 SP1 database and did the same test, and again, the error in OnInsert does not cause the form to close. Completely expected, because it's not supposed to.

    There must be something else going on :-k
Sign In or Register to comment.