double returns

double returns

am 29.01.2008 10:56:16 von ursus.kirk

fmp9a xp

I have created a script that tracks the ID's from the 10 most recently
visited. I do this by setting the current ID on top of the list. Number 10
drops out. However the first calculation has double returns between values.
I have created a solution but am very curious why the first version has
these double returns. I fail the see my error.


MyUniqueID ; text, serial, auto/increment

Set Field gRecentlyVisisted ;
Let ( [
Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
$$ID = If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "¶") &
If(IsEmpty($$ID);"";"¶") & MyUniqueID; 11) ) ] ;
$$ID)

I added a substitute to counter the problem, but am still puzzled.

Let ( [
Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
$$ID = If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "¶") &
If(IsEmpty($$ID);"";"¶") & MyUniqueID; 11) ) ] ;
Substitute ( $$ID; "¶¶"; "¶"))

Keep well, Ursus

Re: double returns

am 29.01.2008 14:10:47 von d-42

On Jan 29, 1:56 am, "Ursus" wrote:
> fmp9a xp
>
> I have created a script that tracks the ID's from the 10 most recently
> visited. I do this by setting the current ID on top of the list. Number 10=

> drops out. However the first calculation has double returns between values=
..
> I have created a solution but am very curious why the first version has
> these double returns. I fail the see my error.
>
> MyUniqueID ; text, serial, auto/increment
>
> Set Field gRecentlyVisisted ;
> Let ( [
> Exists =3D ( PatternCount ( $$ID ; MyUniqueID ) ) ;
> $$ID =3D If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "=
=B6") &
> If(IsEmpty($$ID);"";"=B6") & MyUniqueID; 11) ) ] ;
> $$ID)
>
> I added a substitute to counter the problem, but am still puzzled.
>
> Let ( [
> Exists =3D ( PatternCount ( $$ID ; MyUniqueID ) ) ;
> $$ID =3D If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "=
=B6") &
> If(IsEmpty($$ID);"";"=B6") & MyUniqueID; 11) ) ] ;
> Substitute ( $$ID; "¶¶"; "=B6"))
>
> Keep well, Ursus

You left out a crucial detail: how is 'myuniqueID' formatted?

Does it have a leading CR or a trailing one, or both or neither?

Your use of pattern count almost dictates myUniqueID would have to be
both in order for it to cope with telling the difference between:
"1234" and "112345" and if so, then THAT is why your getting double
spaces.

Other than that there is an outright bug. You are appending to the
bottom, and keeping the top. Once you've got 11 items in the list (10
if you count the blank), you're going to append the next item to the
bottom, and then immediately crop it off again.

But even if you fixed that (which isn't trivial because you need to
keep a blank line at the top so your going to have to bolt even more
cruft on to support that), I'd say its an ugly design, with most of
the ugliness as a result of working around the limitations of
patterncount, and all the kludging you are doing to work around it.

What you -really- want is to use FilterValues, which tells if the
value you have is in the list without mucking about with carriage
returns. Use that instead of patterncount and you can rewrite your
function like this:

$$ID =3D If ( FilterValues( $$ID ; MyUniqueID ) <> "" ; $$ID ;
List(MyUniqueID,LeftValues ($$ID,9)))

Nice clean and simple.
It also sets the list right side up which I find easier to work with
conceptually. Plus it dodges all the nastiness with working with and
around the carriage returns and you don't even have to do anything
special if the list is empty. It just works.

Just make sure you aren't feeding it bad data in the form of uniqueIDs
that contain leading or trailing carriage returns... in which case:
garbage-in, garbage-out.

** So Make sure the uniqueid is 'clean' before using it **

One natural enhancement might be to reorder the list so that if the
item is in the list it gets shunted out to the top:

Let( MyUniqueIDP =3D MyUniqueID & "[P]";
$$ID =3D If ( FilterValues ( $$ID ; MyUniqueID ) <>"" ;
MyUniqueIDP & Subsitute($$ID; MyUniqueIDP;"");
MyUniqueIDP & LeftValues ($$ID,9))))

