2

I would like to get a array with id's of all selected features of layer 'LayerB' (field-name: "id_of_layerB") as a default-value in a qgis-attribute-form of 'LayerA'.

I tried something like:

aggregate(layer:='LayerB',
          aggregate:='array_agg',
          expression:= "id_of_layerB",
          is_selected('LayerB', ???)
          )

but I have no idea how to realize this (especially what to put in in the "???"-part of the expression-part of the code.

I think, the "is_selected"-function checks agains just one feature, but is there a way tho get ALL (one or more) selected features of 'LayerB'?

2
string_to_array(
    aggregate(@layer,
              aggregate:='concatenate',
              expression:=to_string("id"),
              filter:=is_selected(),
              concatenator:=','),
    delimiter:=','
    )

result3

1
  • I've no idea why code works just in some layers in my project. There are several layers where code does not work (type: character varying[]). Same code is copied from one layer and its fieldcalculator to another by copy and paste with different results/previews:['1','2'...] or ['']
    – user191847
    Nov 24 '20 at 20:32
1

Alternatively you may try using a short PyQGIS code:

layer = iface.activeLayer()
selection = layer.selectedFeatures()
ids = [feature['id'] for feature in selection]

result

1
  • But how to add this code in a expession? Modifed code. But still does not work: aggregate( layer:= 'LayerB', aggregate:='array_agg', expression:="id_of_layerB", filter:=is_selected('LayerB' , get_feature_by_id('LayerB',$id))=True)
    – user191847
    Nov 23 '20 at 9:34
1
array_filter(
    array_foreach(generate_series(0, layer_property(@layer, 'feature_count')-1),
        if(is_selected(get_feature_by_id(@layer, @element)), attribute(get_feature_by_id(@layer, @element), 'id'),'***')
        ),
    @element != '***')

result2

2
  • seems to have a slower performance on large layers
    – user191847
    Nov 24 '20 at 20:40
  • yes, you are right. because it involves a bit more functions than other approaches
    – Taras
    Nov 24 '20 at 20:41
1
string_to_array(concatenate(to_string("id"), filter:=is_selected(), concatenator:=','), delimiter:=',')

result1

1
  • I'd prefer your first approach (string_to_array(aggregate(@layer...) because the array shall be stored in another layer
    – user191847
    Nov 24 '20 at 20:37
1

Or you can use Python in the Field Calculator via the Function Editor

from qgis.core import *
from qgis.gui import *
import qgis.utils

@qgsfunction(args='auto', group='Custom')
def ids(field, feature, parent):
    layer = qgis.utils.iface.activeLayer()
    selection = layer.selectedFeatures()
    ids = [feature[field] for feature in selection]
    return ids

python

and get the output

result

Note: That function ids('id') reads field with a single parentheses i.e. '.

2
  • I'd prefer your first approach (string_to_array(aggregate(@layer...) because the layer may not be selected in my case
    – user191847
    Nov 24 '20 at 20:38
  • Shall I delete other solutions that are not working for you?
    – Taras
    Nov 24 '20 at 20:39
1

Used the pyqgis-code from @Taras, renamed some arguments and added some flexibility (layerName as argument) and a check against unique layername and added a helptext :

from qgis.core import *
from qgis.gui import *


@qgsfunction(args='auto', group='Custom')

def selected_content(layerName, field, feature, parent):
    """
    Returns a array of field-contents of selected features<br><br>
    Returns <br><br><span class=\"argument\">string </span>Array of field-contents
    <br>
    <h4>Syntax</h4><br>
    <code><span class=\"functionname\">selected_features</span> <span class=\"argument\">(string, string)</span></code><br>
    
    <h4>Arguments</h4><br>    
    <span class=\"argument\">string </span>UNIQUE layer name <br>
    <span class=\"argument\">integer </span>field name <br>
    <h4>Example</h4><br>    
    <ul> 
      <li><code>selected_content('myLayerName','myFieldName')</code> &rarr; <code>'['a','b']'</code>
    </ul>

    """
    layer = layers = QgsProject.instance().mapLayersByName(layerName)
    if len(layer)>1:
        content=['invalid layer name (not unique)']
    else:
        selection = layer[0].selectedFeatures()
        content = [feature[field] for feature in selection]
    return content

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.