Options

What makes this loop code went wrong?!

jemmyjemmy Member Posts: 247
Folks,

I just passed my C/Side Intro exam. :D
Need to go further C/Side solution dev.
Customer.SETCURRENTKEY ("Credit Limit (LCY)");
Customer.SETFILTER ("Credit Limit (LCY)", '=0');
Customer.FIND ('-');
REPEAT
   Customer.CALCFIELDS (Balance);
   IF Customer.Balance <> 0 THEN
      Customer."Credit Limit (LCY)" := Customer.Balance
   ELSE
      Customer.”Credit Limit (LCY)" := 10000;
   Customer.modify;
UNTIL Customer.NEXT = 0;

The loop only occurs once, which part of this code goes wrong?

Please advice, and thanks as always.

Jemmy

Comments

  • Options
    jhoekjhoek Member Posts: 216
    Do your modifications on a different Customer record variable, as the modified Customer in your example no longer matches the filter criteria after modification:
    Customer.CALCFIELDS (Balance); 
    Customer2 := Customer;
    IF Customer.Balance <> 0 THEN 
      Customer2."Credit Limit (LCY)" := Customer.Balance 
    ELSE 
      Customer2.”Credit Limit (LCY)" := 10000; 
    Customer2.modify;
    
    Kind regards,

    Jan Hoek
    Product Developer
    Mprise Products B.V.
  • Options
    s.delikostovs.delikostov Member Posts: 32
    Customer.SETCURRENTKEY ("Credit Limit (LCY)");
    Customer.SETFILTER ("Credit Limit (LCY)", '=0');
    WHILE Customer.FIND ('-') DO BEGIN
       Customer.CALCFIELDS (Balance);
       IF Customer.Balance <> 0 THEN
         Customer."Credit Limit (LCY)" := Customer.Balance
       ELSE
         Customer.”Credit Limit (LCY)" := 10000;
       Customer.modify;
    END;
    
    Stamen Delikostov
    Navision Solution Developer
    Intelligent Systems Bulgaria
  • Options
    jemmyjemmy Member Posts: 247
    Strange! :shock:
    Where are the other posted message from Steve0?

    To s.delikostov, thank you for your enlighments!
    WHILE Customer.FIND ('-')
    Does it means the pointer always take the "unprocessed" first record?

    Jemmy
  • Options
    s.delikostovs.delikostov Member Posts: 32
    It always take first record in the filter.
    When you modify Credit Limit with value different from 0, this record will be excluded form the filter set.
    Stamen Delikostov
    Navision Solution Developer
    Intelligent Systems Bulgaria
  • Options
    pdjpdj Member Posts: 643
    If you wish to pass the C/Side solution dev exam as well you should stop doing like this:
    Customer.SETFILTER ("Credit Limit (LCY)", '=0');
    
    Only use SETFILTER when you wish to set a filter that can't be set using SETRANGE. :-)
    Regards
    Peter
  • Options
    DenSterDenSter Member Posts: 8,304
    pdj wrote:
    If you wish to pass the C/Side solution dev exam as well you should stop doing like this:
    Customer.SETFILTER ("Credit Limit (LCY)", '=0');
    
    Only use SETFILTER when you wish to set a filter that can't be set using SETRANGE. :-)
    There's nothing wrong with that filter, why should anyone stop filtering that way?
  • Options
    KowaKowa Member Posts: 918
    edited 2005-05-06
    There's nothing wrong with that filter, why should anyone stop filtering that way?

    Because the style guide says so (even some of the standard code was reworked in recent versions to comply to these guidelines, Denmark gets it wrong sometimes too) :?

    SETRANGE appears to me to be a little bit faster than SETFILTER, noticeably on non-key fields in tables with millions of records .
    Kai Kowalewski
  • Options
    pdjpdj Member Posts: 643
    Kowa wrote:
    Because the style guide says so
    That's also my argument. I don't think there is any speed difference, but I don't know.

    Secondly I have seen a lot of developers setting filters like this: SETFILTER("Some Field","Some Value") and this causes strange effects when "Some Value" suddenly contains &, * or |. So I always say that you should be careful using SETFILTER and only use it when it can't be done using SETRANGE.

    I even do like this: SETRANGE("Some Date Field",TODAY,31129999D) eventhough I know that's not common in the standard application.
    Regards
    Peter
  • Options
    jemmyjemmy Member Posts: 247
    There is another point which I hate to bring up, but it is necessary...
    I always use a constant value while filtering "Some Field"... I haven't written a plenty of applications, but I always use "constant" in the "Some Value".
    I realized that SETFILTER is not the easiest way in Navision to get along with... yeah better SETRANGE takes a higher priority rather than SETFILTER. (I also don't know their speed) :|

    Jemmy
  • Options
    kinekine Member Posts: 12,562
    Correct codes:
    Customer.SETCURRENTKEY ("Credit Limit (LCY)");
    Customer.SETRANGE("Credit Limit (LCY)", 0);
    if Customer.FIND ('-') then
    repeat
       Customer.CALCFIELDS (Balance);
       OldLimit := Customer."Credit Limit (LCY)";
       IF Customer.Balance <> 0 THEN
         Customer."Credit Limit (LCY)" := Customer.Balance
       ELSE
         Customer.”Credit Limit (LCY)" := 10000;
       Customer.modify;
       Customer.”Credit Limit (LCY)" := OldLimit; //return old value without modify
    until Customer.NEXT=0;
    
    Customer.SETCURRENTKEY ("Credit Limit (LCY)");
    Customer.SETRANGE("Credit Limit (LCY)", 0);
    if Customer.FIND ('-') then
    repeat
       Customer.CALCFIELDS (Balance);
       Customer2 := Customer;
       IF Customer.Balance <> 0 THEN
         Customer2."Credit Limit (LCY)" := Customer.Balance
       ELSE
         Customer2.”Credit Limit (LCY)" := 10000;
       Customer2.modify;
    modify
    until Customer.NEXT=0;
    

    Other code are not "clean"...
    Kamil Sacek
    MVP - Dynamics NAV
    My BLOG
    NAVERTICA a.s.
  • Options
    DenSterDenSter Member Posts: 8,304
    pdj wrote:
    Kowa wrote:
    Because the style guide says so
    That's also my argument. I don't think there is any speed difference, but I don't know.

    Secondly I have seen a lot of developers setting filters like this: SETFILTER("Some Field","Some Value") and this causes strange effects when "Some Value" suddenly contains &, * or |. So I always say that you should be careful using SETFILTER and only use it when it can't be done using SETRANGE.

    I even do like this: SETRANGE("Some Date Field",TODAY,31129999D) eventhough I know that's not common in the standard application.
    I only use SETRANGE if I need to set a range. If I need to filter on one value, I use SETFILTER. SETRANGE is nothing more than a fancy SETFILTER, inside the executable it translates it into the right SETFILTERS anyway.

    SETFILTER("Some Field","Some Value") is perfectly legitimate, only you should do it like SETFILTER("Some Field",'=%1',"Some Value"), and use the FORMAT statement as it is appropriate. That way you could also do SETFILTER("Some Field",'=*%1*',"Some Value"), and your wildcards are taken care of right there.

    I don't like the use of hard coded artificial end dates. If I need to set a filter on a date I use SETFILTER("Some Date Field",'>=%1',"Some Date Value"). The speed of the query depends on you setting the right key with SETCURRENTKEY.
Sign In or Register to comment.