Hey everyone,
I am completely new to this environment but have already enjoyed the features I have utilized so far. However, I ran into an issue. I am attempting to script a property change event that executes when the user changes the PPM/run rate of the machine. This run rate is also to update a Power table where the part numbers and their attributed PPM’s are stored, but does not update the table, only the UPC. I get an error as follows:
Error executing script for event: propertyChange
on component: Run Rate
Details:
File “event:propertyChange”, line 3, in
AttributeError: ‘NoneType’ object has no attribute ‘replace’
The script in the numeric text field:
if event.propertyName == "intValue":
partNumber = event.source.parent.getComponent("Part Number")
ATMSettings.setRunRateFromPartNumber(int(partNumber.replace(",","")), int(event.newValue))
I also want to point out that in the tree, the ‘Run Rate’ is in Templates-> Data-> Run Rate. and the power table is under Windows-> Standard Run Rates-> Root Container-> Power Table SRR.
Thanks for looking at my issue if you have a second!
partNumber references a component directly.
So partNumber.replace() doesn’t exist - I assuming an you are trying to do this to a get rid of commas out of an integer string? This is unnecessary if you grab the .intValue
from the component directly.
Here is the rest of the code that is within the project library
def getRunRateFromPartNumber(partNumber):
settings = system.tag.readBlocking(["[default]Concentrator PLC/ATM_Settings"])
settingsDataset = settings[0].value
return datasetFindValue(settingsDataset, "PartNumber", partNumber, "RunRate")
def setRunRateFromPartNumber(partNumber, newRunRate):
settings = system.tag.readBlocking(["[default]Concentrator PLC/ATM_Settings"])
settingsDataset = settings[0].value
newDataset = datasetFindReplace(settingsDataset, "PartNumber", partNumber, "RunRate", newRunRate)
system.tag.writeBlocking(["[default]Concentrator PLC/ATM_Settings"], [newDataset])
addHistoryEntry(partNumber, newRunRate)
def addHistoryEntry(partNumber, newRunRate):
historyDataset = system.tag.readBlocking(["[default]Concentrator PLC/History"])[0].value
newDataset = system.dataset.addRow(historyDataset, historyDataset.getRowCount(), [system.date.now(), partNumber, newRunRate, system.security.getUsername()])
system.tag.writeBlocking(["[default]Concentrator PLC/History"], [newDataset])
def datasetFindValue(dataset, searchColName, searchValue, returnColName):
for row in system.dataset.toPyDataSet(dataset):
if row[searchColName] == searchValue:
try:
return row[returnColName]
except:
raise Exception("Column name doesn't exist: " + returnColName)
return ""
return ""
def datasetFindReplace(dataset, searchColName, searchValue, replaceColumn, replaceValue):
rowCt = 0
for row in system.dataset.toPyDataSet(dataset):
if row[searchColName] == searchValue:
return system.dataset.setValue(dataset, rowCt, replaceColumn, replaceValue)
rowCt += 1
raise Exception("Couldn't find column " + searchColName + " with value " + str(searchValue) + " in the dataset, returning original dataset")
return dataset
Is this a text field? You probably want partNumber = event.source.parent.getComponent("Part Number").text
if this is something you need to get an int out of.
Alternatively and probably better is to use a numeric text field, you can make your number masking to have commas (or not) and then you can grab partNumber = event.source.parent.getComponent("Part Number").intValue
and not have to worry about manually getting rid of commas out of an integer.
Thanks for the suggestion. You make a really good point and it was originally set up as a text field and I changed it to a numeric text field, and wasn’t aware I could remove the commas under this type of field. I made these changes and the script looks better but is still throwing a similar error.
File “event:propertyChange”, line 2, in
AttributeError: ‘NoneType’ object has no attribute ‘intvalue’
In advance, sorry if I miss something I currently have the flu and am working 
Think it should be .intValue
, everything is camelCased in Ignition.
However, I don’t even trust myself to type component relationships correctly by hand - I just always use the property selector to find and pick what property I need.
3 Likes
Oops, good catch. I corrected the notation but got the same error. Rookie mistake ha.
if event.propertyName == "intValue":
partNumber = event.source.parent.getComponent("Part Number").intValue
ATMSettings.setRunRateFromPartNumber(int(partNumber.replace()), int(event.newValue))
Did you use the property selector? If not, delete what you have and use the property selector like @bkarabinchak.psi mentioned.
Well now partNumber
has type
of int
so it will not have a .replace()
function, nor do you need to typecast it as it is already an int.
An AttributeError means you are calling a property or method on something that does not exist, and an integer does not have a replace
method.
1 Like
I did and got a whole new error.
Traceback (most recent call last):
File “event:propertyChange”, line 2, in
AttributeError: ‘NoneType’ object has no attribute ‘event’
You’re making some great points. How would you structure it since I have literally chopped it to death and am clearly leaving behind unnecessary functions?
I would think this is enough
if event.propertyName == "intValue":
partNumber = event.source.parent.getComponent("Part Number").intValue
ATMSettings.setRunRateFromPartNumber(partNumber), int(event.newValue))
Though since you are looking for the propertyName intValue
, the event.newValue\event.oldValue will be of int
type, so you can probably do it as
if event.propertyName == "intValue":
partNumber = event.source.parent.getComponent("Part Number").intValue
ATMSettings.setRunRateFromPartNumber(partNumber), event.newValue)
2 Likes
Okay, I made the changes to remove anything not needed and I still get the ‘intValue’ in line 2. Could the issue be that because the ‘intValue’ I am trying to use is inside the power table and I am stuck in the Data under Templates. Do I need to drill out and then back down into the windows to use the correct property?
When I use the ‘Insert Property Reference’ I cannot get to the Part Number because it is in the Power Table under Windows.
For anyone who may need this information in the future within the community, the solution to my issue was as follows:
if event.source.parent.txtPartNumber:
partNumber = event.source.parent.txtPartNumber
ATMSettings.setRunRateFromPartNumber(partNumber, event.newValue)
There were a few problems found throughout the troubleshooting, but after some cleaning up and pointing to the correct data “txtPartNumber”, the issue was resolved. Hopefully this will help someone else.