here is the other screenshot
When this script runs on server, how do you tell it what Jobs record you mean, and how does it populate it's session's copy of the Jobs::gProductQTY field? When you use the Perform Script On Server script step, the script running on the server has no concept of what record or layout you're on in your client-side session, or the contents of any client-side global fields or variables. You should pass this information in a script parameter.
So, the Jobs::gProductQTY field not matching the value from your client session may be the main cause of your infinite loop. One thing that wouldn't make your script work as you expect, but would at least have avoided the infinite loop would be if your Exit Loop If condition on line 48 was Get ( FoundCount ) ≥ Jobs::gProductQTY, rather than using =. This is a general defensive best practice.
Some other comments about your script:
- Why are you using $$globalVariables? Unless you need to access these data outside the script, it's best to use $localVariables to avoid any unintended side effects from other processes that might be using variables with the same names. Even if you do need to access that data outside the script, make an effort to use script parameters and results to pass that information around in a more contained way before resorting to global variables.
- In step 8, you have the Freeze Window script step. If you're performing this script on server, it doesn't make any sense to use that script step, as there isn't a window being rendered, so it won't give you any performance benefit. Further, it's not a server-compatible script step, so it's throwing out errors on the server every time it runs that step. If you would like to keep that step in the script for when you run it client-side, I recommend that you wrap it in If/End If checking that the script is not running on a server.
- In step 28, you use the Show All Records script step immediately before entering find mode. Showing All records accomplishes nothing for you there, so you may as well not do it; and you're definitely better off not doing when you run the script client-side, so you avoid loading any unnecessary records over the network. Furthermore, you're better off entering find mode before going to the "LineItems_Sequence" layout rather than after, so that there's no opportunity to load any record data except for the records the script actually needs to act on.
Rules for PoS scripts:
- As Jeremy Bante indicated, you need to use the script editor to check each script for server compatibility.
- The script performed on the server "knows nothing" of your current "context". It won't know your current layout, current found set, current record or current sort order--all things that client side scripts take for granted. The only info that this script will have to work with is any data you choose to pass in a script parameter. As I recall, even global variable values will not be accessible from the PoS script. (If you have used PoS and know that what I just said about variables is wrong, please correct me!) Think of it as writing out a message to a fellow user of the database on a 3x5 card: "Hey George, use the script ABC with the data value 123, write the result on this card and throw it back to me."
- Any "context" results such as Found sets produced by this script will also be invisible to the client machine that performed this server side script.
- Any changes to the values of global fields will not be immediately visible to the client machine. Any change to global variables will not be accessible at all.
- The only way to pass data back to the client side script that called it is via the result parameter of the exit script step.
- Unlike client sessions, changes to global fields are changes made from a "host" context. The changes will persist and will be visible to each user that logs in to the database after this script changed the values. (Your original client session would have to do a relogin before the changes to global field data will be visible.)
Thank you gentlemen for your insight and advice. :)
So obviously I have a number of items to pass to the server using Script Parameters. ($BOMID, $JOBID, etc)
Is it wise to use the LET function within a script parameter to list and handoff these values to the server and then use the Evaluate function to grab them and drop them in the necessary fields while the script is running on the server?
Awesome. THANK YOU!!!
You can also use the List function. This method is much simpler than Let, but requires that none of your listed items be allowed to be empty values.
You can use a List function like this: List ("Apple" ; "Orange" ; "Grape" ) as your script parameter expression and then:
GetValue ( Get ( ScriptParameter ) ; 1 ) will return "Apple",
GetValue ( Get ( ScriptParameter ) ; 3 ) will return "Grape"
ok. Would this be allowed?
List ($BomID; $SeqID)
then Get Value (Get (ScriptParameter) ;1) would return $BOMID and so forth?
everything in this script is based on going to the next record, grabbing a value, then going to a layout to create a new record and setting a field in that new record with that value.
It would return the value of the variable, not the variable itself.
You set up something like:
Set Variable [$ScriptVarriableNameHere ; GetValue ( Get ( ScriptParameter ) ; 1 ) ]
I like that approach not only for its simplicity but the list of set variable steps at the beginning of the script make a nice "declarations block" documenting the values passed to the script in the Parameter List.
i dig it. :)
I've since updated the local script and went further with it.. at least locally. From one new job it creates manufacturer records based on the products' s primary bom.. finds the related bom sequences and creates the related tasks.. then goes looking for related sub assemblies and their sequences, creates the manufacturing record and related tasks for them as well.. then starts over.. depending on the quantity the user set when the button was pressed. (although I forgot to change the end of the script from "=gProductQuantity" to the suggested expression. I'll work on that today.
Ok so if I'm following you.. I would declare my variable like this in the beginning of the script.
Set Variable [$BomID ; GetValue ( Get ( ScriptParameter ) ; 1 ) ]
Set Variable [$JobID ; GetValue ( Get ( ScriptParameter ) ; 2 ) ]
Set Variable [$SeqID ; GetValue ( Get ( ScriptParameter ) ; 3 ) ]
Set Variable [$ManufID; GetValue ( Get ( ScriptParameter ) ; 4 ) ]
And then Script Parameter would look like this..
List (_fkBomID; _fkJobID; _fkSeqID; _fkManufID)
Am I following that correctly?
Yep. You don't have to have that block of Set Variables at the beginning of the script, nor do you need to use variables as you can use the getvalue calculations shown to get this data as needed, but this is how I prefer to set it up as it makes things fairly "self documenting".
pretty groovy. Thanks!!!