Hi,
here I am using one template. I have taken this template in main screen for 2 machines.
I have written the script on multistate button calling named query. the script is working its is displaying total parts.
But can you suggest any other way of writing script to get the data for all templates on the screen.
without using if statement can we do this. because still I need to add other 5 machine data, so how to avoid repetition.
def runAction(self, event):
inputtime = self.props.controlValue
allmachines = ['R17_Rougher','R17_Honor']
for i in allmachines:
parameters = {"InputTime":inputtime,"MachineName":i}
system.perspective.print(i)
dataIn = system.db.runNamedQuery("select_TotalGoodParts_MES",parameters)
if i == 'R17_Rougher':
self.getSibling("SimpleMachineView1").props.params.TotalYield = dataIn
#break
pass
else:
self.getSibling("SimpleMachineView2").props.params.TotalYield = dataIn
My first thought would be to include the named query within the View Template itself. Pass in the period to the template, and pass the parameter into the named query and it will automatically re-execute whenever the parameter changes.
As for the script itself (I suggest you not use it, as per above), but as a learning example, you can improve this like so:
You're going to want to use the Flex Repeater component, but I advise against handing off a parameter to each instance and letting the instances run a parameterized query; it would work, but there's a better way. Modify the query to return data for a subset of specified machines, and then use the returned data to populate the instances property of the Flex Repeater.
Pseudo-code:
allmachines = ['R17_Rougher','R17_Honor']
query = "select myColumn from TotalGoodParts where name in ({0})".format(','.join(['?' for machine in allmachines]))
myYields = system.db.runPrepQuery(query, "MyDB")
# convert yields from PyDataSet to list
instances = [{"dataIn": myYield} for myYield in myYields]
self.getSibling("MyFlexRepeater").props.instances = instances
Alternatively, you could just bind FlexRepeater.props.instances against your parameterized Named Query, and include the Multi-State Button as a param of the query. The binding is a much better way to go.
The binding route is much cleaner. In the following screenshot, I've bound FlexRepeater.props.instances to a Named Query. My Named Query happens to only take in one value, but this could easily be expanded to accept several values. My transform converts the returned PyDataSet to a json object so the Flex Repeater knows what to do with the values.
But even this approach can be a headache because of the PyDataSet conversion, so I went back and modified my NamedQuery to alias the returned quantity, and I also modified the returned value to be json. This allowed me to remove my transform entirely, and pass the pure data right into the binding.
That solution has multiple concerns which will make it a long-term maintenance headache:
If the number of machines ever changes, this script will either begin logging exceptions to the Gateway logs or you'll have an Embedded View which is empty/stale because you've hard-coded j to always depend upon the count of machines. If you ever add a machine without adding an Embedded View, you'll see exceptions because a component could not be found. If you remove machines you'll have an Embedded View present which never updates.
You're performing a Query for each item. I highly recommend finding a way to get all of your data from a single query. If you have many sessions using this View on a regular basis you're going to have a lot of traffic for no reason.
Dynamically building component names in a script is very fragile. If you rename even one of the Embedded Views, or if you put them into a container in an effort to organize your View, this script will stop working.
The use of a pure binding has many benefits, including:
no scripting is necessary.
reduced number of queries.
If the Flex Repeater is renamed or moved into a container the binding will immediately fault and inform you that the path has been broken (as opposed to the script route where it will not fail until executed).
I'll throw in as well, that you're using a coordinate View, but this type of content is very much more suited to a flex View with emdebed flex containers. It'll be significantly easier to develop and modify with flexs, with more options