Trier les enregistrements sélectionnés

Bonjour,
J’ai un objet métier dont les attributs sont triés selon un ordre défini.

J’ai une action qui va créer un xml avec les enregistrements sélectionnés ( ou tous les enregistrements si pas de sélection) avec un ordre différent.

  ObjectDB entite = this.getGrant().getTmpObject("ParticipationEntite");
	entite.resetFilters();
	entite.resetOrders();
	entite.getField("ParticipationEntiteTypePers").setOrder(1);
	entite.getField("participationDirectionLibelle").setOrder(2);
	//trouve les éléments sélectionnés, si pas de sélection prend tous les éléments
	List<String> ids  = this.getSelectedIds();
	List<String[]> rows  = new ArrayList<String[]>();

Mais au final, c’est l’ordre dans lequel j’ai sélectionné les enregistrements qui est conservé…

Bonjour,

Les ordres de tri servent aux recherches en base via la méthode search.
Le getSelectedIds retourne les enregistrements sélectionnés par l’utilisateur dans l’ordre de sa sélection, ce qui est bien le résultat attendu (typiquement pour une action de “merge” où le premier sera l’objet principal).

Vous devez donc :

  • soit re-trier vos ids par code java
  • ou refaire un search limité aux ids sélectionnés via filtre ou search-spec

Attention

  • si ids est nul ce la signifie que “tout” est sélectionné pour éviter d’encombrer la mémoire avec toute la base. Si ce comportement est attendu et que la table est énorme, il faudra paginer la lecture pour ne pas saturer le mémoire.
  • si ids est vide : rien n’a été sélectionné, à vous de dire si c’est normal ou pas à l’utilisateur
ObjectDB entite = this.getGrant().getTmpObject("ParticipationEntite");
entite.resetFilters();
entite.resetOrders();
entite.getField("ParticipationEntiteTypePers").setOrder(1);
entite.getField("participationDirectionLibelle").setOrder(2);

List<String> ids = getSelectedIds();
if (!Tool.isEmpty(ids)) {
   String[] list = Arrays.asList(ids);
   entite.getRowIdField().setFilter("in (" + String.join(",", list) + ")");
}

// attention si ids est nul = ceci ramènera TOUTE la table
// Si tel est le cas, il faudra prévoir une lecture paginée en boucle
List<String[]> rows = entite.search();

...

entite.resetFilters();
entite.resetOrders();

“ou refaire un search limité aux ids sélectionnés via filtre ou search-spec”

c’est ce que je vise. Est-ce qu’il y a de la doc pour ça?

Et pour la pagination? parce que je suis en train de voir que mon xml est créé tant que je ne dépasse pas 30 sélections…

Le code en exemple fait exactement ce que vous demandez : un search trié avec un row_id filtré sur quelques ids. La documentation est là

https://docs.simplicite.io/documentation/01-core/basic-code-examples.md#searching

Pour 30 lignes inutile de paginer, sinon cela se fait comme ceci :

Historiquement en V4 :

long totalNbRows = o.getCount();
int maxRowsPerPage = 200;
o.preparePagination(totalNbRows, maxRowsPerPage);
for (int p = 0; p <= o.getMaxPage(); p++) {
	o.setCurrentPage(p);
	for (String[] row : o.search(true, maxRowsPerPage)) {
		o.setValues(row, false /* or true if you do an update */);
		String val = o.getField("myField1").getValue();
		(...)
	}
}

Depuis la V5 via callback par page :

int pageSize = 200;
obj.search(true, pageSize, (rows) -> {
	for (String[] row : rows)
		o.setValues(row, false /* or true if you do an update */);
		// ...
	});

Je suis navré de revenir sur le tri, mais je n’arrive pas bien à voir comment je trie par

ParticipationEntiteTypePers

Ma liste ids contient les rowid des enregistrements sélectionnés
je boucle sur ma liste ids pour récupérer toutes les valeurs de chaque enregistrement sélectionnés et créer la liste rows

J’imagine que c’est dans cette liste rows que je dois trier les lignes par type de personne morale, mais je ne vois pas comment.

c’est certainement basique, mais là sur le coup, ça m’échappe…

Votre entite.resetOrders(); annule les ordres de tris paramétrés sur votre objet.

Pour conserver ces tris paramétrés retirez cette ligne, sinon remettez des tris explicites via des myField.setOrder(n) ad hoc.

Comme déjà indiqué dans mon exemple de code, il faut obligatoirement refaire un search une fois votre setOrder spécifiés, et non pas une simple boucle de N select sur des ids non triés.

List<String[]> rows = entite.search();

rien ne sert de faire N select unitaires ensuite, puisque ça ramène tout en une seule fois.

  1. init de l’objet (orders…)
  2. filtre sur les ids sélectionnés via setFilter("in (...)")
  3. search

Je ne peux pas vous aider plus, sauf venir faire un copier/coller de mon code.

j’ai remplacé mon code par le vôtre :

  ObjectDB entite = this.getGrant().getTmpObject("ParticipationEntite");
	entite.resetFilters();
	entite.resetOrders();
	entite.getField("ParticipationEntiteTypePers").setOrder(1);
	entite.getField("participationDirectionLibelle").setOrder(2);
	
	List<String> ids = getSelectedIds();
	if (!Tool.isEmpty(ids)) {
	   String[] list = Arrays.asList(ids);
	   entite.getRowIdField().setFilter("in (" + String.join(",", list) + ")");
	}
	
	// attention si ids est nul = ceci ramènera TOUTE la table
	// Si tel est le cas, il faudra prévoir une lecture paginée en boucle
	List<String[]> rows = entite.search();
	
	StringBuilder x = new StringBuilder();
	x.append("<Entites>" + System.getProperty("line.separator")); ...

mais j’ai une erreur :

Compile error:Class compilation error (status 1)
/home/fabrice/tomcat/webapps/ROOT/WEB-INF/src/com/simplicite/objects/Participation/ParticipationEntite.java:729: error: incompatible types: no instance(s) of type variable(s) T exist so that List conforms to String
String list = Arrays.asList(ids);
^
where T is a type-variable:
T extends Object declared in method asList(T…)
1 error
#ERROR

J’ai écrit le code sans le tester, il doit y avoir un pb de cast.
L’idée est de transformer une List en tableau de String pour faire un “join” facilement, essayez avec

String[] list = (String[])ids.toArray();

Cette fois ça compile.
Mais l’exécution donne une erreur :

class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader ‘bootstrap’)

C’est du java… et comme ça ?

String[] list = new String[ids.size()];
list = ids.toArray(list);

sinon faites une boucle pour faire le join à la main.

Mille Mercis, ça fonctionne parfaitement !

1 Like

[Message prédéfini]

Nous conseillons aux utilisateurs de marquer comme “solution” la réponse résolvant leur problématique pour permettre au support de mieux suivre les sujets non résolus, et à la communauté de trouver plus facilement la bonne réponse.

Vos messages indiquant une résolution du problème, nous avons réalisé cette opération pour vous.