Jump to content
Sign in to follow this  
David Jondreau

$ and $$ variables in custom functions

Recommended Posts

Will $ or $$ variables called by a calculation ever interfere with each other? I thinking about a custom function that uses a $ variable as a counter, but I'm wondering if that can backfire.

If a $ variable is defined by more than one calc at a time (in a Let() statement), how does that resolve?

Share this post


Link to post
Share on other sites

Hi DJ

I know the answer, but try yourself.

( remember to set the $var to empty before the last iteration )

Share this post


Link to post
Share on other sites

If I could come up with a simple test, I wouldn't have bothered to post.

I suppose my question isn't clear enough. There are no iterations to be reset.

If I use $counter in a CF instead of passing the counter as a parameter, what happens when multiple instances of that CF run at the same time? Say during a Replace() on a field in a parent table that acts as a trigger for a calc that calls that CF.

This would be used in solution that summarizes dozens to hundreds of children records and such a Replace() on a set of, say, 10 records, may take up to 30 secs.

Share this post


Link to post
Share on other sites

It's still not too clear... I don't think there can be more than one evaluation taking place at the same time. And AFAIK, there can be only one register named $counter in the memory (per script), so in a Replace Field Contents[] step every record should pick up the value from the previously evaluated record.

Share this post


Link to post
Share on other sites

What if no scripts are involved? Say you have multiple calc fields that are updated by the same trigger field. Those calc fields use a the same custom function (with different parameters) and that CF uses a $ variable.

The testing I'm doing seems to indicate that the you can NOT use a variable as a counter in a CF.

Which I think is my real question.

Share this post


Link to post
Share on other sites

From FMP Help:

From Variables:

"Using the Set Variable script step or the Let function, you can create local and global variables. The scope of local and global variables is limited to the current file.

A local variable can only be used in script steps in the currently executing script. The value in a local variable is cleared when the script exits. Local variables are prefixed with $.

A global variable can be used in a calculation or script anywhere in a file, for example, other scripts or file path. The value of a global variable is not cleared until the file is closed. Prefix global variables with $$.

Local and global variables (or even two local variables in different scripts) can have the same name but they are treated as different variables and can store different values."

From the Let function help:

"Once defined, local and global variables can be referenced in any calculation within their scope. The scope of global variables is limited to the current file. The scope of local variables is the current script. Local variables defined in a calculation are scoped to the file but are only available when scripts are not running. A local and global variable (or even two local variables in different scripts) can have the same name but they are treated as different variables and store different values."

Share this post


Link to post
Share on other sites

While no script is running, a "no-script" memory is being used - and within it too, only one register named $counter can exist.

You still haven't told us what the CF does, and I am quite puzzled regarding what you mean by using a variable as a counter.

Share this post


Link to post
Share on other sites

What if no scripts are involved? Say you have multiple calc fields that are updated by the same trigger field. Those calc fields use a the same custom function (with different parameters) and that CF uses a $ variable.

The testing I'm doing seems to indicate that the you can NOT use a variable as a counter in a CF.

Which I think is my real question.

The calc-fields are triggering in a particular order (which is based on their inter-dependencies), when I was at FileMaker, they were never run in parallel, and I doubt they would go to the effort, due to the potentially complex dependencies between them.

So, if I understand you correctly, I would think it safe.

Counters.fp7.zip

Edited by Guest
Added example file.

Share this post


Link to post
Share on other sites

( remember to set the $var to empty before the last iteration )

You need to reset the counter somewhere, otherwise it will just keep climbing

Dj, try as I said.

This is a simple example of resetting $var:

Invert ( text )

Let([

$counter = $counter + 1 ;

stop = Left ( text ; 1 )

];

Case(

$counter < Length ( text ) ; Middle ( text ; Length ( text ) + 1 - $counter ; 1 ) & Invert ( text );

Let ( [color:red]$counter = "" ; stop )

)

)

Share this post


Link to post
Share on other sites

First, thanks everyone for taking time to help me through this (esp Daniele who tried to put me on the right path from the start). I understand how to make a $ var work now as a counter by resetting it either with another function or within the function itself, which was my immediate goal.

But I still don't understand how $ vars behave within calculation fields. (They are local to a script, obviously, their most common use).

