Operator writes in a text field and whatever they wrote is then queried. Here's the code:
bar = currentValue.value
bar = str(bar)
system.db.runNamedQuery('Pack', {'scan': bar})
scan is supposed to be a string and the query works when attached to a button, but now that I have it in the text field property change script, it says data mismatch.
It's no longer giving me that error but now it's giving me a completely new error message:
com.inductiveautomation.ignition.common.script.JythonExecException
Traceback (most recent call last):
File "function:valueChanged", line 19, in valueChanged
UnboundLocalError: local variable 'lvalue' referenced before assignment
for this line that also worked just fine on a button:
for row in DATApy:
for lvalue in row:
print lvalue
What is line 19? That error generally means that you've used a variable outside of the scope it is defined for.
Also, in perspective print doesn't do what you might expect. You should use system.perspective.print().
Going to be difficult to troubleshoot this script without the whole thing, or at least all of the relevant lines. If you're concerned about reveling proprietary data then redact it and replace it with a suitable stand in.
Or Call into support who can have a proper NDA agreement.
previousValue = ''
time = system.date.now()
bar = currentValue.value
DATA = system.db.runNamedQuery('Pack', {'scan':bar})
DATApy= system.dataset.toPyDataSet(DATA)
for row in DATAPY::
for lvalue in row:
print lvalue
system.db.runNamedQuery('DATAPack', {'BAR':lvalue})
TOTAL = system.db.runNamedQuery('ASTOTAL', {'pn':lvalue})
TOTALpy = system.dataset.toPyDataSet(TOTAL)
for row in TOTALpy:
for tvalue in row:
print tvalue
system.db.runNamedQuery('DATATOTAL', {'TOTAL':tvalue})
self.props.text = previousValue
Okay, well there aren't 19 lines in that script either, even if I add one for the function definition.
I can say a few things though.
You have two :'s in the line with for row in DATAPY: there should only be 1. I suspect this is the culprit for the error you're getting unless its a typo from typing it into the forum
You have DATAPY instead of DATApy.
You can just as easily use a comprehension to print those values. system.perspective.print([lvalue for lvalue in row for row in DATApy]
You should inisialize lvalue prior to using it in the loop if for whatever reason DATApy has no rows, lvalue will not be set and you'll see an error.
I would not use previousValue in this way, there is already an argument in the function definition for a property change and you're blasting it away.
It looks like you're expecting to get a single value back from the named queries, I would suggest that you create custom properties and use a query binding with the return format set to scaler, or you can access the value directly from the dataset.
In all, here is what I would think the script would look like:
time = system.date.now()
system.db.runNamedQuery('DATAPack', {'BAR': self.custom.lvalue})
system.db.runNamedQuery('DATATOTAL',{'TOTAL':self.custom.tvalue})
self.props.text = ''
Of course I probably don't understand what all of the different queries are doing. If you give some more context, we will be able to better help you develop the best way to approach the problem.
My original code has a bunch of comments in between but I didn't add them here. I'll try your suggestions and if it still gives me those errors i'll just go back to using a button instead
This type of code (code intended for troubleshooting) in any form should never be left in production (Vision or Perspective):
for row in pyDs:
for col in row:
print col
Here is some information on how print works in various contexts:
Currently the code as you had it is filling up your wrapper logs with what ever random data is returned in your queries. Of course if you want it to be there out of sight, then have at it, but depending on the size of the datasets you're adding an execution pause that will be seen as poor performance from the User's point of view.
Also, this is not how you initialize a variable. If you wanted to do it this way then the proper way to do it would be to initialize it prior to the loop, and set it inside of the loop.
lvalue = 0
for row in pyDs:
for col in row:
lvalue = col
Though that is equivalent to lvalue = pyDs[pyDs.rowCount -1][pyDs.columnCount - 1]
Tip: use print repr(row) to print the values of a pydataset. While the rows __str__ method doesn’t return anything particularly useful, their __repr__ does return the values.
Yes, but I was attempting to be clear on what was going on. I find that those not accustomed to pythons list indexing find that hard to follow.
For instance it isn't as obvious that [-1] will get you to the end of the list which is equal to the total number of rows/columns. Where [ds.*count -1] is fairly straightforward.