So, if the uniqueid is not in the list, its added at the front, and
tail cropped off. If its in the list, its substituted out and then
added to the front. (You'll also note that I reworked it slightly to
ensure that the list would -always- have a trailing [P] after each
line, even if there is only one. This is needed so that the substitute
would always work.

PS - you don't say what version of FM you are running, and I'm not
sure when filtervalues was added. If you don't have filtervalues,
ideally you should implement its functionality via a custom function
or within a script.

PPS You could solve the issue with patterncount more or less as you've
done.
Assuming MyUniqueID comes in formatted [P]idvalue[P]:

$$ID =3D If ( PatternCount ( $$ID ; MyUniqueID ) ; $$ID ; MyUniqueID &
MiddleValues ($$ID,2,9))

As you can see, in this version:

1) it doesn't matter if the list is blank, so we don't have to
initialize it

2) we append to the front instead of the tail; the list is right side
up. ;)

3) we use middle values to extract the 9 next most recent values in
the the 2nd-10th positions; (the first value is always blank).

4) because MyUniqueID is coming in with a leading and trailing [P], we
can safely use patterncount, and we can safely prepend it to the list
returned by middle values, resulting in the leading [P] (the blank
line we need for pattern count) , then the value, and a single [P]
between the new ID, and the first entry in the list -- because we used
middle values to bypass the [P] which was already there.

5) We also don't need to do any double-return substitutions.

Of course I've probably made a few typos so test and debug ;)

cheers,
Dave

Re: double returns

am 29.01.2008 19:39:22 von ursus.kirk

Thanks Dave for your very informative reply.

I know for sure that the ID is formatted correctly. It reads ArchID000001
and increments by one, it has no returns. At this time I haven't tested your
suggestions, but I will surely do.

Many thanks again,

Keep well, Ursus

Re: double returns

am 29.01.2008 19:45:10 von ursus.kirk

Ps I did state fmp9a xp, so I do have filtervalues.

Re: double returns

am 29.01.2008 22:02:45 von ursus.kirk

David,

I have tinkered with your solution and came up with a working end result,
wich is:

Set field MyField ;

Let (
[ $$ID_ret = MyUniqueID & "¶" ;
$$ID = If ( FilterValues ( $$ID ; MyUniqueID ) ? "" ; $$ID_ret &
Substitute ( $$ID ; $$ID_ret ; "" ) ; $$ID_ret & LeftValues ( $$ID ; 9 )
) // END IF
] // END LET
; $$ID )

I replace the <> with the ?. I don't know why, but the <> did not work while
the ? does. I thought the <> would be platform independent, while the ?
isn't something I normally (on XP) would use. But anyway. This does all I
needed now. Thanks again.

Keep well, Ursus

Re: double returns

am 29.01.2008 22:30:53 von d-42

On Jan 29, 10:39 am, "Ursus" wrote:
> Thanks Dave for your very informative reply.
>
> I know for sure that the ID is formatted correctly. It reads ArchID000001
> and increments by one, it has no returns. At this time I haven't tested your
> suggestions, but I will surely do.
>
> Many thanks again,
>
> Keep well, Ursus


Thanks for the clarification. I re-reviewed your calc, and the issue
is that IsEmpty() clause.

LeftValues when applied to any non-null list already returns a list
with each item followed by a [P].

The first value you insert results in:

ArchID000001[P]

When you add the 2nd one:

$$ID going in:
ArchID000001[P]

substitute($$ID,[PP],[P]):
ArchID000001[P]