Generally, it seems that if a $var is defined within a calc, that $var is local to that calc, except for other expressions of the $var (which don't define it).

Some issues are:

-When the $var trigger is null, most (but not all) of the $vars don't evaluate. That's definitely not expected.

-An expression that doesn't define a $var, but expresses it (counter / triggered counter) apparently takes on a value from one of the other definitions (the last one defined that is on the layout??).

-For those non-defining calcs, unstored and stored expressions behave differently.

I don't know if this is making sense to anyone else...it doesn't really to me at the moment.

Here's another file, with a variety of calc fields each setting the same $var, with different results.

mysandbox2.fp7.zip

Share this post


Link to post
Share on other sites

it seems that if a $var is defined within a calc, that $var is local to that calc

No, not at all. Once you declare a $variable, it is there and can be accessed by other calculations. The limit of the scope is the script that "owns" the $variable - that would be the the script that was running when the $variable was declared. If a $variable is declared when no script is running, it will be available as long as no script is running.

When the $var trigger is null, most (but not all) of the $vars don't evaluate

When a $variable is set to empty, it ceases to exist.

Share this post


Link to post
Share on other sites

$vars are local to the current script, but variables in calcs named without a "$" are local to the calc, such as, Let ( theDate=Get (CurrentDate) ).

Share this post


Link to post
Share on other sites

But we are speaking about variables in calcs that are named WITH a "$".

BTW, variables WITHOUT a "$" are valid ONLY within the Let() function that created them, not beyond that.

Share this post


Link to post
Share on other sites

I am aware that you were specifically discussing $var and $$var, but it seemed odd that no one mentioned named variables using Let( ). I thought, perhaps, they should be mentioned for others reading the thread. They're not as glamorous, but they're very useful!

Share this post


Link to post
Share on other sites

First, thanks everyone for taking time to help me through this (esp Daniele who tried to put me on the right path from the start). I understand how to make a $ var work now as a counter by resetting it either with another function or within the function itself, which was my immediate goal.

But I still don't understand how $ vars behave within calculation fields. (They are local to a script, obviously, their most common use).

You are presenting conflicting ideas. If you're talking about calculated fields, they are calcuated fields; they are by definition NOT dependent on a script. So far it isn't clear why you have any $ variables at all, they are not necessary to any of your calculations, the standard Let variable will do the job. Further confusing the issue, you talk about using $ variables within a custom function but there are no custom functions in your example file. So it isn't at all clear what you're trying to do here.

Edited by Guest

Share this post


Link to post
Share on other sites

I've been reading this thread with great interest. I am tickled that DJ asks the questions he asks. Bruce, what you say is true but, just because DJ asks these questions and we (and maybe even he) doesn't see where the answers will lead, doesn't mean the questions should not be asked.

If you're talking about calculated fields, they are calcuated fields; they are by definition NOT dependent on a script. So far it isn't clear why you have any $ variables at all, they are not necessary to any of your calculations...

I'm not so sure about that. I've seen work where $variables are used within calculations which rely on script and I've seen quite interesting results. Just because something hasn't been done (and I'm not sure it hasn't) doesn't mean it shouldn't.

Okay, I'll take my usual screwy mind and move on; I'm just most pleased you all are providing your input on this one. :wink2:

Share this post


Link to post
Share on other sites

LaRetta: I'm glad you appreciate the question...I always enjoy your forays in the the underbelly of FMP.

Bruce: I've posted two sample files. The first has CFs, the second does not. Please see my second file for my current crop of questions. No, the fields in the second file do not have any functionality for the file itself. I'm not trying to solve a real world problem, I'm trying to figure out how Filemaker works.

comment:

of course, you're right, $vars are global to the file if set by calculation. I think I'm getting confused by how (as Shadow says) multiple calcs will trigger "based on their inter-dependencies".

comment:

in the second demo file, I am not setting the $var to null. I'm setting a field to null, which triggers auto-entered calcs that have a result of a $var.

So, the issues, from the second demo file are:

-When the number field upon which the auto-enter calcs are set to trigger (with a $var result) is set null, most (but not all) of the $vars don't evaluate correctly. What the heck is going on there?

-What are the "interdependencies" at work when expressing a $var in a calc field that isn't defined in that calc (field dependencies? stored/unstored/auto-enter calcs? creation order? $var placement order?). Is that why I'm getting different results for different fields in the demo file?

Thanks all

DJ

Share this post


Link to post
Share on other sites

you're right, $vars are global to the file if set by calculation

Had I said that, I wouldn't be right. They are NOT global to the file - they are available only within their "parent script boundary" (for lack of a better definition).

I am having a difficulty following your file. I think it's important to separate the issues. The order in which calculation fields evaluate is difficult to control since version 8 (IIRC). This has nothing to do with $variables, although it may have a critical impact when the same $variable is being set by multiple fields.

Share this post


Link to post
Share on other sites

comment,

As both of us have said in this thread, this thread is $vars when no script is involved. I didn't think I would have to provide context in every post, that the thread was context enough, but do the parens below help?

How is the statement "$vars are global to the file (when no script is running) if set by calculation (when no script is running)"

different than

If a $variable is declared when no script is running, it will be available as long as no script is running.

___________

It seems like my second question (in what order do calc fields evaluate) may be unanswerable.

_____________

But I am very curious to the answer to my first.

In my demo file, why does setting the trigger field result to a Null value (a simple Number field) result in $vars of the the auto-enter calc and stored calc fields also being null?

I've put together ANOTHER sample file. I don't think I can make it any simpler without losing the point.

mysandbox3.fp7.zip

Edited by Guest
forgot the file

Share this post


Link to post
Share on other sites

I am sorry, I didn't mean to quibble - it's just that as Barbara pointed out, this is a public thread, so it's important to be precise. And you sort of attributed that statement to me. Everyone needs to find the model that helps them best to organize the stuff in their own mind. As it happens, your (new) formulation doesn't fit the way I think about this, but that's no reason why it couldn't work for you.

It seems like my second question (in what order do calc fields evaluate) may be unanswerable.

Oh, it's definitely answerable - after all, Filemaker doesn't pick the fields in random order. But I believe it deserves a thread of its own (probably quite a long one). This is something I began investigating at one time, but I have put it aside when I saw it what it would take to get the answer. Perhaps Shawn can offer some simple formulation of the rules.

I've put together ANOTHER sample file.

Where is it?

Share this post


Link to post
Share on other sites

why does setting the trigger field result to a Null value (a simple Number field) result in $vars of the the auto-enter calc and stored calc fields also being null?

Because the fields are set not to evaluate when all referenced fields are empty.

Share this post


Link to post
Share on other sites

Oh, it's definitely answerable - after all, Filemaker doesn't pick the fields in random order. But I believe it deserves a thread of its own (probably quite a long one). This is something I began investigating at one time, but I have put it aside when I saw it what it would take to get the answer. Perhaps Shawn can offer some simple formulation of the rules.

I helped work on the dependency-computation for a while (to make it faster). As far as I recall, its pretty simple, given a calculation X:

X = A + B + C

A, B, C must be available before X is computed, if they are calculations, that means they must be computed first. Let's say B is also a calculation:

B = C & "!"

So, now the dependencies are inverted into a 'trigger table', such that when C changes FM knows to recompute B first, then X.

Any oddness in the order of execution observed probably comes from the fact that internally, field-creation order is the easiest thing to use - so in any case where it doesn't matter who goes first, fields likely recompute in the order they were defined. So, you might make two files which appear to have the same calculations in them, but there order of execution differs slightly, since the fields weren't defined in the same order.

Share this post


Link to post
Share on other sites

I agree that's pretty weird.

It looks to me like its computing using the committed value of the other field (rather than the new value entered) to compute the other calculation.

Share this post


Link to post
Share on other sites

It can get even weirder than that: I can't find my old files at the moment, but I have a distinct memory of setting up a situation where modifying a field would cause some fields to be evaluated TWICE during the same cascade run.

Share this post


Link to post
Share on other sites

So, the issues, from the second demo file are:

-When the number field upon which the auto-enter calcs are set to trigger (with a $var result) is set null, most (but not all) of the $vars don't evaluate correctly. What the heck is going on there?

By definition, none of the calcs evaluate incorrectly.

You didn't write the calculation engine and you are exploring issues and dependencies that you don't understand.

What exactly are the "incorrect" values?

Share this post


Link to post
Share on other sites

Sorry for the delay, I just got back from vacation where I did not have internet access for a whole 8 days.

Because the fields are set not to evaluate when all referenced fields are empty.

*%$#! Something that simple! Thanks so much.

Now, I've got to look into how that setting interacts with the auto-enter field. Intuitively (to me) if it's not supposed to evaluate, it shouldn't replace.

Share this post


Link to post
Share on other sites

You didn't write the calculation engine and you are exploring issues and dependencies that you don't understand.

I'm not sure what your point is.

Of course I'm exploring issues I don't understand. Why else would I be posting questions about them?

I'm sorry you don't understand my questions, I don't think I can make the issues clearer for you.

Thankfully, others understand and have helped by answering two problems and posting a very interesting file.

Edited by Guest

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

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