14 Replies Latest reply on Jul 3, 2014 11:08 PM by user19752

    Incremental Date Custom Function

    Hudi

      Hi and happy 4th to all.

       

      I need some help creating a recursive custom function that will return an incremental list of dates.

       

      Here's what I have so far. It's my fist attempt at a recursive function, up untli now I've been using the ones other have written. I'm hoping someone can tell me why so I can learn about recursive functions.

      CFincrementDate ( startDate ; increment ; number_of_increments )

      Case (

       

      number_of_increments >1

      ; CFincrementDate ( startDate + increment & "¶" ; increment; number_of_increments -1 )

      )

       

      What I'd like to see is:

      CFincrementDate ( 1/1/2014 ; 10 ; 3 )

       

      1/1/2014

      1/11/2014

      1/22/2014

       

      Thank you so much

        • 1. Re: Incremental Date Custom Function
          ChadAdams

          Looks to me like you just need an "exit" condition.  You currently have it checking to see if the increments are > 1 then recursivly call the function again, but you don't have it doing anything when the increments are not > 1.

           

          Try this:

           

          Case (

             number_of_increments > 1 ;

             CFincrementDate ( startDate + increment & "¶" ; increment ; number_of_increments -1 ) ;

             startDate 

          )

           

          Disclaimer: I've not tested the above.  CF's are always a little bit of a mind warp for me :-)  I can never remember if this will produce:

          1/1/2014

          1/11/2014

          1/21/2014

           

          OR

           

          1/21/2014

          1/11/2014

          1/1/2014

           

           

          Chad

          • 2. Re: Incremental Date Custom Function
            Hudi

            Hi Chad,

             

            Thank you for the quick reply.

             

            At least now it's returnign something whereas before I was gettiing nothing.

             

            But, it's adding the dates together and giving me one number instead of a list.


            Any ideas?

            • 3. Re: Incremental Date Custom Function
              Mike_Mitchell

              Your list of dates is text. In order to add a number of days, you need to tell FileMaker two things: First, to parse the value as a date, and second, that you want to extract a particular value from the list. Example:

               

              1/1/2014

              1/11/2014

               

              That's two values in a return delimited list. If you want to add 10 days to the second value, you need:

               

                   GetAsDate ( GetValue ( theList ; 2 )) + 10

               

              Then you can do:

               

                   List ( theList ; GetAsDate ( GetValue ( theList ; 2 )) + 10 )

               

              to get the next iteration.

              1 of 1 people found this helpful
              • 4. Re: Incremental Date Custom Function
                Hudi

                Mike,

                 

                Maybe I'm not understanding correctly. I'm starting with just one date that I'd like to make into a list. So if I start on 1/1/2014 and have 3 10-day increments (1/1/2014 ; 10 ; 3 ) it will return this:

                 

                1/1/2014

                1/11/2014

                1/22/2014

                 

                Thanks

                • 5. Re: Incremental Date Custom Function
                  ChadAdams

                  This probably isn't the most elegant way, but this seems to work:

                   

                  Case (

                     number_of_increments > 1 ;

                     startDate & ¶ & CFincrementDate ( GetAsDate ( startDate ) + increment ; increment ; number_of_increments - 1 ) ;

                     startDate

                  )

                   

                  Chad

                  • 6. Re: Incremental Date Custom Function
                    Hudi

                    Chad,

                     

                    Works great!

                     

                    I put in bold what you changed from the previous answer. So Mike was right that we needed the GetAsDate function, when FM was giving us a number. And we needed to tell the function to start with the ::startDate. Cool. Thanks Chad and Mike!

                     

                    Case (

                       number_of_increments > 1 ;

                      startDate & ¶ & CFincrementDate ( GetAsDate ( startDate ) + increment ; increment ; number_of_increments - 1 ) ;

                       startDate

                    )

                    • 7. Re: Incremental Date Custom Function
                      ChadAdams

                      Ok, so this will probably seem weird, but I find it useful.

                       

                      I've been working with FileMaker a long time, and my brain does well when thinking about scripts.  Sometimes when I'm trying to get a recursive custom function to work out right, I'll write a script to do the same thing then reverse engineer it into the custom function :-)

                       

                      For example with your CF, it might look like this:

                       

                      Script Name = RecursiveExample

                       

                      Set Variable $startDate ; GetAsDate( GetValue ( Get( ScriptParameter ) ; 1 ) )

                      Set Variable $increment ; GetValue ( Get( ScriptParameter ) ; 2 )

                      Set Variable $numIncrements ; GetValue ( Get( ScriptParameter ) ; 3 )

                      #

                      IF $numIncrements > 1

                         Set Variable $$theResult ; Case( not IsEmpty ( $$theResult ) ; $$theResult & ¶ ) & $startDate

                         Perform Script "RecursiveExample" ; Parameter: $startDate + $increment & ¶ & $increment & ¶ & $numIncrements - 1

                      Else

                         Set Variable $$theResult ; Case( not IsEmpty ( $$theResult ) ; $$theResult & ¶ ) & $startDate

                      End IF

                       

                      For some reason I can get my head around that much easier than I can the recursive function.  Maybe it is because I can see the scripts stacking up in the debugger window...I don't know.

                       

                      Chad

                       

                      Message was edited by: ChadAdams - Cleaned up some GetAsDate stuff that was only there because I was copy and pasting script step examples.

                      • 8. Re: Incremental Date Custom Function
                        beverly

                        That and Loop, Exit Loop and End Loop for the "recursive" part.

                         

                        I almost prefer using Scripts & variables set by Let() and Loops if needed over Custom functions. Scripts are easy to print out, CustFns are not....

                        Beverly

                        • 9. Re: Incremental Date Custom Function
                          erolst

                          ChadAdams wrote:

                           

                          For some reason I can get my head around that much easier than I can the recursive function.  Maybe it is because I can see the scripts stacking up in the debugger window...I don't know.

                           

                          I find that Let () helps in this regard , since you can stack and calculate intermediate variables in a similar fashion. Here's another take:

                           

                          CFincrementDate (startDate ; increment ; iterations ) =

                           

                          List (

                            startDate ;

                            Case ( Iterations > 1 ; CFincrementDate ( startDate + increment ; increment ; Iterations - 1  ) )

                          )

                           

                          though in this case Let() helps more with shortening the expression than actual readibility.

                          • 10. Re: Incremental Date Custom Function
                            ChadAdams

                            That and Loop, Exit Loop and End Loop for the "recursive" part.

                             

                            I almost prefer using Scripts & variables set by Let() and Loops if needed over Custom functions. Scripts are easy to print out, CustFns are not....

                            Beverly

                             

                            I agree! Scripts rule :-)

                             

                            As for the recursive part of the example above, the script calls it self so no loops needed.  If I were solving the problem I'd totally use the loops as you suggest, but when trying to "script my way to a CF" performing the script from itself seems a more accurate metaphor.

                             

                            Chad

                            • 11. Re: Incremental Date Custom Function
                              Mike_Mitchell

                              Additionally, scripts can be copied / imported without needing Advanced.

                               

                              About the only real advantage CFs enjoy is incorporation into the calc engine.

                              • 12. Re: Incremental Date Custom Function
                                BruceRobertson

                                " in this case Let() helps more with shortening the expression..."

                                 

                                Hm.

                                 

                                But in this case - there was not Let() statement at all in your example.

                                • 13. Re: Incremental Date Custom Function
                                  erolst

                                  BruceRobertson wrote:

                                   

                                  " in this case Let() helps more with shortening the expression..."

                                   

                                  Hm.

                                   

                                  But in this case - there was not Let() statement at all in your example.

                                   

                                  Good catch! I was just testing if you're all still awake …

                                   

                                  This used to be

                                   

                                  Let ( [

                                    sd = startDate ;

                                    inc = increment

                                    ] ;

                                    List (

                                      sd ;

                                      Case ( Iterations > 1 ; CFincrementDate ( sd + inc ; inc ; Iterations - 1  ) )

                                    )

                                  )

                                   

                                  I changed it and forgot to modify the text accordingly.

                                  • 14. Re: Incremental Date Custom Function
                                    user19752

                                    number_of_increments is limited up to 10000 in this CF.

                                    It should be big enough, but for example changing it to 'tail recursion' like as first you wrote.

                                     

                                    Case (

                                       number_of_increments < 2 ;

                                       dateList ;

                                       CFincrementDate3 ( dateList & ¶ & GetAsDate ( RightValues ( dateList ; 1 ) ) + increment ; increment ; number_of_increments - 1 )

                                    )

                                     

                                    I changed name of first parameter as 'dateList', but of cource it can be a date.