& if(isemtpy($$ID,"","[P]") <-- evaluates to false, and adds a [P]
ArchID000001[P][P]

& myUniqueID2:
ArchID000001[P][P]ArchID000002

Leftvalues(the above; 11) <-- tacks a [P] at the end if there isn't
already one there
ArchID000001[P][P]ArchID000002[P]

Hence your double spacing.

Fixing it is as simple as removing the isempty clause. You don't need
it.

But the technique is still buggy, because your appending to the right
but grabbing left values, so you'll also need to change it to
RightValues, and I'm still not sure why you're grabbing 11 instead of
10.

-cheers,
Dave

Re: double returns

am 29.01.2008 23:00:51 von d-42

On Jan 29, 1:02 pm, "Ursus" wrote:
> David,
>
> I have tinkered with your solution and came up with a working end result,
> wich is:
>
> Set field MyField ;
>
> Let (
> [ $$ID_ret =3D MyUniqueID & "=B6" ;
> $$ID =3D If ( FilterValues ( $$ID ; MyUniqueID ) ? "" ; $$ID_ret &
> Substitute ( $$ID ; $$ID_ret ; "" ) ; $$ID_ret & LeftValues ( $$ID ; 9 )
> ) // END IF
> ] // END LET
> ; $$ID )
>
> I replace the <> with the ?. I don't know why, but the <> did not work whi=
le
> the ? does. I thought the <> would be platform independent, while the ?
> isn't something I normally (on XP) would use. But anyway. This does all I
> needed now. Thanks again.
>
> Keep well, Ursus

Interesting note about <> vs /=3D (at least I'm guessing its /=3D, your
post came through with a question mark?!) I don't use <> in actual
code, I just wrote it because /=3D doesn't reliably show up.

That said, I prefer to avoid /=3D or <> as much as possible; and in this
case would recommend testing for equality instead of inequality, and
just reordering the statements to match. (Or better still testing for
IsEmpty, because that's what we really care about.)

Thus if you want to polish it this code to perfection:

Let (
ID_ret =3D MyUniqueID & "=B6" ;
$$ID =3D ID_ret & If ( IsEmpty(FilterValues ( $$ID ; MyUniqueID )) ;
LeftValues ( $$ID ; 9 );
Substitute ( $$ID ; ID_ret ; "" )))

(which factors out the "$$ID_ret &", and re-orders the if-filtervalues
clauses to allow us to use isEmpty instead of a string comparison. I
also removed the $$ on $$ID_ret; there is no reason for it to be a
global.)

-cheers,
Dave

Re: double returns

am 30.01.2008 00:51:54 von Helpful Harry

In article <479ef83b$0$16743$dbd41001@news.wanadoo.nl>, "Ursus"
wrote:

> fmp9a xp
>
> I have created a script that tracks the ID's from the 10 most recently
> visited. I do this by setting the current ID on top of the list. Number 10
> drops out. However the first calculation has double returns between values.
> I have created a solution but am very curious why the first version has
> these double returns. I fail the see my error.
>
>
> MyUniqueID ; text, serial, auto/increment
>
> Set Field gRecentlyVisisted ;
> Let ( [
> Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
> $$ID = If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "¶") &
> If(IsEmpty($$ID);"";"¶") & MyUniqueID; 11) ) ] ;
> $$ID)
>
> I added a substitute to counter the problem, but am still puzzled.
>
> Let ( [
> Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
> $$ID = If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "¶") &
> If(IsEmpty($$ID);"";"¶") & MyUniqueID; 11) ) ] ;
> Substitute ( $$ID; "¶¶"; "¶"))
>
> Keep well, Ursus

I don't really know why you're getting double-returns. Perhaps it's
something to do with parameters (if that's what $$ID is) or maybe the
LeftValues function is adding the extra returns. If the IDs are single
"words" you could try swapping LeftValues to LeftWords and see if the
extra returns disappear (assuming of course that newer versions of
FileMaker haven't replaced LeftWords with LeftValues).

Apart from that, the only other possible reason I can think of for
double-returns could be if you are removing values in a different
Script / Calculation (or manually editing the field) and leaving the
return character behind ... BUT the Substitute function that is in the
first function above should take care of that).


I think there are a couple of other possible mistakes here too ...
although they could just be typos when transferring the function to a
newsgroup message.

Firstly, you say you want the "top 10" and yet the LeftValues function
appears to be taking 11.

Your custom function above is appending MyUniqueID to the end of the
list rather than the front. You either need to turn around the
appending or use the RightValues function (so that it grabs values
starting from the end of the data), otherwise the newly added ID is
being dropped once you reach 11 ... unless I'm misunderstanding what
the LeftValues function does and it somehow reverse the values.

I also don't understand why the first version of the custom function
has a Substitute function in it (unless the Substitute function is
there to get rid of the extra return characters from values being
removed elsewhere, as mentioned above). It should probably just be $$ID
itself.

Combining all of these gives you a custom function of:

Let ( [
Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
$$ID = If ( Exists ; $$ID ; LeftWords ( MyUniqueID &
If( IsEmpty ( $$ID ) ; "" ; "¶" ) & $$ID; 10) ) ] ;
$$ID)

Of course, this function won't move an existing ID to the top of the
list, so the list is not "age sorted".


I recreated this as an equivalent Script and it works fine.

If [PatternCount($$ID; MyUniqueID) = 1]
Set Field [$$ID; $$ID]
Else
Set Field [$$ID; LeftWords(MyUniqueID & If(IsEmpty($$ID); "";
"¶") & $$ID, 10)]
End If
Set Field [gRecentlyVisisted; $$ID]


Helpful Harry
Hopefully helping harassed humans happily handle handiwork hardships ;o)

