ListIndex qui déraille ?

Bonjour à tou.te.s,

Je rencontre un bug plutôt étonnant (et obscur pour moi) en utilisant une listbox d'une userform (UF).

Dans l'exemple minimal joint, je permets, via une UF, la modification de la colonne "Prénom" d'un tableau structuré (suivre les étapes décrites dans l'UF).
Tout se passe bien tant que les item de la première colonne "Nom" sont uniques.

Par contre, si on créé un doublon (p. ex. ici remplacer "Bernard" par "Martin", et qu'on modifie alors le prénom de cette même ligne (n° 3)), la propriété ListIndex "prend la liberté" de passer de 2 à 1 (c'est-à-dire de passer de la ligne 3 à la ligne 2 par elle-même) sans qu'aucun code (explicite) n'aille la modifier

Ayant contourné le problème en ajoutant une première colonne avec un index (1,2,3,...) unique, je me demande si, "en route", le code interne de VBA ne perd pas la propriété ListIndex et cherche à la retrouver en utilisant la valeur de la première colonne de la ligne sélectionnée, et tombe ainsi sur la première occurrence de la valeur doublon, et finalement la recharge, et génère le "bug" observé.

Ceci n'est qu'une hypothèse, et mes limites de compréhension sont ici clairement atteintes.

Je fais donc appel à vos lumières !!!

5listindex-bug.xlsm (29.86 Ko)

Bonjour,

1- ne pas utiliser la propriété Rowsource pour un tableau structuré mis à jour au cours de l"exécution

2- utiliser le code propre à un tableau structuré : classe ListObject

3- éviter d'utiliser le nom du UserForm dans le code. Cela facilitera son changement éventuel de nom en cas de maintenance.

ci-jointe version modifiée:

Bonjour thev,

Merci pour votre réponse !

  1. Auriez-vous la raison derrière l'incompatibilité de Rowsource et d'un tableau structuré modifié ?
  2. Je serai preneur d'informations complémentaires pour manipuler les tableaux structurés avec ListObject.
    Auriez-vous des références à me conseiller sur le sujet ?
  3. En effet, merci à nouveau !

Problème résolu

Bonsoir,

Auriez-vous la raison derrière l'incompatibilité de Rowsource et d'un tableau structuré modifié ?

La raison est que cela conduit à un plantage d'Excel car le Rowsource ne peut s'appliquer qu'à un tableau invariant lors de l'exécution, comme une table par exemple.

Je serai preneur d'informations complémentaires pour manipuler les tableaux structurés avec ListObject.
Auriez-vous des références à me conseiller sur le sujet ?

Une première référence serait cet article d'Excel pratique : https://www.excel-pratique.com/fr/astuces/tableau-structure

Ensuite, vous pouvez compléter par ce petit mémo que j'ai rédigé :

Rappel

Un tableau structuré Excel est en fait l’équivalent d’une table Access.

  • Il est borné car le nombre de ses lignes et colonnes est obligatoirement défini
  • Il est identifié par son nom et les entêtes de ses colonnes.

Utilisation de la classe ListObject

Ses principales propriétés sont les objets :

  • Range = ensemble du tableau
  • HeaderRowRange = ligne des entêtes de colonne
  • DataBodyRange = lignes des données du tableau
  • TotalsRowRange = ligne des totaux du tableau si elle a été définie
  • ListRows = lignes du tableau
  • ListColumns = colonnes du tableau

Assignation du tableau structuré à partir de son nom :

    Dim tb_struct As ListObject
    Dim feuille As Worksheet

    Set tb_struct = Range("nom_du_tableau").ListObject
    'feuille où se trouve le tableau
    Set feuille = tb_struct.Range.Worksheet

Gestion des lignes du tableau :

    Dim ligne As ListRow
    Dim i As Integer, nb_lig As Integer, nb_col As Integer

    '// nombre de lignes
    nb_lig = tb_struct.ListRows.Count

    '// nombre de colonnes
    nb_col = tb_struct.ListColumns.Count

    '// ajout d'une ligne et indice de la ligne ajoutée
    Set ligne = tb_struct.ListRows.Add: i = ligne.Index

    '// suppression d'une ligne d'indice i
    tb_struct.ListRows(i).Delete

    '// vidage intégral du tableau
    tb_struct.DataBodyRange.Delete

    '// modification d'une ligne d'indice i
    tb_struct.ListColumns("entête_de_la colonne").DataBodyRange(i) = valeur

    '// recherche de l'indice d'une ligne du tableau à partir d'une valeur de recherche
    Dim cell As Range
    Set cell = tb_struct.Range.Find(valeur_recherchée)
    'indice de la ligne du tableau
    i = cell.Row - tb_struct.HeaderRowRange.Row

Merci thev !

J'avais déjà identifié l'article mais votre mémo complète bien

Rechercher des sujets similaires à "listindex qui deraille"