Navision Function not working as expected.

thetallblokethetallbloke Member Posts: 66
Hi guys,

I have some weird behaviour with a function that I've written.

I have a form that accepts the following:
gPeriod (just a year and month in the format of YYYY/MM)
gVendor (a record variable from the vendor table)
gSelectRetentionFlag (a boolean variable to help with setting filters)
also a grid at the bottom of the window that shows all records that fall within the filter.

I want to have my users enter a period, select a vendor (from lookup) and toggle the retention flag and as they do, the ApplyFilter function called to reflect the changes in the grid.

My problem is kinda weird from about now... I have the following triggers set:
gSelectRetentionFlag - on the tickbox control I call the ApplyFilter function (below) from OnPush trigger, and it applies the filter correctly using the mouse to click in the tickbox.

On the textbox that is linked to gPeriod, the OnDeactivate trigger calls the ApplyFilter function. This doesn't seem to work correctly. If I type the value and then hit TAB, the ApplyFilter runs perfectly, but if I click outside the textbox or into another control, I either get additional records in my grid or no records at all.

The same happens for the gVendor lookup field. If I type in the Vendor No. and hit TAB, the ApplyFilter works fine, but if I click onto another control (thus correctly firing the OnDeactivate trigger) I get additional or no records in the grid.

I have tried puting in breakpoints and debugging and both times (keyboard or mouse clicking) the code appears to execute the same. I've even put in MESSAGE calls to check the flow when I'm not debugging, but it makes no difference...

Am I hitting a known bug, or is there anything that anyone can suggest I try to see whats happening...???
I have a menubutton at the bottom of my form that I can call ApplyFilter from and it works fine then... filters are applied correctly every time.

If you need any clarification or further information please let me know...

Thanks.

ApplyFilter()
IF gVendor."No." > '' THEN BEGIN
IF gPeriod > '' THEN BEGIN
Rec.RESET;
gVendor.FIND();
IF gVendor.Status = 1 THEN BEGIN
gShareholderFlag := TRUE;
END ELSE BEGIN
gShareholderFlag := FALSE;
END;

IF gSelectRetentionFlag = TRUE THEN BEGIN
SETFILTER("Retention Payment",'Yes');
END ELSE BEGIN
SETFILTER("Retention Payment",'No');
END;

IF gPeriod <> '' THEN BEGIN
SETFILTER(Period,gPeriod);
SETFILTER("EDA Paid Status",'Not Paid');
SETFILTER("Vendor No.",gVendor."No.");
END;
END ELSE BEGIN
ClearFilter;
END;
END ELSE BEGIN
ClearFilter;
END;

ClearFilter()
Rec.RESET;
SETFILTER("Customer No.",'-9-');
.
I'm not crazy !!! Just ask my toaster...
.

