# Global search across field definitions?

**URL:** <https://the.fmsoup.org/t/global-search-across-field-definitions/3882>\
**Category:** MBS Plugins\
**Tags:** feature-request\
**Created:** [January 2, 2024, 7:05pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882 "2024-01-02T19:05:32Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![xochi](https://avatars.discourse-cdn.com/v4/letter/x/0ea827/32.png) [@xochi](https://the.fmsoup.org/u/xochi)\
**Post date:** [January 2, 2024, 7:05pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/1 "2024-01-02T19:05:32Z")

</div>

I was bitten by this issue again today: [Scope of $variable in Let statement in Calculated Field](https://the.fmsoup.org/t/scope-of-variable-in-let-statement-in-calculated-field/3155) and I want to make sure I don't have any more `$variables` in my field calculations.

Is there a way using MBS Plugin where I can do a **global** search for a string?

I'd like to search across:

- field definitions (calculated fields, auto-enter fields, field validation)
- custom functions

---

<div class="post-metadata">

**Author:** ![Malcolm](https://yyz2.discourse-cdn.com/flex030/user_avatar/the.fmsoup.org/malcolm/32/196_2.png) [@Malcolm](https://the.fmsoup.org/u/Malcolm)\
**Post date:** [January 2, 2024, 7:27pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/2 "2024-01-02T19:27:48Z")

</div>

Not an MBS solution, however, an effective method is to output a Copy as XML and to use a good text editor to search.

---

<div class="post-metadata">

**Author:** ![MonkeybreadSoftware](https://yyz2.discourse-cdn.com/flex030/user_avatar/the.fmsoup.org/monkeybreadsoftware/32/361_2.png) [@MonkeybreadSoftware](https://the.fmsoup.org/u/MonkeybreadSoftware)\
**Post date:** [January 2, 2024, 7:35pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/3 "2024-01-02T19:35:43Z")

</div>

You could try our sample database to search scripts with a hotkey:

## [Search scripts in FileMaker for Windows](https://www.mbsplugins.de/archive/2023-12-20/Search_scripts_in_FileMaker_fo)

That one would find stuff in a Let statement and tell you the line number.

---

<div class="post-metadata">

**Author:** ![xochi](https://avatars.discourse-cdn.com/v4/letter/x/0ea827/32.png) [@xochi](https://the.fmsoup.org/u/xochi)\
**Post date:** [January 2, 2024, 9:47pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/4 "2024-01-02T21:47:21Z")

</div>

@Malcolm - thanks for the idea.

@MonkeybreadSoftware - is that a Windows-only solution or would it work on macOS?

---

<div class="post-metadata">

**Author:** ![MonkeybreadSoftware](https://yyz2.discourse-cdn.com/flex030/user_avatar/the.fmsoup.org/monkeybreadsoftware/32/361_2.png) [@MonkeybreadSoftware](https://the.fmsoup.org/u/MonkeybreadSoftware)\
**Post date:** [January 2, 2024, 10:32pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/5 "2024-01-02T22:32:20Z")

</div>

MacOS and Windows

---

<div class="post-metadata">

**Author:** ![OliverBarrett](https://avatars.discourse-cdn.com/v4/letter/o/f19dbf/32.png) [@OliverBarrett](https://the.fmsoup.org/u/OliverBarrett)\
**Post date:** [January 3, 2024, 11:38am UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/6 "2024-01-03T11:38:37Z")

</div>

I would love to see something as user-friendly and as useful as 2EMPower (but of course without the $395 (over)priced amount.

It never ceases to amaze me that a "development" product could be around for **decades** without a simple search/replace across scripts and CFs. Totally weird, IMHO.

Thanks!

---

<div class="post-metadata">

**Author:** ![xochi](https://avatars.discourse-cdn.com/v4/letter/x/0ea827/32.png) [@xochi](https://the.fmsoup.org/u/xochi)\
**Post date:** [January 3, 2024, 7:23pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/8 "2024-01-03T19:23:08Z")

</div>

I figured out a quick & dirty way to do this using **Save as XML...** and the **xpath** commands in macOS:

1. FileMaker / Tools / Save a Copy as XML.
2. Open a Terminal window
3. Run this command (replacing `/path/to/my/database.xml` with the path to the XML file you just saved.

```auto
xpath -q -e "//Field[descendant::Calculation]" -e "@name | .//Calculation//Text/text()" /path/to/my/database.xml

```

This will output something like this:

```auto
 name="EmployeeFirstName"
 Trim ( Self )
 name="EmployeeLastName"
 Trim ( Self )
 name="SocialSecurityNumber"
// validate this SSN
Let(
[
   n = Filter(Self;"0123456789"); // get only the digits
  ...

```

Notes on how the XPATH command works:

- `-q` means 'quiet' (suppresses non essential information)
- `-e` means "use this xpath expression"
- multiple `-e` commands are chained together in order by passing the resulting nodeSet from each command to the next one
- `//Field[descendant::Calculation]`means "select any **Field** node that has a **Calculation** node as a descendant (one or more levels below)
- `//` in a path is like a wildcard, so will select the node at any level, even if it has parents (it doesn't have to be the root node)
- `@name` means print the 'name' attribute of the node (e.g. which is the name of your FileMaker Field name)
- `|` is the bar or chain operator which allows you to select two disparate nodes at once
- `.//Calculation//Text/text()` means 'if there is a **Calculation** node at any (at any level) which has a child **Text** node as a descendant, select it. The `/text()` means "print only the text value of the node"

So, at a high level, the xpath command does this:

- Select any **Field** nodes that have a **Calculation** node within them
- send this nodeset to a second level of processing.
- In the second level of processing, print the name of the Field node (which is our Field name) and also print the contents of the **Calculation**'s **Text** node (which contains the calculation formula)

I believe this will find most Calculations, including calculations used inside a field validation, auto-enter calculations, as well as normal calculated fields.

Edit to add:

To get the text of formulas for **Custom Functions** , use this script:

```auto
 xpath -q -e "//CustomFunctionCalc[descendant::Calculation]" -e "./CustomFunctionReference/@name | .//Calculation//Text/text()" /path/to/my/database.xml

```

---

<div class="post-metadata">

**Author:** ![steve\_ssh](https://yyz2.discourse-cdn.com/flex030/user_avatar/the.fmsoup.org/steve_ssh/32/160_2.png) [@steve\_ssh](https://the.fmsoup.org/u/steve_ssh)\
**Post date:** [January 3, 2024, 7:52pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/9 "2024-01-03T19:52:36Z")

</div>

Nice work @xochi . Thank you for providing the detailed breakdown of the use of the xpath command. That is very helpful, and I appreciate you taking the time to break it down.

---

<div class="post-metadata">

**Author:** ![Malcolm](https://yyz2.discourse-cdn.com/flex030/user_avatar/the.fmsoup.org/malcolm/32/196_2.png) [@Malcolm](https://the.fmsoup.org/u/Malcolm)\
**Post date:** [January 3, 2024, 8:15pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/10 "2024-01-03T20:15:55Z")

</div>

Nice. I keep a notebook of xpath snippets for re-use.

But getting exactly the right xpath/xquery can require a little bit of trial and error. For open ended browsing I use [https://basex.org](https://basex.org). It provides a variety of nice visualisation methods that can make it much easier to understand and work with the results.

---

<div class="post-metadata">

**Author:** ![xochi](https://avatars.discourse-cdn.com/v4/letter/x/0ea827/32.png) [@xochi](https://the.fmsoup.org/u/xochi)\
**Post date:** [January 3, 2024, 10:22pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/11 "2024-01-03T22:22:07Z")

</div>

I managed to get it figures out - I used BBEdit - when dealing with XML it gives you disclosure triangles so you can collapse sections, which makes it more manageable, but the baseX app looks quite nice.

---

<div class="post-metadata">

**Author:** ![Malcolm](https://yyz2.discourse-cdn.com/flex030/user_avatar/the.fmsoup.org/malcolm/32/196_2.png) [@Malcolm](https://the.fmsoup.org/u/Malcolm)\
**Post date:** [January 4, 2024, 8:22pm UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/12 "2024-01-04T20:22:57Z")

</div>

BaseX is worth getting to know. It has some good features.

For example, If your xquery is based on an attribute of an object the paths may be deep.

```svgbob

    *--------* *-------* *---------* *----------*
    | object |-->| child |-->| element |-->| attribute|
    *--------* *-------* *---------* *----------*

```

On the layout you are really interested in the top level object but your search is for attributes. With BaseX you can simply step back to higher levels to display the ancestor object. It provides lots of different visual representations of the data, as well as plain text (similar to what you'd see on the command line).

---

<div class="post-metadata">

**Author:** ![flybynight](https://yyz2.discourse-cdn.com/flex030/user_avatar/the.fmsoup.org/flybynight/32/1023_2.png) [@flybynight](https://the.fmsoup.org/u/flybynight)\
**Post date:** [January 8, 2024, 3:21am UTC](https://the.fmsoup.org/t/global-search-across-field-definitions/3882/13 "2024-01-08T03:21:25Z")

</div>

FMPerception lets you search for variables across all areas of your code (DDR). Highly recommend!
