11 Replies Latest reply on Oct 20, 2012 9:35 AM by mdiehr

    What's the correct way to set constants?

    benlevi

      I've been programming w/FM for a long long time, and for some reason I'm still not clear on the best way to set a global constant in FM. I've read numerous methods, but there's got to be a recommended way.

       

      Like many folks, I want to set a text constant that I can use in a relationship, i.e. to filter a set of records to only show those that have a field containing that constant value. Obviously everyone opening the database needs to see those same constant values.

       

      There are 3 methods (possibly more) that I can think of:

      1) Create a global text variable, and use an "on open" script to set that global variable to a constant value.

      2) Create a global calculation variable and set the calculation to the constant. NOTE: does a record have to be created in order for this to happen? Or does it happen simply by creating the global field?

      3) Create a global text variable and set it to a Calculated value equal to the constant.

       

      Which does FM recommend?

      Thanks.

        • 1. Re: What's the correct way to set constants?
          jbante

          FileMaker, Inc., is unlikely to recommend any one method as the preferred method for setting constants. How you will use the constant (and how the value of the constant might change in the future) should guide which method you go with. One method you didn't list that's worth noting is to define a custom function with no parameters that simply returns the value of the constant. This eliminates any issues with forgetting to set the constant or the startup script being bypassed or the value being inaccessible due to missing records or wrong context.

          • 2. Re: What's the correct way to set constants?
            beverly

            Excellent suggestion, j! Now if they'd give us a way to have a "repository" of Custom Functions, so we don't have to remember to add them to each file we touch...

            Beverly

            • 3. Re: What's the correct way to set constants?
              benlevi

              Let me clarify my question:

              What are the pros and cons of each of the options for setting global constants? Which ones work in which circumstances? If we're looking to set a constant across all files for all users, what's the recommended method? Is there a white paper by Filemaker on this? The Help files are useless... so I'm sure the FM community would appreciate understanding how global constants work.

              Thank you.

              • 4. Re: What's the correct way to set constants?
                jbante

                There's no whitepaper on constants that I know of.

                 

                Personally, I like the custom function method. There's no complication added to the startup script (and hence a way for it to break by bypassing the startup script), and users don't have to re-login for it to take effect if you change it. The downside is that the scope of a custom function is only the file it lives in. You'd have to copy the custom function to another file if you want to the other file to have the same constant, which can be a liability if you have to remember all the files it has to be changed in later. Still, it's a self-contained solution, unlike the alternatives.

                 

                Setting a global variable at startup is a decent solution if you need a user (typically a manager) to be able to change the value in a settings table. If you wanted to keep the instant updating advantage of the custom function, maybe you could pair the settings table with a custom function using FileMaker 12's new ExecuteSQL function, which would also make it possible to distribute one change across files. I haven't tried this, so I can't speak for how well it works. Thanks for triggering the idea though!

                 

                Another thought I had would be to use a value list to share constant values between files. Each file that needs to reference a constant would reference the value list in whatever you're referencing as the "master" file for global settings. Then each file could retrieve constant values with the ValueListItems function. You could even wrap that in a custom function! You could either use a separate one-value value list for each constant, or just have one "Constants" value list and you can parse each value out as you need it — just don't change the order of the values! Again, I haven't tried this personally.

                 

                I suppose some factors to take into account when deciding how to handle constants include:

                • How likely is the constant to ever change? Pi isn't changing ever, but an application version number can change daily, or even faster.
                • If you do change a constant, how quickly do users already logged-in when you change the constant need to see the change (i.e., can it wait until their next session)?
                • How many files need to share the constant?
                • Do you already have a settings table?
                • Do end users need to be able to edit the constant?

                 

                It's starting to sound like I don't care very much for setting global variables or fields at start-up, which I didn't think was the case before now; but maybe that's right. After all, they update more slowly than the alternatives, and there's an easy way for them to not get set at all. If you try the ExecuteSQL ( "SELECT ... FROM AppSettings" ) or value list ideas, I'd be interested to hear how they work out for you.

                • 5. Re: What's the correct way to set constants?
                  jbante

                  Perhaps you should start a proposal at FileMakerStandards.org to get a discussion going that is likely to result in a publicly recorded best practice?

                  • 6. Re: What's the correct way to set constants?
                    steve_ssh

                    Hello Jeremy,

                     

                    I think your idea of using a value list is very clever.  Thanks for sharing that inspiration.

                     

                    Best,

                     

                    -steve

                     

                     

                    jbante wrote:

                     

                    Another thought I had would be to use a value list to share constant values between files. Each file that needs to reference a constant would reference the value list in whatever you're referencing as the "master" file for global settings. Then each file could retrieve constant values with the ValueListItems function. You could even wrap that in a custom function! You could either use a separate one-value value list for each constant, or just have one "Constants" value list and you can parse each value out as you need it — just don't change the order of the values! Again, I haven't tried this personally.

                     

                    • 7. Re: What's the correct way to set constants?
                      beverly

                      Yes! a clever way, indeed. Jeremy must live outside (the box).

                       

                      Beverly

                      • 8. Re: What's the correct way to set constants?
                        Stephen Huston

                        You mentioned wanting to use this constant with a relationship, so part of the deciding factor is

                        1. do you want this constant used in the relationship as one of the keys for defining the related records, or
                        2. do you just need this for filtering a portal.

                        If you only need it for filtering a portal, a $$globalvariable will be enough. If you need to use it in the relationship definition itself, then you will need a field, which can be set to global-storage if it is on the parent-side of the join (from which you are viewing the related records).

                         

                        The rest of the discussion as to ways to set the value still leaves many options, as others have described above.

                         

                        One more that I have used for globals that need updating in a served environment is to use a single-record table for "globals" but some of the fields in that table are set as stored/indexed fields. Those can be updated by a client so they will persist between sessions, and then a calc field which references that field can be set to global so it is available throughout the solution files. It  pulls the last updated value from the stored field as the global  value for each new session.

                        • 9. Re: What's the correct way to set constants?
                          benlevi

                          Stephen,

                          Thanks... you're helping to steer the conversation onto the track I'm having a problem with. I want to reference the constant in a relationship by setting a global variable (but will probably go with the function solution, which seems to actually work).

                           

                          What about the two solutions:

                           

                          1) Set a global variable as a Type=calculation of the constant;

                           

                          2) Set a global variable as a Type=Text, and set the Option: Auto-Enter: Calculation = constant

                           

                          It seems like either of these two solutions "should" work... my question is, why do either of them not work?

                           

                          Thank you all... this is definitely a useful conversation for the community.

                          Ben

                          • 10. Re: What's the correct way to set constants?
                            DavidJondreau

                            Two of your options, the ones using global variables can't actually be directly used in a relationship.

                             

                            A couple other options are to use a stored or an unstored calculation field.

                             

                            If you need the relationship to work both ways, a stored calc field will work. One downside is that the field takes up a little bit of space for each record which may have nominal performance issues tables with a large number of tables.

                             

                            If you want a value that may change (but only need the relationship to be valid in one direction), an unstored calc may be what you want. Unstored calcs take up a negligible amount of space. They can also be used to reference $$variables which is nice. Instead of using $$var to filter a set of child records at the portal level (which, if there are a lot of child records can be pretty slow, though is the only way if the child fields are unstored) you can do it at the relationship level which is faster.

                            • 11. Re: What's the correct way to set constants?
                              mdiehr

                              There's a subtle bug (in my opinion) regarding relationships using globals : a global used in a relationship key only fully works if its table has 1 or more records.   The WTF here is that if the table has zero records, then the relationship still works fine for READING data, but no longer works for CREATING a record.   This one burned me quite badly for a while...

                              See discussion here:  https://fmdev.filemaker.com/message/69629#69629