Re: double returns

am 30.01.2008 09:46:10 von ursus.kirk

Harry,

$$ means it is a named, global variable. It exists as long as the program
runs
$ means its a named, local variable. It exists as long as the current script
runs.


Keep well, Ursus


"Helpful Harry" schreef in bericht
news:300120081251545734%helpful_harry@nom.de.plume.com...
> In article <479ef83b$0$16743$dbd41001@news.wanadoo.nl>, "Ursus"
> wrote:
>
>> fmp9a xp
>>
>> I have created a script that tracks the ID's from the 10 most recently
>> visited. I do this by setting the current ID on top of the list. Number
>> 10
>> drops out. However the first calculation has double returns between
>> values.
>> I have created a solution but am very curious why the first version has
>> these double returns. I fail the see my error.
>>
>>
>> MyUniqueID ; text, serial, auto/increment
>>
>> Set Field gRecentlyVisisted ;
>> Let ( [
>> Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
>> $$ID = If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "¶") &
>> If(IsEmpty($$ID);"";"¶") & MyUniqueID; 11) ) ] ;
>> $$ID)
>>
>> I added a substitute to counter the problem, but am still puzzled.
>>
>> Let ( [
>> Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
>> $$ID = If ( exists ; $$ID ; LeftValues ( Substitute ( $$ID; "¶¶"; "¶") &
>> If(IsEmpty($$ID);"";"¶") & MyUniqueID; 11) ) ] ;
>> Substitute ( $$ID; "¶¶"; "¶"))
>>
>> Keep well, Ursus
>
> I don't really know why you're getting double-returns. Perhaps it's
> something to do with parameters (if that's what $$ID is) or maybe the
> LeftValues function is adding the extra returns. If the IDs are single
> "words" you could try swapping LeftValues to LeftWords and see if the
> extra returns disappear (assuming of course that newer versions of
> FileMaker haven't replaced LeftWords with LeftValues).
>
> Apart from that, the only other possible reason I can think of for
> double-returns could be if you are removing values in a different
> Script / Calculation (or manually editing the field) and leaving the
> return character behind ... BUT the Substitute function that is in the
> first function above should take care of that).
>
>
> I think there are a couple of other possible mistakes here too ...
> although they could just be typos when transferring the function to a
> newsgroup message.
>
> Firstly, you say you want the "top 10" and yet the LeftValues function
> appears to be taking 11.
>
> Your custom function above is appending MyUniqueID to the end of the
> list rather than the front. You either need to turn around the
> appending or use the RightValues function (so that it grabs values
> starting from the end of the data), otherwise the newly added ID is
> being dropped once you reach 11 ... unless I'm misunderstanding what
> the LeftValues function does and it somehow reverse the values.
>
> I also don't understand why the first version of the custom function
> has a Substitute function in it (unless the Substitute function is
> there to get rid of the extra return characters from values being
> removed elsewhere, as mentioned above). It should probably just be $$ID
> itself.
>
> Combining all of these gives you a custom function of:
>
> Let ( [
> Exists = ( PatternCount ( $$ID ; MyUniqueID ) ) ;
> $$ID = If ( Exists ; $$ID ; LeftWords ( MyUniqueID &
> If( IsEmpty ( $$ID ) ; "" ; "¶" ) & $$ID; 10) ) ] ;
> $$ID)
>
> Of course, this function won't move an existing ID to the top of the
> list, so the list is not "age sorted".
>
>
> I recreated this as an equivalent Script and it works fine.
>
> If [PatternCount($$ID; MyUniqueID) = 1]
> Set Field [$$ID; $$ID]
> Else
> Set Field [$$ID; LeftWords(MyUniqueID & If(IsEmpty($$ID); "";
> "¶") & $$ID, 10)]
> End If
> Set Field [gRecentlyVisisted; $$ID]
>
>
> Helpful Harry
> Hopefully helping harassed humans happily handle handiwork hardships ;o)