Comments

  • kinekine Member Posts: 12,562
    I never (or just in some exceptions) have used the OnDeactivate trigger. I am using OnAfterValidate trigger to set filters from the edit box. It is much better and I bet that it will work for you too... ;-)
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • Dave_CintronDave_Cintron Member Posts: 189
    The trouble you're having is familiar to me from when I was working through the foibles of Navision forms. It's hard to debug this based on a prosaic description (no object). First, I would not use onDeactivate, I would use OnValidate. Next, does your form have a source table? Next, I'd like to see the whole object. Next, There are lines of code that are too complicated like your first 2 paragraphs in ApplyFilter can be shortened with
    gShareholderFlag := (gVendor.Status = 1); and
    SETFILTER("Retention Payment",gSelectRetentionFlag);
    Dave Cintron
    Dynamics West
    http://www.dynamicswest.com
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Hi tallbloke,

    I guess what you are wanting here is a magic solution to fix your existing code. Unfortunately its just not that easy. Navision has its way of doing things, and I am guessing that you are not too comfortable with the way it works.

    Instead of starting with a bug in your code and trying to fix it, why not let the big secret out of the bag, and tell us what you are trying to do. If do that we can then let you know "The Navision Way" of doing it properly.
    David Singleton
  • thetallblokethetallbloke Member Posts: 66
    Hi David,

    I guess I'm not all that comfortable in the way Navision works just yet.. I've come from a .net world, and therefore am comfortable in THAT world.. I've been thrown into the deep end with Navision and am still trying to work out the "Navision Way"...

    I'm not really trying to do anything secretive here.. all I want to do is have a centralised way to apply some filters based on user input without recoding the same logic 3 or 4 times... This may sound strange, but I wasn't really posting my code up to have someone provide a magic solution.. although I do really appreciate any comments on my coding, and will certainly try the suggestions made by Dave Cintron to simplify my code a little.
    Also I'll try using the OnAfterValidate trigger as Kine suggested.. I'm still learning.

    I just thought that others may have come across something similar.. as a result I've found out that using the OnDeactivate isn't the best way to trigger this kind of event...


    Tall-ee.
    .
    I'm not crazy !!! Just ask my toaster...
    .
  • DenSterDenSter Member Posts: 8,305
    What you can do is add a function to the form, let's say "ApplyMyFilters", and set the filters using what the user entered into the parameters. Then call the function from each control's OnValidate trigger.

    Let us know if you need help creating the function or finding that trigger. You can find examples of similar calls in the General Journal form (number 39).
  • thetallblokethetallbloke Member Posts: 66
    Hi guys,

    I've managed to fix the problem... \:D/
    I've called the ApplyFilter function from the OnAfterValidate trigger for the three controls that the user can set filter options in...

    I've also added this line near the end, which seems to have worked...
    CurrForm.UPDATE(FALSE);

    ApplyFilter()
    IF gVendorNo > '' THEN BEGIN
      IF gPeriod > '' THEN BEGIN
        Rec.RESET;
        gVendor."No." := gVendorNo;
        gVendor.FIND();
    
        IF gVendor.Status = 1 THEN BEGIN
          gShareholderFlag := TRUE;
        END ELSE BEGIN
          gShareholderFlag := FALSE;
        END;
    
        IF gSelectRetentionFlag = TRUE THEN BEGIN
          SETFILTER("Retention Payment",'Yes');
        END ELSE BEGIN
          SETFILTER("Retention Payment",'No');
        END;
    
        SETFILTER(Period,gPeriod);
        SETFILTER("EDA Paid Status",'Not Paid');
        SETFILTER("Vendor No.",gVendorNo);
    
        {**************************************}
        CurrForm.UPDATE(FALSE);
        {**************************************}
      END ELSE BEGIN
        ClearFilter;
      END;
    END ELSE BEGIN
      ClearFilter;
    END;
    
    .
    I'm not crazy !!! Just ask my toaster...
    .
  • DenSterDenSter Member Posts: 8,305
    Excellent work :mrgreen:

    Couple suggestions:
    1 - When you have all primary key values, instead of
    gVendor."No." := gVendorNo; 
    gVendor.FIND();
    
    do this:
    gVendor.GET(gVendorNo);
    
    When using FIND, you should really use a parameter, such as '-' or '+'. If you're on 4.0 SP2 or later, and you only need one record, and you DONT have all primary key values, use FINDFIRST.

    2 - Instead of SETFILTER, always try to use SETRANGE. It is easier to program, because it is strongtyped, you dn't have to convert to string to make the filter work. Only for complex filters (i.e. if you're filtering on anything other than one value or a range) should you use SETFILTER. So here's the code:
    // don't do this:
      SETFILTER("Retention Payment",'Yes'); 
      SETFILTER("Retention Payment",'No'); 
    //but do this:
      SETRANGE("Retention Payment",TRUE); 
      SETRANGE("Retention Payment",FALSE);
    
  • thetallblokethetallbloke Member Posts: 66
    DenSter,

    Thanks..!!!! I'll go and modify the code with your suggestions...

    Tell-ee
    .
    I'm not crazy !!! Just ask my toaster...
    .
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Hi David,

    I guess I'm not all that comfortable in the way Navision works just yet.. I've come from a .net world, and therefore am comfortable in THAT world.. I've been thrown into the deep end with Navision and am still trying to work out the "Navision Way"...

    ...

    The first thing (before solviing coding issues) if you want to get to understand Navision, is to get the business principles right. If you go down the path of inventing a new way of doing somethign, you will probably get it to work this time, and maybe the next time, but eventually either you will hit a brick wall, or more likely the system will start to grind to a halt. By then the users will be comfortable with the fact that you can "do anything" so will not want to here that they need to do it differently. so its important to do it correctly from the get go.

    So your code may work, but what on earth is is supposed to do? Better would be to state the business need, and then ask "how is this done in Navision" That way we can show you the way to do it in Navision, instead of showing you how to do code work arounds. Yes it will take a bit to change the users to the NAV way, but once changed they will be fine.

    Oh and believe me if you start putting code on forms YOU WILL REGRET IT big time.
    David Singleton
Sign In or Register to comment.