├── .gitignore ├── Main.fp7 ├── Main.fmp12 ├── Archive.fmp12 ├── Candidates.fmp12 └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.swp 3 | -------------------------------------------------------------------------------- /Main.fp7: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chivalry/filemaker-custom-functions/HEAD/Main.fp7 -------------------------------------------------------------------------------- /Main.fmp12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chivalry/filemaker-custom-functions/HEAD/Main.fmp12 -------------------------------------------------------------------------------- /Archive.fmp12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chivalry/filemaker-custom-functions/HEAD/Archive.fmp12 -------------------------------------------------------------------------------- /Candidates.fmp12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chivalry/filemaker-custom-functions/HEAD/Candidates.fmp12 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FileMaker Custom Functions 2 | 3 | These are the standard custom functions that I generally import into all of my FileMaker 4 | projects. They represent a library of custom functions, some commonly used, others more 5 | esoteric, but each one has actually been used or seems to have a high liklihood of 6 | utility in some future project. 7 | 8 | While I wrote many of these myself, there are quite a few that are from other sources. 9 | I've tried to acknowledge the original author when I could as well as provide a URL to 10 | the web page where the function was originally found. If you find a function that you 11 | wrote without an attribution to you, please open an issue so I can fix that, or, if the 12 | text format is available for it, fork the repository, make your change and submit a pull 13 | request. 14 | 15 | ## Acknowledgements 16 | 17 | Many of these functions are from sources other than myself. I've tried to include 18 | attributions when I knew who originally wrote them, but this information is sometimes 19 | missing. If you know who wrote a particular function for which an attribution is missing 20 | (see the issues for some authors that I'm looking for), please let me know. Among the 21 | FileMaker developers that I can definitively thank for their contributions to the FileMaker 22 | community (in no particular order): 23 | 24 | - [Matt Petrowski](http://www.filemakermagazine.com) 25 | - [Jeremy Bante](https://twitter.com/jbante) 26 | - [Winfried Huslik](https://twitter.com/whuslik) 27 | - Matt Wills 28 | - [Kevin Frank](http://www.kevinfrank.com/index.html) 29 | - [Tom Robinson](http://www.tomrobinson.co.nz) 30 | - [Jesse Antunes](http://sixfriedrice.com/wp/about-sfr/) 31 | - [Agnès Barouh](mailto:barouh.agnes@wanadoo.fr) 32 | - [Arnold Kegebein](http://www.kegebein.net/blog/about/) 33 | - [Geoff Coffey](http://sixfriedrice.com/wp/about-sfr/) 34 | - [Andrew Persons](http://www.excelisys.com/our-team-custom-database-consultants.php) 35 | - [Theo Gantos](https://twitter.com/tgantos) 36 | - [Mikhail Edoshin](http://mikhailedoshin.com) 37 | - [The Shadow](http://www.fmfunctions.com/members_display_record.php?memberId=34) 38 | - Vaughan Bromfield 39 | - [Bob Weaver](http://fmforums.com/profile/53726-bobweaver/) 40 | - [LaRetta](http://fmforums.com/profile/59345-laretta/) 41 | - [Fabrice Nordman](https://twitter.com/FabriceN) 42 | - [Joe Scarpetta](http://scarpettagroup.com/filemaker-development-about/) 43 | - [James Scarpetta](http://scarpettagroup.com/filemaker-development-about/) 44 | - [Will M. Baker](https://www.beezwax.net/beez/100) 45 | - Brad Lowry 46 | - Alexander Zueiv 47 | - Jesse Swensen 48 | - [Debi Fuchs](http://www.aptworks.com/welcome.html) 49 | - [Mislav Kos](http://www.soliantconsulting.com/users/mkos) 50 | - [Nicholas Orr](http://www.goya.com.au/about/staff) 51 | - [John Jones](john.christopher@alumni.virginia.edu) 52 | - [Andy Knasinski](http://www.nrgsoft.com/about/leadership.html) 53 | 54 | For those of you above which I haven't yet linked to, or if there's a different URL you'd like a link to, send me a URL that you would like attached to your name. 55 | 56 | ## Formats 57 | 58 | All of the custom functions can be found in three places: 59 | 60 | 1. Within a FileMaker 14 file, `Main.fmp12`. This is the golden master and the only place a standard function is guaranteed to be. 61 | 2. Within a FileMaker 11 file, `Main.fp7`. Incompatible custom functions that take advantage of FileMaker 12+ features, such as `ExecuteSQL`, will not be included here. Functions here may not yet have been updated to the latest version, but exist to ease importing into FileMaker systems based on versions 11-. Eventually it may cease to receive any updates. 62 | 3. Within a text file in a parent folder named for the functions group, such as `Main/Lists/lsts.First.fmcalc`. The `fmcalc` extension will allow the proper syntax highlighting within vim if the [filemaker.vim](https://github.com/chivalry/filemaker.vim) plugin is installed. These files are included for two reasons: to show line by line differences as functions are updated and provide the ability to retrieve the code for a single function. Note that if you copy and paste the code from a text file, you'll want to make sure you also manualy create any custom functions it depends upon. 63 | 64 | There's one more file included for historical reference only, `Archive.fmp12`, 65 | which contains the custom functions I had in their original format before I began editing 66 | them to conform to standards and eliminating them if they weren't actually used or likely 67 | to be used. It also contains functions that were created for specific applications, 68 | unlikely to be generally useful as they are, but worthy of retention for some other reason, 69 | perhaps as a reference to the algorithm used. If a function is collected but not used in 70 | main because it's not yet a standard function, it may be stored here. 71 | 72 | ## Standards 73 | 74 | These custom functions strive to conform to the following standards. Not all do yet, but 75 | I hope to correct the shortcomings in the near future. 76 | 77 | ### Dividers 78 | 79 | These custom functions are divided into groups. Since FileMaker doesn't (yet) offer 80 | folders within the custom function dialog box, the grouping occurs with two kludges. 81 | First, there is one custom function for each group that acts solely as a heading. Second, 82 | each group is signified with a four-letter prefix unique to the group. 83 | 84 | Headers begin with the four-letter prefix, followed by five underscores, the group name, 85 | appended with underscores to provide a sufficient dividing line when the Function Name 86 | column of the custom function dialog is widened to a fair width. This leads to custom 87 | function headers named like the following: 88 | 89 | appl_____ Application Functions ___________________________________ 90 | devp_____ Developer _______________________________________________ 91 | lsts_____ Lists ___________________________________________________ 92 | 93 | Divider functions also contain comments on the purpose of the group. 94 | 95 | ### Normal Functions 96 | 97 | Normal custom functions start with the four-letter prefix, followed by a dot, and then a 98 | descriptive name in `CamelCase`, which is how FileMaker's built-in functions are named. 99 | Some examples follow. 100 | 101 | date.BusinessDays 102 | devp.IsDeveloper 103 | dict.Add 104 | lsts.RemoveDuplicates 105 | 106 | ### Wrapped Recursive Functions 107 | 108 | If a function's sole purpose is to act as a recursive tool for a wrapper function, in 109 | which case it is only ever called by the wrapper function, then the recursive tool is 110 | named identically to the wrapper function but with an appended underscore. 111 | 112 | lsts.Concat 113 | lsts.Concat_ 114 | prtf.PortalFilterCreator 115 | prtf.PortalFilterCreator_ 116 | 117 | ### Parameters 118 | 119 | Parameters are named in `snake_case`, but with a leading underscore, as in `_list` and 120 | `_folder_path`. 121 | 122 | ### Preamble 123 | 124 | Each custom function starts with a preamble that looks like the following: 125 | 126 | // Temmplate 127 | // 128 | // Purpose: description 129 | // 130 | // Parameters: _param: description 131 | // 132 | // Requirements: requirements 133 | // 134 | // Author: Charles Ross 135 | // Version: 1.0 written 15-03-07 136 | // 137 | // Notes: Notes 138 | // 139 | // Example: 140 | // sample = result 141 | 142 | The template is what would normally show between FileMaker's parameter list and the custom 143 | function code. For example, if there was a function actually called Template and it 144 | actually took two parameters as above, the template line would have `Template ( _param_1 )`. 145 | If there're no parameters for the function, the template should not have parentheses. 146 | 147 | The example portion should be a sort of unit test for the function, something that, once 148 | the custom function has been defined, would allow a developer to copy and paste into the 149 | data viewer, remove the commenting and have it return `True`. An example, using one of 150 | FileMaker's built-in functions, might be `Middle ( "abc"; 2; 1 ) = "a"`. If multiple 151 | examples are included, use a single calculation that uses a boolean `and` to create the 152 | truth statement. If the test is trivial because a constant is being returned, this can 153 | be omitted. 154 | 155 | Such unit tests aren't always possible, expecially when the funciton's primary purposes 156 | resides not in its return value but in its side effects. If possible, use comments in the 157 | example to explain what the initial conditions should be and use the example to not only 158 | express the return value of the function but also what side effects should also be true 159 | after calling it. 160 | 161 | If the function depends on any other custom functions, these dependencies should be 162 | documented in the requirements section. 163 | 164 | ### Script Variables 165 | 166 | If script variables are used within a custom function to track information between recursive 167 | calls, the script variable names should include the custom function to reduce the chance 168 | that custom function script variables will conflict with those found in actual executing 169 | scripts. For example, if a function is named `MyCustomFunction` and it references a script 170 | variable that under normal circumstances might be named `$_len`, with the custom funciton 171 | a name of `$_MyCustomFunction_len`, or perhaps `$_mcf_len`, should be used. While this can 172 | unfortunately result in very long script variable names within custom functions, using this 173 | namespacing technique is preferable to having a script reference the same variable and use 174 | the custom function in question, thereby overwriting the script's variable value. 175 | --------------------------------------------------------------------------------