Skip to content
View in the app

A better way to browse. Learn more.

FMForums.com

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Leaderboard

Popular Content

Showing content with the highest reputation since 06/01/2025 in Posts

  1. I don't think you are describing the problem accurately. A portal will not resort until you commit records. Not even if you exit the portal to go to a field of the parent record. If you see a shift in the record's position then a commit has occurred, either by the user or possibly by a script trigger. You could probably prevent premature committing by the user by validating the When? field as not empty. My preference would be to bypass the issue by scripting the process of creating (and possibly editing too) a child record in a card window.
  2. For the last year, this community has burned thousands of hours trying to bridge the gap between Modern AI (ChatGPT, Codex, Claude, Copilot) and the FileMaker Script Workspace. We all know the pain: you manage to get an LLM to output what looks like a working FileMaker script, but because FileMaker relies on a strict, complex XML clipboard structure, you either have to re-type it out line-by-line, or the XML paste simply fails silently. The wait is officially over. We just launched ai2fm — a native IDE bridge that completely solves the clipboard gap, allowing you to execute low-latency "Vibe Coding" directly between your AI agent and your FileMaker solution. It is a dedicated extension that intercepts the FileMaker fmxmlsnippet, translates it instantly into a deterministic, semantic text pseudo-code so your AI can easily read/rewrite your logic, and—most importantly—compiles it flawlessly back into FileMaker XML so you can paste it directly into your Script Workspace. What the infrastructure unlocks: ✅ 100% loss-less bidirectional translation of the FileMaker clipboard (XMSS, XMFN, XMFD, XMTB, etc.) ✅ Live syntax validation with a strict Linter right in the editor to prevent broken XML pastes. ✅ Native autocomplete and Auto-formatting for .fmscript documents. ✅ Seamless integration with any VS Code fork (Cursor, Windsurf, Antigragity, Kiro, Codium) on both macOS and Windows. No more forcing LLMs to guess at FileMaker XML schema. No more manual transcription. You can finally let the AI read your entire script, rewrite it, and paste it back safely. The extension is hardware-agnostic and relies on your own local editor, meaning your data never touches a middleman API. If you trained a Local LLM to your coding preferences and your knowledgebase you can use it directly in any of those editors for free, or use any of the AI agent providers. We've opened up unrestricted 21-day trial access so you can test it on your most complex scripts immediately. Download the extension and let the AI finally do the heavy lifting: https://ai2fm.com/
  3. ai2fm v2.37.3 Makes the FileMaker Round Trip Faster Community-Driven DX: Bidirectional Auto-Convert Previously, translating an emailed FileMaker XML snippet into .fmscript required two manual keyboard shortcuts. Now, you can do it in one. Simply press Cmd+Opt+Q (Mac) or Ctrl+Alt+Q (Windows), and the extension will instantly execute a true bidirectional translation in a split side-pane. If you have raw FileMaker XML, it converts it into clean, linted .fmscript. If you have .fmscript, it instantly compiles it back into exact FileMaker XML. One keystroke, perfectly bidirectional. Explicit Shape Control (Multi-Line Preservation) For the architects building complex script dependencies, you now have explicit control over how your code shapes are preserved. You can right-click any step to easily toggle between Single Line and Multi-Line formatting for ultimate readability. For complex scripts, readability matters. v2.37.3 gives you direct control over the shape of individual script steps. You can now right-click a long step and choose: FM Clipboard: Step -> Multi-Line hat expands the step into a readable multi-line form. If you want it compact again, right-click the multi-line step and choose: FM Clipboard: Step -> Single Line This is especially useful for long AI-related script steps and complex steps with many parameters. You can keep dense code compact, or open it up when you need to inspect it carefully. Engine Patches & Cleanups We also deployed several reverse XSLT engine patches this week to improve stability. One visible cleanup: array variables such as $varName[1] now render cleanly, without ugly bracket spacing. That matters especially for those of you creating tutorials, screenshots, and teaching material with ai2fm. https://ai2fm.com/announcements.html
  4. Today at 1PM Pacific we will be sharing a prerecorded interview with Claris CEO: Ryan McCann. He will share some clarity related to his recent blog, and add some more depth to Claris' path forward with AI. Richard will also share his thoughts on the interview and maybe answer a few relevant viewer questions. Register for the LiveStream: https://fmtraining.tv/register.php?eventid=3039324319712715655830695959477104853386275117213238481841 If you cannot make the livestream at 1PM Pacific, a link to the recorded interview is found here: https://youtu.be/M2UYtO3hDMM [email protected] www.FMTraining.TV www.FMStartingPoint.com www.rcconsulting.com
  5. If you cannot rely on users to enter a negative amount for expenses then let them enter a positive amount for both and use a calculation field along the lines of: If ( Type = "expense" ; -EnteredAmount ; EnteredAmount )
  6. See the attached demo. A few notes: The script here is triggered on object exit. The default height is hard-coded into the script. The default height was measured using GetLayoutObjectAttribute() when the field is empty and active. This is different from the height dimension shown in Layout mode. This simple implementation has a flaw: if you edit an overflowing field and shorten the text so that it no longer overflows, the script will still mark it as overflowing. That's because the field only expands as you type, not shrink as you delete. To get the correct result, you would need to re-enter and re-exit the field. MeasureOverflow.fmp12
  7. MY-MCP vs OttoFMS MCP — A Head-to-Head Comparison With OttoFMS recently launching their MCP server feature, I thought it was worth comparing it against MY-MCP. Both connect AI clients like Claude to FileMaker data — but they take fundamentally different approaches. The Key Philosophical Difference OttoFMS MCP is a script gateway. The intelligence lives in your FileMaker scripts. It exposes your existing scripts as MCP tools, configured through the Otto Console GUI — no code required on the MCP side. MY-MCP is a query engine. The intelligence lives in the server itself. Schema discovery, OData query building, field quoting, date normalization, multi-tenant switching, and LLM-optimized output all happen automatically — no FM scripting required to get started. ( 1 script that returns DDL) Where OttoFMS Wins Write operations out of the box (create, update, delete via FM scripts) No code needed — GUI configuration Server-side hosting — no local install per user Where MY-MCP Wins Zero-config querying — connect and immediately query any table Automatic schema discovery at runtime Multi-tenant — one server, multiple FM databases In-memory analytics without additional FM round trips Bottom Line: They're Complementary Use MY-MCP for reads, discovery, and analytics. Use OttoFMS for write operations via existing FM scripts. They solve different problems and pair well together.
  8. Nick Hunter is starting a multi-week FileMaker LiveStream event on supercharging imports with MBS. We kick off Day 1 today at 1PM Pacific! Register for the LiveStream: https://fmtraining.tv/register.php?eventid=1116817859356653838668455889686670314554342801106723282545 If you miss a day, not to worry. We'll be uploading each stream with a unique title so you can find the topics that matter the most to you. [email protected] www.FMTraining.TV www.FMStartingPoint.com www.rcconsulting.com
  9. 1 point
    I have upgraded the engine that runs the site please let me know if you discover errors
  10. 1 point
    You can change some view settings to your own preference. https://fmforums.com/settings/links/
  11. Databases work best with regular structures. That's not to say that an inconsistency such as this cannot be accommodated, but it won't be ideal. A lot depends on what do you actually intend to produce out of the data entered. I would probably opt for a "star" join table of Roles joining Staff (or StaffAssignments) to both Districts and Schools. And if a role can apply to multiple schools in a single district I would consider using a checkbox field to select the applicable schools - provided that it wouldn't conflict with some reporting ability you may want to provide. Please note that we are discussing an ERD, not the relationships graph. That will be a whole another issue.
  12. Just for fun, you could also do: While ( [ values = Substitute ( Yourfield ; ", " ; ¶ ) ; n = ValueCount ( values ) ; result = "" ] ; n ; [ result = GetValue ( values ; n ) & Choose ( Mod ( n ; 2 ) ; ¶ ; ", " ) & result ; n = n - 1 ] ; result ) But this one will have a trailing carriage return, unless you change the output line to something like: Left ( result ; Length ( result ) - 1 ) or: Substitute ( result & ¶ ; "¶¶" ; "" )
  13. To find only the exact value of of "Ice" you can make your script do: ... Enter Find Mode [ ] Set Field [ YourTable::YourField; "\"¶" & $searchValue & "¶\"" ] Perform Find [ ] where the $searchValue variable contains the text "Ice". But again, this is actually looking for "¶Ice¶" (the searchValue surrounded by returns) and will not find records where "Ice" is the first or the last value (without a trailing return). If your values are sorted by the SortValues() function, then you already have a trailing return and you only need to add a leading one. There is no need for double returns. Yes. The list field will function as a multikey, which means any single value will be matched: https://help.claris.com/en/pro-help/content/creating-relationships.html?Highlight=multikey Yes, if you want to have the global field in the same table (it can be in any table).
  14. Gee, I wonder why no one has thought of that in 4 years. Let alone explain exactly how to migrate the data to a normalized structure...
  15. I don't understand your question, especially this part: It seems you have a parent-child relationship, with DeliveryNotes being the child table. In such arrangement, there should be a foreign key field in the child table holding the parent record's unique ID value. There should be no fields in the parent table that refer to the parent's children. To display the parent's children on the parent layout you would use a portal. This is the standard practice for a parent-child relationship. If you have some sort of a special requirement that isn't covered by this then please explain in more detail. For example, if you wish to isolate a specific child record, you could click on it in the portal (thereby setting a global field or variable to its unique ID) and then use a 2nd relationship or a filtered one-row portal to display it. P.S. Please use the standard font when posting. P.P.S Please update your profile to reflect your version and OS so that we know what you can use.
  16. Yes. Every script has its own parameter that must be passed to it explicitly when the script is called. To pass its own parameter to a subscript, the calling script would need to do: Perform Script [ “abc”; Parameter: Get ( ScriptParameter ) ] Keep in mind that a subscript does not "know" it's a subscript. It runs independently and does not inherit anything from the calling script.
  17. This is a little too much to take in all at once. Consider simplifying the issue and/or breaking it up to individual points. Speaking in general, the script parameter remains constant throughout the life of the script, while a script variable can be defined and redefined at any point. If you want to export a file using a variable as the file's name, and the file's name is supposed to contain the count of exported records, then of course you will want to define that variable as close to the export as possible and not before any event that can modify the current found set. HTH.
  18. In MBS FileMaker Plugin 15.3 we have a Format button on macOS for the data viewer's detail view. If the data is XML or JSON, we can use the format and colorize functions: JSON.Format & JSON.Colorize, XML.Format & XML.Colorize. Let's say you have some variables in the data viewer with XML or JSON content. When you double click the text, you get a new window showing the detail. Here we find the Format button added by MBS Plugin. Press the button and it will format the content: If we get a parse error or the content is not XML/JSON, we beep. If you click OK, the formatted text is stored in the variable. If you press cancel, the unformatted text stays in the variable. Please try the feature and let us know what you think. Available for macOS in MBS FileMaker Plugin 15.3.
  19. Just to comment on this line of thinking: “I have a script that I would like to use in multiple "similar" situations”. Be aware that what seems economical can lead to highly conditional scripts that are difficult to maintain or change without risk. Separate scripts without much indirection or abstraction are more easy to maintain and troubleshoot. Consider the trade off you’re making.
  20. You cannot use a variable to specify the field in the Edit Find Request window. But a find request can also be constructed through setting fields - and then you can use the script parameter to select which field to use, similar to what we discussed only recently here: https://fmforums.com/topic/110860-script-problem-remove-container-file-from-a-record-trying-to-transition-to-json-to-pass-multiple-parameters/#findComment-494081
  21. As you can see from the release notes, folders for custom functions have been implemented: https://help.claris.com/en/pro-release-notes/content/index.html
  22. https://www.fmcomparison.com
  23. There are various tools that can compare DDRs such as: BaseElements https://baseelements.com/ CrossCheck http://www.fm-crosscheck.com FMDiff http://fmdiff.com/ FMperception https://www.fmperception.com/ InspectorPro https://www.beezwax.net/products/inspectorpro-8 I have no recommendation to make since I don't use any of them. You can also use general tools for comparing XML documents (either DDR or the output of Save a Copy as XML). The result may be more difficult to read but it could be all you need for a one-time task such as you describe. Oh, and for fields only you could simply compare the results of ExecuteSQL() querying the FileMaker_BaseTableFields table.
  24. I don't know if that's a good analogy to your situation. Anyway the answer here is yes, at least WRT interference. They would simply login as different users and their privilege set would deny them access to any records other than those tagged by their account name. Then it's up to the developer to prevent situations where a bunch of records labeled <<no access>> would crop up - such as replacing the Show All Records command with a bogus find (any find will automatically omit records for which the user has no access). And there may be other details to consider e.g. serial numbering of records. Maybe not: https://support.claris.com/s/article/New-FileMaker-data-migration-tool?language=en_US
  25. Actually, it's quite the opposite: you would have a List layout to show a bunch of records (typically non-editable). Then you use a popover or a card window to drill into a specific record for more details and/or editing. It's functionally similar to list-detail layout but you have more space to work with, since the detail temporarily conceals the list.
  26. Yes, that's exactly what I meant. You are not alone in that wish, it's been often suggested (usually as a type of a layout part). As a side note: while I often switch between form and table view in solutions for my own use, I would almost always create separate layouts in solutions designed for others. So there would be a button for "detailed view" on the list layout and a "back to list" button on the form layout. Also keep in mind the possibilities offered by list-detail layouts, popovers and card windows.
  27. When I read this, I was taken aback: I thought surely a button cannot override the layout setup and allow access to a view which the developer has disabled?? But you are right, it does do exactly that. I consider this a bug. I think you have no choice other than to customize the bar for its specific layout. It's not like we have the option to share objects across layouts anyway.
  28. That's not going to work. Exactly. A button activates only by tabbing into it. Again, your hunch is correct. You don't need to add the selected button's object name to the script parameter. In fact, the buttons do not need to have object names at all (at least not for this). You only need to add a recognizable value to the script parameter of each button. It could be as simple as 1, 2 and 3 or perhaps something more explicit - say "current", "found" and "all". Then extract this value from the script parameter and use it to branch your script.
  29. The simple method is to open a new window, isolate the current record and do the export. Then close the current window to return to the original found set. Alternatively you could switch to a layout that has the fields you want in the order you want them and do Save Records as Excel from there. But if that's all such layout would be used for, it's hardly worth the effort.
  30. From what I can see the problem is that you are passing the container field's value instead of its name. Try defining the script parameter along the lines of = JSONSetElement ( "" ; [ "container_field_name" ; GetFieldName ( document::document_file ) ; JSONString ] ; [ "container_file_name" ; document::document_filename ; JSONString ] ) You could also get by with: JSONSetElement ( "" ; [ "container_field_name" ; "document::document_file" ; JSONString ] ; [ "container_file_name" ; document::document_filename ; JSONString ] ) but this would break if you renamed the container field.
  31. Just a random thought: Whether a field is optimized for static or interactive content is a matter of formatting the specific instance of the field on a specific layout. You could have two separate layouts showing the same field optimized differently. Or two different instances of the same field on different panels of a tab/slide control. Or even just hiding one of them conditionally.
  32. Not really. Your formula for constructing the JSON is correct and if the referenced field contains the text "Active" you should be getting the result you expect. Is it possible that the two tests were performed from different records?
  33. It won't happen in the 1st file until you populate the Data__lxn field in the newly created child records. It will happen in the 2nd file, but only after you commit the record (that's a good thing: you don't want portal records to fly up and down while you're still working on them).
  34. For the next version of MBS FileMaker Plugin in 15.3 we add the Window.SetRoundCorners function to provide round corners. At the recent Vienna Calling conference a developer asked if we can get the edges of the card in FileMaker to be round. And yes, that is indeed possible. Once the card is shown, the MBS Plugin can find the card window and apply round corners to it. This even works on Windows: This seems to work fine in FileMaker Pro on macOS and Windows. It does of course not work for WebDirect or FileMaker Go. To add the round corners, you simply call our plugin function Window.SetRoundCorners just after showing the card. The plugin finds the front window and applies them. Here is an example: Show card with round rectangle: New Window [ Style: Card ; Name: "Card" ; Using layout: “Tabelle” ; Height: 400 ; Width: 600 ] Set Variable [ $r ; Value: MBS("Window.SetRoundCorners"; 0; 12) ] Please try with 15.3 plugin and let us know how well it works for you.
  35. This file shows how I would approach this using the aforementioned method of filtering a portal to display only unique values. A few notes: For simplicity, I have left out the Positions and Subjects tables and used meaningful values for PositionID and SubjectID in the Assignments join table instead. This has no impact on the calculation formulae that need to be used. To some extent, this is a cop-out: I believe I could have done without the cCombinedKey field in the Assignments table. But it would have taken some time and - perhaps more importantly - the formula used for portal filtering would be much more difficult to understand. A note about your setup: I don't understand why you need the Levels table. Does it hold any other information besides an ID and the level? It seems to me that a custom value list of these levels would be quite sufficient. The other thing that puzzles me is the checkbox of these levels shown in your screenshot. It looks like users actually select multiple levels for each unique combination of Position and Subject, and your script breaks these down to individual records. And now you are asking how to combine them back to the original form? Wouldn't it be easier just to store the data as entered by the user? Link to the file (expires in 24 hours): https://wormhole.app/3D9xaz#GF8aSO2FXKXPIp8mfOLBkQ
  36. Did you notice that MBS FileMaker Plugin 15.2 includes a new feature to add keyboard shortcuts for the result data types for a formula? If you visit the manage database dialog, you can use keyboard shortcuts to pick data types for a field: Text ⌘ T Number ⌘ N Date ⌘ D Time ⌘ T Timestamp ⌘ M Container ⌘ R Calculation ⌘ L Summary ⌘ S If you define the formula, you get a dialog like the one shown above. The MBS Plugin looks for the popup menu on the bottom left and adds the same shortcuts for the data types. If it finds the menu, it adds the shortcuts to the menu entries. This way you can press e.g. command-T to pick text. Just a little convenience, but our clients asked us for it. Enjoy!
This leaderboard is set to Los Angeles/GMT-07:00

Important Information

By using this site, you agree to our Terms of Use.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.