4

This is based on a previous question/answer that I had. Replacing values in multiple columns using QGIS Field Calculator?

I need it to update 3 fields now and I get an name 'e' is not defined error. What have I done wrong?

layer = qgis.utils.iface.activeLayer()

Set field names you want to update

field_1 = "New_Name" field_2 = "New_File_P" field_3 = "Process" idx_1 = layer.fieldNameIndex( field_1 ) idx_2 = layer.fieldNameIndex( field_2 ) idx_3 = layer.fieldNameIndex( field_3 )

Set expression to find all features which fall into expression

exp = QgsExpression( """ "Existing_F" LIKE '%2015 Aerial Ortho\_2015\ECW_Tiles%' """ )

Select all features which fall into expression

ids = [i.id() for i in layer.getFeatures(QgsFeatureRequest(exp))] layer.setSelectedFeatures(ids)

Set expressions to fill in values for selected features

formula_1 = """ "File_Name" """ formula_2 = """ '\sipv-gis01\GIS_Library\Raster\Aerial\2015_25cm\Images\ECW' """ formula_3 = """ 'y' """ e_1 = QgsExpression(formula_1) e_2 = QgsExpression(formula_2) e_3 = QgsExpression(formula_3) e.prepare(layer.pendingFields())

with edit(layer): # For each selected feature for f in layer.selectedFeatures(): f[idx_1] = e_1.evaluate(f) f[idx_2] = e_2.evaluate(f) f[idx_3] = e_3.evaluate(f)

    layer.updateFeature(f)

Error

e.prepare(layer.pendingFields())
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'e' is not defined

==== I needed to do this again and here's the QGIS 3x code =====

#search and replace text in all fields of all layers in map

#set text to search for and replace with. #CAUTION Partial match is allowed #Based on https://gis.stackexchange.com/questions/317855/search-and-replace-text-in-all-fields-in-qgis-3

searchText = "Bougainvilia" replaceText = "Bougainvillea"

#run on active layer #layer = iface.activeLayer()

#run on all layers layers = QgsProject.instance().mapLayers() i=1 for layer_id, layer in layers.items(): print("Layer: %s" % (layer.name())) # get data provider dpr = layer.dataProvider() for field in layer.fields(): fieldName=field.name()

    for feature in layer.getFeatures():
        inText = str(feature[fieldName])
        # get field index
        fieldIndex = layer.fields().indexFromName(fieldName)
        #print (&quot;Checking %s&quot; % (inText))

        if searchText in inText:
            # change inText
            print (&quot;%s . REPLACED: %s in %s with %s in column: %s&quot; % (i, searchText, inText, replaceText, fieldName))
            outText = inText.replace(searchText, replaceText)
            i+=1
            # save changes
            dpr.changeAttributeValues({feature.id(): {fieldIndex: outText}})

print ("Completed")

GeorgeC
  • 8,228
  • 7
  • 52
  • 136
  • 1
    I don't know python, but what stands 'e' for? don't see any declaration in your code snippet or is it al global variable? – Frau Schmidt May 13 '16 at 07:03
  • Is it a typo for the exp QgsExpression you declared in line ~20? – Spacedman May 13 '16 at 07:09
  • 1
    Sorry, that was a mistake on my part. You shouldn't need that line e.prepare(layer.pendingFields()). – Joseph May 13 '16 at 10:03
  • Thanks @Joseph you were correct. Can you post this as an answer? – GeorgeC May 16 '16 at 21:47
  • 1
    Thanks George but @JochenSchwarze posted an answer which already describes commenting out (or removing) that line so please accept his :) – Joseph May 17 '16 at 09:23
  • @Joseph -I approved this to quick. It appears to work (i.e no errors) but the data fields are not updated. The query works correctly when just run in "select by expression" but not in the code. What else could be wrong? – GeorgeC May 19 '16 at 22:23
  • @Joseph -can you help with why this isn't working? – GeorgeC May 22 '16 at 07:33
  • @GeorgeC - Are you running this from the Python Console or from a script? Try adding your last line layer.updateFeature(f) directly underneath f[idx_3] = e_3.evaluate(f) so there's no extra line between them. – Joseph May 23 '16 at 09:16
  • Thanks @Joseph this didn't work. I am running it from the python console in QGIS. – GeorgeC May 23 '16 at 14:38
  • @GeorgeC - Are the fields you want to update String type? – Joseph May 23 '16 at 14:40
  • Yes, it works fine manually @Joseph – GeorgeC May 23 '16 at 22:51
  • @GeorgeC - I tested your code on an example shapefile and it works so not exactly sure what's going on. Perhaps if you upload your shapefile to a public server, others could test it and confirm if it's the shapefile that's the problem or not. – Joseph May 24 '16 at 09:07
  • @Joseph -Not sure why it's not working but a test dataset is in the following link. You will need to modify the search to fit with something in this subset of the full dataset. https://drive.google.com/file/d/0B1XGDTNNfbMJZFRJeDlZalF5RVU/view?usp=sharing – GeorgeC May 24 '16 at 10:47
  • 1
    @GeorgeC - Struggling to find the problem as the code still works and updates the .dbf file. This is after I clear all attributes in the 3 fields you mention in your code and setting the expression to exp = QgsExpression( """ "File_Type" = 'shp' """ ). Don't think I can help much further, sorry -_- – Joseph May 24 '16 at 11:07
  • Updated question to have QGIS 3.x code. Just paste it in to the python editor within QGIS and click on the layer you want to update. Change the search and replace text as appropriate. – GeorgeC Feb 01 '22 at 22:29

1 Answers1

2

According to http://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/expressions.html the member function QgsExpression.prepare() is not mandatory but makes the execution faster. I would recommend to comment out the line e.prepare(layer.pendingFields()) and see what happens.

And as far as I see, an exp.prepare(...) is missing directly behind the creation of the expression (i.e. exp=QgsExpression("""...) if things run slow, because the expression is evaluated in the next line as an argument to QgsFeatureRequest(exp).

Jochen Schwarze
  • 14,605
  • 7
  • 49
  • 117
  • I approved this to quick. It appears to work (i.e no errors) but the data fields are not updated. The query works correctly when just run in "select by expression" but not in the code. What else could be wrong? – GeorgeC May 19 '16 at 22:23
  • Hello everyone, does this work with QGIS 3.x and python 3? I failed to repeat this successfully. – Dan Sep 18 '18 at 07:53
  • See the updated Q for Python 3x code. – GeorgeC Feb 01 '22 at 22:30