Jump to content
Salesforce and other SMB Solutions are coming soon. ×

PIPR_Beta ..who needs relationships, when you can have virtual stacks ;)


forbade

Recommended Posts

/*

 

P ( Class, Row , Option , Data )

 

 

Possibly my only Public release of PIPR ,

 

As of now I am only half way done with this function but the core features are implemented..., It was created out of personal interest

and curiosity.

 

The completed version plans to have more interesting features like finding, displaying, and or replacing all unique values of a stack.

Also I plan on adding FIFO, and Specific extraction for the POP option and adding more options for the recursive output.

This cF uses some undocumented oddities :D ... Ill let you find them.

 

The Algorithms used in stack projection are mine, and take into consideration this is a semi - refined function, and it introduces

several conceptual ways of implementing some unique features. My final version, will probably much cleaner.

 

The function won't work if you go outside the defined Grid, the each stack index is protected from option overwrites, and the

recursive feature has safeties applied to it as well.

 

This was created and tested with FMP8 Advanced,

 

*/

 

Let (

[

 

//////////////////////////////////////////////////////////////////////////////

// Core Definition of Parameters

 

/* THE PROCESS NAMELIST | Converts Process Name to corresponding Stack in Grid */

 

// You can Either create your own name list, or just pass numbers to specify the Class / Column

c = If ( IsEmpty ( GetAsNumber ( Class ) ) = "0" ; Class ; // Checks to see if the Class is text or number, and then passes it to C

Case ( // Defines C_olumn number based on the Case of the name Input ( useful for assigning Class Names in the stack Grid.

Class = "inventory" ; "1" ;

Class = "session" ; "2" ;

Class = "rclass" ; "3" ; // etc etc...

"" )) ;

 

r = Row ; // Defines the R_ow location of Stack Grid

b = $$PIPR[-2] ; // Defines the B_ase of the Columns in the Grid ( Number of instances in Column ) This value is primed in the start up script.

cs = $$PIPR[-3] ; // Defines the number of C_olumn_S in the Stack Grid

L = If ( c ≥ 2 ; ( b * ( c - 1 ) + r ) ; "-1" ) ; // Returns the L_ocation of the top of the stack ( Important: holds stack index ) exception for first column

Lv = Evaluate ( $$PIPR[L] ) ; // Returns the Data from L_ocation rep.

E = ( b * cs ) ; // E_levator for 3rd dimension of stack (important when projecting the stack length) Used in stack projection.

 

d = Case ( // D_epth of Stack: This case will Set the Index $$PIPR[L_ocation] if it is empty, or it will return the stored value if populated.

IsEmpty ( $$PIPR[L] ) = "1" ; "2" ; // If its empty set to base

Evaluate ( "$$PIPR[" & L & "]" ) ≤ "1" ; "2" ; // Stack index protection against writing negative repetitions.

Evaluate ( "$$PIPR[" & L & "]" ) ); // Pulls the depth of the stack from top of stack

 

// Parameters used in Stack Manipulation

 

Fd = ( d - 1 ) ; // Returns F_alse D_epth of stack.(Critical in Stack Projection) //// Top layer reserved for index.

Ln = If ( c ≥ 2 ; ( E * Fd + L ) ; ( ( E * Fd ) + 1) ) ; // L_ocation N_umber //// This is next projected location for the stack //old ( E * ( d - 1 ) + L )

Lnv = Evaluate ( $$PIPR[Ln] ) ; //L_ocation N_umber V_alue : returns the Data held in Ln ( will return an empty result ,cause this is the next projected value)

Lnm = If ( c ≥ 2 ; ( E * ( Fd - 1 ) + L ) ; ( E * ( Fd - 1 ) + 1 ) ) ; // This is the Ln minus one layer used in the pop option

Fdv = Evaluate ( $$PIPR[Lnm] ) ; // Returns the Data from the most current stack layer.//

 

// Misc Parameters

key = ( b * c ) ; // key

null = "0"

 

] ;

 

// STARTUP writes: Used only in initial writes. Used in startup script. :)

////////////////////////////////////////////////////////////////////////////////////////

// Check out autoexec script for example how these variables are written.

 

Case ( Class = "core" and option = "write" ;

Let ([

//vData = " Let ( $$PIPR[- "&r&"] = \""&Quote ( Data )&"\" ; \"\" )" ; // set index to s_lide B_ack value

vRep = "$$PIPR[ -"&r&"]"; // Sets grid parameters to protected a location.

vData = "Let( " & vRep & " = " & Quote( data ) & " ; \"\" )" ;

wVariable = Evaluate( vData ) // Write variable

];

Evaluate ( "$$PIPR[-"&r&"]" )

) ;

 

// If not start up than begin.

///////////////////////////////////////////////////////////////////////////////////////

// Grid Protection

( c > cs or r > b ) = 1 ; "" ; // Function will not operate Parameters are greater than Grid.

 

Case ( // MASTER CASE_ This is the Top of the function Schema.

 

 

//PUSH - add data to Stack ( Takes input and adds it to the defined stack)

//////////////////////////////////////////////////////////////////////////////////////

 

option = "push"

;

Let ([

 

vL = "$$PIPR["&L&"]" ;

vLn = "$$PIPR["&Ln&"]" ;

vInput = "\"\"\""&Data&"\"\"\"" ; // :D & ;)

vData = "Let( " & vLn & " = "&Quote ( vInput )&" ; \"\" )" ;

vIndex = "Let( " & vL & " = " & ( d + 1 ) & " ; \"\" )" ;

wToLocation = Evaluate( vData ) ;

wIndex = Evaluate ( vIndex )

];

P ( Class ; Row ; "rec" ; "" ) // Display's stack via rec, option

) ;

///////////////////////////////////////////////////////////////////////////////////////

//POP - remove data from Stack ..LIFO ( takes last input and pops it to $$PIPR[1] aka $$PIPR )

////////////////////////////////////////////////////////////////////////////////////////

 

Option = "pop" ; If ( Evaluate ($$PIPR[L]) = 2 ; // Stack Index Protection

Let ([

vRep = "$$PIPR[1]";

vData = "Let( " & vRep & " = \"\" ; \"\" )" ;

wVariable = Evaluate( vData ) // Write variable

];

"" ) ;

// Note. that unlike Push's method which chains the write outs, it defines the write outs to one alias, and then writes the script in sequence.

Let ([

// Variable script. (1: sets vHome to Data from $$Lnm 2: write data to home 3: Set index,

vData = "Let(

[ vHome = Evaluate ( $$PIPR["&Lnm&"] ) ;

$$PIPR[1] = Evaluate ( vHome ) ;

$$PIPR["&L&"] = \""&Fd&"\" ;

$$PIPR["&Lnm&"] = \"\" ;

end = 0 ] ; \"\" )" ;

//////////////////////////////////////////////////////////////

//Write Predefined Variable script

SetData = Evaluate( vData )

 

];

P ( Class ; Row ; "rec" ; "" )&" HOME: "&$$PIPR[1]

)

)

;

 

 

/////SLIDE//////////////////////////////////////////////////////////////

 

////////////////////////////////////Forward/////////////////////////////

option = "slide" and Data = ">" ;

 

If ( $$PIPR[-L] = ( Fd - 1 ) ; Substitute ( $$PIPR[Lnm] ; "\"\"\"" ; "" ) ;

Let ( [

 

sF = ( Evaluate ( $$PIPR[-L] ) + 1 ) ; //s_lide F_orward, takes slide index in increments it plus one.

vF = ( E * sF + L ) ; // Projects, the next variable value for display

vData = " Let ( $$PIPR[-"&L&"] = \""&sF&"\" ; \"\" )" ; // sets slide index to the s_lide F_orward value

vWrite = Evaluate ( vData ) ] ; // writes to Index.

 

//

 

Substitute ( $$PIPR[vF] ; "\"\"\"" ; "" ) //displays output of slide forward

 

)

)

;

 

//Slide

/////////////////////////////////Reverse//////////////////////////////////

option = "slide" and Data = "

 

Case ( $$PIPR[-L] = "1" ; Substitute ( $$PIPR[(L+E)] ; "\"\"\"" ; "" ) ; // If index = 1 , than display first location

IsEmpty ( $$PIPR[-L] ) = True ; // if slide index is empty, than

 

Let ( // Write index, and display the entry location.

[

entryDepth = ( Fd - 1 ) ;

entryLocation = ( E * ( Fd -1 ) + L ) ;

variableData = " Let ( $$PIPR[-"&L&"] = \""&entryDepth&"\" ; \"\" )" ;

variableWrite = Evaluate ( variableData ) ;

end = "null"

];

Substitute ( $$PIPR[entryLocation] ; "\"\"\"" ; "" )

)

 

;

// If slide index is populated, than

Let ( [

 

// Write Location value to -L >

sB = ( Evaluate ( $$PIPR[-L] ) - 1 ) ; // set s_lide B_ack to the index minus 1

vB = ( E * sB + L ) ; // Project the variable to display

vData = " Let ( $$PIPR[-"&L&"] = \""&sB&"\" ; \"\" )" ; // set index to s_lide B_ack value

vWrite = Evaluate ( vData ) ] ; // write Data

 

//

 

 

Substitute ( $$PIPR[vB] ; "\"\"\"" ; "" )//show the projected value

 

)

)

;

 

///Slide ( Returns value to home) this does not delete the value,

////////////////////////////////////Return/////////////////////////////

option = "slide" and Data = "ret" ;

 

If ( $$PIPR[-L] = ( Fd - 1 ) ; // If Last entry....than

 

Let ( [

entryTrim = Substitute ( Evaluate ( $$PIPR[Lnm]) ; "\"" ; "" ) ;

retData = "

Let (

[

vData = "&entryTrim&" ;

$$PIPR[1] = vData

] ; \"\" )" ;

retWrite =Evaluate ( retData ) ;

end = "null"

] ;

Substitute ( $$PIPR[Lnm] ; "\"\"\"" ; "" )

)

 

 

 

//If Not last entry... Return Value

;

Let ( [

entryDepth = Evaluate ( $$PIPR[-L] ) ;

entryLocation = ( E * entryDepth + L ) ;

entryTrim = Substitute ( Evaluate ( $$PIPR[entryLocation]) ; "\"" ; "" ) ;

retData = "

Let (

[

vData = "&entryTrim&" ;

$$PIPR[1] = vData

] ; \"\" )" ;

//////////////////////////////////////////////////

retWrite =Evaluate ( retData ) ;

 

end = "null"

] ;

 

//

 

Substitute ( $$PIPR[entryLocation] ; "\"\"\"" ; "" ) //

 

)

)

;

 

///////////Recursive Beta...///////////////////////////////////

option = "rec" ;

If ( $$PIPR[L] ≤ 2 or IsEmpty ( $$PIPR[L] ) ; "" ; // Infinite loop protection

Let ( [

rS = If ( IsEmpty ( Data ) ; "2" ; Data ) ; // r_ecursive S_end , this is the initial value.

On = If ( c ≥ 2 ; ( E * (rS - 1) + L ) ; ( E * (rS - 1) + 1 ) ) ; // O_utput n_umber

O = Evaluate ( "$$PIPR["& On &"]" ) ] //O_utput

;

 

Case (

Option = "rec" and Data ≠ d ; ( rS - 1)&":"&Substitute ( O ; "\"\"\"" ; "" ) & ¶&""&P ( Class ; Row ; Option ; ( rS +1) ) ;

Option ≠ "rec" ; "non-recursive"

; "" )

 

)) ;

 

//MASTER CASE DEFAULT

 

"PIPR"

 

) // End Master Case

) // End Main IF Protection

) // End Master Let

 

 

/*

SDG†

*/

Link to comment
Share on other sites

hey Forbade. I'm going to come clean straight away. I have not got the faintest idea what PIPR is.... nor what the function is supposed to do. can you be a bit more specific about the purpose and workings? I'm afraid your sample is less than self explanatory.

Link to comment
Share on other sites

sorry kjoe,.. I am kinda new to the whole custom function thing.

 

This function is a multitool of sorts.

 

What it does, is manipulate a Global variable into acting like a Stack Grid.

The function add data to an assigned stack via a script. I fear my example database is probably just as confusing, so if it is I apologize for that.

 

The function is designed to be used with scripts,

 

You can set your stack grid up by priming it with the width and length of the grid. I give an example of this in my sample database.

 

after that you can add Text, or Numbers to a stack location in the grid.

 

 

P ( 3 ; 2 ; "push" : Table::Field )

 

would, push the data from Table::Field to the stack at the location marked by x

 

-123

1ooo

2oox

3ooo

4ooo

5ooo

 

each stack keeps track of how many items has in its index,

so you can retrieve or display the items,

 

P ( 3 ; 2 ; "rec" ; "" )

would display all of the items in the stack, (if any)

 

 

P (3; 2; "pop" ; "" )

 

would take the last entered value of the stack, pop it to $$PIPR and then delete it from the stack.

 

the slide options allow you to brows the items in a stack as well as extract the value.

 

----

so.... why this craziness you may ask

 

well I needed a more dynamic way to access information across tables that did not have relationships.

 

so now I can hand pick key data from any table I want add it to a stack and then transport it across any table.

Link to comment
Share on other sites

"so now I can hand pick key data from any table I want add it to a stack and then transport it across any table."

 

Kinda like use $$global but more complex?

Link to comment
Share on other sites

Maybe it's just my short attention span tonight, but I can't follow that CF either. Maybe it's the non-descript variable names. And a friendly note about posting CFs: Please include the function name and parameters at the top, like this:

 

P(Class;Row;Option;Data) =

 

or put it in a comment like at the top:

 

//P(Class;Row;Option;Data)

 

 

 

Anyway, if stacks are your thing, you might find this set of CFs useful:

 

http://www.clevelandconsulting.com/support/viewtopic.php?t=1519

 

It's only for one dimentional stacks, but then I guess I don't see where a 2D stack would be useful, so I never thought about it.

 

It looks like you're basically overloading the function to handle multiple operations, depending on what "Option" parameter is sent. As you can see in my implementation, I prefer to keep each operation as a separate CF. I also don't like to have a CF refer to a specific global variable. This would cause problems if you ever wanted to work with more than one of them. You'll notice in my version, I have the variable name passed to the CF as a parameter, then use the evaluate() function to actually make the magic happen.

 

 

BTW, if you like queue data structures, here's a similar set of queue CFs:

 

http://www.clevelandconsulting.com/support/viewtopic.php?t=1518

Link to comment
Share on other sites

"so now I can hand pick key data from any table I want add it to a stack and then transport it across any table."

 

Kinda like use $$global but more complex?

 

yes,

 

it actually manipulates a global variable. It just allows the global variable to be used as multiple stacks.

Link to comment
Share on other sites

Maybe it's just my short attention span tonight, but I can't follow that CF either. Maybe it's the non-descript variable names. And a friendly note about posting CFs: Please include the function name and parameters at the top, like this:

 

P(Class;Row;Option;Data) =

 

or put it in a comment like at the top:

 

//P(Class;Row;Option;Data)

 

 

 

Anyway, if stacks are your thing, you might find this set of CFs useful:

 

http://www.clevelandconsulting.com/support/viewtopic.php?t=1519

 

It's only for one dimentional stacks, but then I guess I don't see where a 2D stack would be useful, so I never thought about it.

 

It looks like you're basically overloading the function to handle multiple operations, depending on what "Option" parameter is sent. As you can see in my implementation, I prefer to keep each operation as a separate CF. I also don't like to have a CF refer to a specific global variable. This would cause problems if you ever wanted to work with more than one of them. You'll notice in my version, I have the variable name passed to the CF as a parameter, then use the evaluate() function to actually make the magic happen.

 

 

BTW, if you like queue data structures, here's a similar set of queue CFs:

 

http://www.clevelandconsulting.com/support/viewtopic.php?t=1518

 

Thanks for the tips ender, and the links. :D I am always curious to know how to use new ideas and concepts.

 

Can you tell me the benefits of having, these operations as separate cF's ?

 

I am just getting my feet wet with cF's and I am eager to learn different Theory.

 

 

also, the reason I don't mind setting the Stack Grid to one Global variable, is that I can theoretically have as many stacks as I want within the variable, so I will never run out of stacks.

I can access the whatever stack location by using the correct vector.

Link to comment
Share on other sites

I guess it's to keep with the spirit of FileMaker's functional programming model. You probably come from an object oriented background, as that what your code looks like. But FileMaker isn't really object oriented. It doesn't behave that way for most things.

 

For example, there's no set of "value" options for a Value() function that does the get, left, right, and middle operations. Each of those are built as separate functions, each acting on their own inputs.

 

For me, staying with this convention on my own functions makes it easier to read and write code using those functions.

Link to comment
Share on other sites

What you have done is interesting. You might consider 4D if these stacks are that important to your project since it has both a stack system of its own where you can put and push and it uses variables(x) that you can completely code with more versatility than Filemaker. In other words you would be spending your time using a system rather than creating one.

 

However, the change from Filemaker to 4D is quite strenuous and you might get lost in 4D's myriad of fun tools.

 

4D's lists are similar to Filemaker's lists and repeating fields but with more manipulating tools, etc.

Link to comment
Share on other sites

What you have done is interesting. You might consider 4D if these stacks are that important to your project since it has both a stack system of its own where you can put and push and it uses variables(x) that you can completely code with more versatility than Filemaker. In other words you would be spending your time using a system rather than creating one.

 

However, the change from Filemaker to 4D is quite strenuous and you might get lost in 4D's myriad of fun tools.

 

4D's lists are similar to Filemaker's lists and repeating fields but with more manipulating tools, etc.

 

I'm still rather new to Filemaker & Databases in general. I might try to check out 4D in the future. Filemaker has given me enough to chew on for right now lol.

 

I still have a ton to learn. :D

 

And thanks for the feedback I really appreciate everyone's help at this forum.

Link to comment
Share on other sites

This thread is quite old. Please start a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

Terms of Use