XL 2021 Erreur "l'indice n'appartient à la selection"

  • Initiateur de la discussion Initiateur de la discussion treza88
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

treza88

XLDnaute Occasionnel
bonjour à tous,

j'utilise une fonction à l'intérieur avec un Array dynamique à une dimension "sdba", qui a chaque fois que j'appelle cette fonction utilise ce tableau, mais qui n'a pas toujours la même longueur.

A mon premier appel tout ce passe bien, mais après j'ai une erreur "l'indice n'appartient à la sélection" sur la ligne suivante :

VB:
ReDim Preserve sdba(LBound(sdba) To UBound(sdba) + 1)

j'ai bien essayé d'utiliser Erase pour pouvoir le redimensionner, mais j'ai toujours cette erreur.
Voici le code de fonction :

Code:
Function SansDoublonsArray(a)
  Set mondico = CreateObject("Scripting.Dictionary")
  Dim sdba() As Variant
 
  Erase sdba
  mondico.CompareMode = vbTextCompare
  For Each c In a
    If Not mondico.Exists(c) And c <> "" And c <> "?" Then
        mondico(c) = ""
   End If
  Next c
    If mondico.Count <> 0 Then
    sdba = Application.Transpose(mondico.keys)
    ReDim Preserve sdba(LBound(sdba) To UBound(sdba) + 1)
  Else
    ReDim sdba(1 To 1)
  End If
  
  sdba(UBound(sdba)) = "Pilotage"
 
  SansDoublonsArray = sdba
End Function

Pouvez vous me dire ce qui cloche, car de mon coté je ne comprend pas.
Je me dit bien que c'est a cause du changement de longueur du tableau, mais avec Erase je suis sensé être capable de le redimensionner ?
 
Bonsoir.
La propriété Keys d'un Dictionary est un tableau à 1 dimension basé 0 soit équivalent à une ligne de Mondico.Count colonnes
Worksheetfunction.Transpose en fabrique inutilement un tableau à 2 dimensions (1 To Mondico.Count, 1 To 1) dont le nombre de lignes ne peut plus être changé. Vous auriez intérêt à ajouter"Pilotage" à mondico avant d'en extraire les clés.
 
Dernière édition:
Merci Dranreb pour cette information qui me permet de mieux comprendre,

Par contre ce qui m'étonne c'est que quand j'ai plusieurs valeurs, j'ai bien sdba qui est un tableau a 2 dimension.

Capture d'écran 2026-01-16 075819.png


Mais si je n'ai qu'une valeur mon tableau sdba est à une dimension

Capture d'écran 2026-01-16 080304.png

Le fait que Transpose fabrique un tableau 2D m'intéresse, car après cette fonction, j'ai besoin d'un tableau 2D "sdba(x,5)".
Donc si c'est un tableau 2d, sachant que le x serait définit par Transpose en ayant intégré "Pilotage" dans mondico, je n'aurais qu'a ReDim la dernière dimension pour quelle soit définit à 5.

Mais pourquoi quand j'ai une seule valeur le tableau est à 1 dimension et comment faire pour qu'il soit a 2 dimension rien qu'avec une valeur ?

Si c'est possible car VBA n'est pas très souple avec les tableaux.
 
Je ne comprends rien à ce que vous décrivez. Joignez un classeur pour me montrer.
Mais c'est sûr que parfois quand il n'y a qu'une cellule il faut dimensionner manuellement le tableau puis affecter la valeur unique à son seul élément. Ne serait-ce que parce que la valeur d'une cellule isolée n'est pas un tableau notamment.
 
Dernière édition:
Bonjour à tous,

A tester, mais sans fichier

VB:
Function SansDoublonsArray(a)

    Dim mondico As Object
    Set mondico = CreateObject("Scripting.Dictionary")
    mondico.CompareMode = vbTextCompare

    Dim c As Variant
    For Each c In a
        If Not mondico.Exists(c) And c <> "" And c <> "?" Then
            mondico.Add c, Empty
        End If
    Next c

    Dim sdba() As Variant
    Dim i As Long

    If mondico.Count > 0 Then
        ReDim sdba(1 To mondico.Count + 1)
        i = 1
        For Each c In mondico.Keys
            sdba(i) = c
            i = i + 1
        Next c
    Else
        ReDim sdba(1 To 1)
    End If

    sdba(UBound(sdba)) = "Pilotage"
    SansDoublonsArray = sdba

End Function

Nicolas
 
Bonsoir à tous,
Par contre ce qui m'étonne c'est que quand j'ai plusieurs valeurs, j'ai bien sdba qui est un tableau a 2 dimension.
Tout à fait, Transpose crée un tableau d'une ou plusieurs lignes et d'une colonne mais ensuite vous écrivez :
VB:
ReDim Preserve sdba(LBound(sdba) To UBound(sdba) + 1)
ce qui définit un tableau à une dimension et là ça ne va pas.

Utilisez plutôt cette fonction :
VB:
Function SansDoublonsArray(a)
    Dim mondico As Object, c, sdba()
    Set mondico = CreateObject("Scripting.Dictionary")
    mondico.CompareMode = vbTextCompare
    For Each c In a
        If Not mondico.Exists(CStr(c)) And c <> "" And c <> "?" Then mondico(CStr(c)) = ""
    Next c
    mondico("Pilotage") = ""
    sdba = Application.Transpose(mondico.keys)
    SansDoublonsArray = sdba
