3

In a vector layer table there are two fields F1 and F2 with float type. I want to multiply these fields and insert results to new field F3. In below code new field created but without any value. What is problem?

layer = iface.activelayer()
F1 = self.ui.cBox_Width.currentText()
F2 = self.ui.cBox_Length.currentText()

new_Field = "F3"
provider = layer.dataProvider()
caps = provider.capabilities()

idx = provider.fieldNameIndex(new_Field)
try:
    if idx == -1:
        if caps & QgsVectorDataProvider.AddAttributes:
            res = provider.addAttributes([QgsField(new_Field, QVariant.Double)])
except:
    return False

layer.startEditing()
bufferfield = layer.fieldNameIndex('buffer_km')
formula = QgsExpression("\"F1\" * \"F2\"")
formula.prepare(layer.pendingFields())
for f in layer.getFeatures():
    f[idx] = formula.evaluate(f)
    layer.updateFeature(f)

layer.updateFields()
layer.commitChanges()
HMadadi
  • 1,046
  • 11
  • 24

1 Answers1

1

Try moving:

layer.updateFields()

before you start editing to ensure all newly created fields are recognised. You also need to replace:

f[idx] = formula.evaluate(f) 

with something like:

new_Field_idx = layer.fieldNameIndex(new_Field)
f[new_Field_idx] = formula.evaluate(f) 

as the old index would be -1 if it wasn't already created. And if you're calling your fields in your expression, you could use:

formula = QgsExpression(str(F1) + '*' + str(F2))

So you could try using something like the following:

layer = iface.activeLayer()
F1 = self.ui.cBox_Width.currentText()
F2 = self.ui.cBox_Length.currentText()

new_Field = "F3"
provider = layer.dataProvider()

idx = layer.fieldNameIndex(new_Field)
if idx == -1:
    layer.dataProvider().addAttributes([QgsField(new_Field, QVariant.Double)])

layer.updateFields()
layer.startEditing()
#bufferfield = layer.fieldNameIndex('buffer_km')
new_Field_idx = layer.fieldNameIndex(new_Field)
formula = QgsExpression(str(F1) + '*' + str(F2))
formula.prepare(layer.pendingFields())
for f in layer.getFeatures():
    f[new_Field_idx] = formula.evaluate(f)
    layer.updateFeature(f)

layer.commitChanges()
Joseph
  • 75,746
  • 7
  • 171
  • 282
  • Hi @Joseph, Unfortunately the result field is empty. – HMadadi Oct 27 '17 at 11:38
  • @nickan - Apologies, edited the post :) – Joseph Oct 27 '17 at 11:53
  • Sorry I can't get any result. – HMadadi Oct 27 '17 at 12:20
  • @nickan - Does it work if you replace F1 and F2 with the actual field names in the line formula = QgsExpression(str(F1) + '*' + str(F2))? (i.e. formula = QgsExpression('fieldName1 * fieldName2)) – Joseph Oct 27 '17 at 12:32
  • I tested your advice and replace F1 and F2 with field names and but it didn't work :( – HMadadi Oct 27 '17 at 13:13
  • I think you find problem, in Field tab of layer properties for my layer, F1 and F2 fields type is double and when I test the code with another field with type of qlonglong it works. But when I use Field Calculator GUI it works for F1 and F2 with double type.What is problem in this code for act on double type values? – HMadadi Oct 27 '17 at 13:36
  • @nickan - Not sure what the problem could be, I tested this on QGIS 2.18.13 and it works for me. Perhaps you can ask this as a new question and see if others have similar issues? – Joseph Oct 30 '17 at 10:11