End Function
Edit : j'ai ajouté CStr pour le cas où a et c seraient des Range.

A+
 
Dernière édition:
Bonjour le forum,

Il est plus logique et plus sûr de placer "Pilotage" au début du tableau :
VB:
Function SansDoublonsArray(a)
    Dim mondico As Object, c, sdba()
    Set mondico = CreateObject("Scripting.Dictionary")
    mondico.CompareMode = vbTextCompare
    mondico("Pilotage") = ""
    For Each c In a
        If Not mondico.Exists(CStr(c)) And c <> "" And c <> "?" Then mondico(CStr(c)) = ""
    Next c
    sdba = Application.Transpose(mondico.keys)
    SansDoublonsArray = sdba
End Function
Edit : j'ai ajouté CStr pour le cas où a et c seraient des Range.

A+
 
Dernière édition:
Merci Dranreb, Nicolas JACQUIN et job75,

Grace à vos codes et explication j'ai réussi à m'en sortir.

Code de base :
VB:
'Récupération des données de la feuille dans un tableau
 caseArray = Workbooks(file_Name).Sheets(tab3dFinal(j, 1)).Range("C" & tab3dFinal(j, 2) + 2 & ":J" & dernCell)
            
'Extraire la colonne comportant les noms
 TabNomUnique = ExtraitCol(caseArray, 4)
            
'Supprimer les doublons de la liste
 tbNomSdbl = SansDoublonsArray(TabNomUnique)

Je rajoute 3 item à mon tableau b, j'extrais les noms de ma colonne dans le nouveau tableau b à partir de la 4eme position, j'insère mes noms de base en premier dans le tableau.
Fonction ExtraitCol() :

Code:
Function ExtraitCol(a, col)
  ReDim b(LBound(a) To UBound(a) + 3)
  For i = LBound(a) + 3 To UBound(a) + 3
     b(i) = a(i - 3, col)
  Next i
  b(1) = "Pilotage"
  b(2) = "Z-Pilotage"
  b(3) = "Z-Vente"
  ExtraitCol = b
End Function

Je crée mondico pour supprimer les doublons, ensuite je crée un nouveau tableau dynamique au format de mondico avec une dimension supplémentaire et enfin j'insère les données de mondico dans le tableau.
Fonction SansDoublonsArray() :

Code:
Function SansDoublonsArray(a As Variant) As Variant
    Set MonDico = CreateObject("Scripting.Dictionary")
 
    MonDico.CompareMode = vbTextCompare
    For Each c In a
        If Not MonDico.Exists(c) And c <> "" And c <> "?" And c <> "DJA" Then
            MonDico(c) = ""
        End If
    Next c
 
    Dim tbNomSdbl() As Variant
    ReDim tbNomSdbl(1 To MonDico.Count, 1 To 5)
            
    For Each TestValeurDico In MonDico.keys
        k = k + 1
        tbNomSdbl(k, 1) = TestValeurDico
    Next TestValeurDico
 
  SansDoublonsArray = tbNomSdbl
End Function

Merci encore pour vos infos, car c'est pas toujours simple et souple les tableaux en VBA
 
bonjour,
tu te prends la tête pour rien tu rajoutes "Pilotage" a ton dico et plus de problème de redim.

Code:
Function SansDoublonsArray(a)
  Set mondico = CreateObject("Scripting.Dictionary")
  Dim sdba() As Variant
  mondico.CompareMode = vbTextCompare
    For Each c In a
        If Not mondico.Exists(c) And c <> "" And c <> "?" Then
           mondico(c) = ""
         End If
     Next c
     mondico("Pilotage") = ""
     sdba = Application.Transpose(mondico.keys)
  SansDoublonsArray = sdba
End Function
 
Dernière édition:
Bonjour dysorthographie,

Oui tout à fait, mais j'ai quand même besoin d'un ReDim, car j'ai besoin d'un tableau du type Array(x, 5).

Et du coup ça ressemblerait à ça :

VB:
Function SansDoublonsArray(a As Variant) As Variant
Dim sdba() As Variant
    Set mondico = CreateObject("Scripting.Dictionary")
 
    mondico.CompareMode = vbTextCompare
 
    mondico("Pilotage") = ""
    mondico("Z-Pilotage") = ""
    mondico("Z-Vente") = ""
    For Each c In a
        If Not mondico.Exists(c) And c <> "" And c <> "?" And c <> "DJA" Then
            mondico(c) = ""
        End If
    Next c
 
   sdba = Application.Transpose(mondico.keys)
    ReDim Preserve sdba(LBound(sdba) To UBound(sdba), 1 To 5)
  SansDoublonsArray = sdba
 
End Function

Si j'ai bien compris. Et c'est vrai que c'est moins tordu et évite une boucle.
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

  • Question Question
Microsoft 365 Erreur UBound
Réponses
4
Affichages
259
Réponses
12
Affichages
691
Réponses
3
Affichages
619
Retour