Problème de tableau en liste [Résolu]

Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
- - Dernière réponse : CerberusPau
Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
- 5 oct. 2013 à 11:35
Bonjour à tous,

J'ai une erreur (9) dans mon codeci-dessous, à la ligne
TabTests(i) = Ref
, et je ne trouve pas pourquoi.

'contruction du tableau
'======================
    Dim Ref As String   'Référence du Test
    Dim TabTests()      'Déclaration tableau variable
    'Taille du tableau
    Dim Fin As Integer  'N° de la dernière ligne du tableau
    Fin = Sheets("CertJG").Range("BZ65536").End(xlUp).Row - 1
    'Redimentionner si plusieurs Tests ont été trouvés
    If Fin > 1 Then ReDim TabTests(Fin)
    ' Avec un seul test trouvé, Fin = 0
    For i = 0 To Fin
        'Référence du Test trouvé (exemple Ref = "45")
        Ref = Sheets("CertJG").Range("BZ" & i + 1).Value
        'ERREUR D'EXECUTION (9)
        'L'indice n'appartient pas à la sélection
        TabTests(i) = Ref
    Next i


Merci de votre aide
Cordialement
Afficher la suite 

10 réponses

Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214
0
Merci
Bonjour,
ton tableau n'étant pas dimensionné, je vois mal comment tu peux accéder à son indice i !

De toutes manières : ne pas chercher midi à 14 heures et remplir le tableau d'un seul coup, ainsi (exemple) :
Dim tableau
tableau = Range("B1:C3")

et tableau contiendra toutes les valeurs (ici sur 2 colonnes, donc) de la plage traitée.
Commenter la réponse de ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214
0
Merci
En appelant ton attention sur le fait que le tableau ainsi obtenu sera en option base 1 (et non 0)
tableau(2,2) , donc (exemple) pour avoir le contenu de la cellule B2 (2ème ligne, 2ème colonne de la plage et du tableau)
Commenter la réponse de ucfoutu
Messages postés
781
Date d'inscription
lundi 22 janvier 2007
Statut
Membre
Dernière intervention
30 octobre 2013
3
0
Merci
Fin vaut 1 de trop.

Je pense que Sheets("CertJG").Range("BZ65536").End(xlUp).Row = 10
Donc Fin = 9

Ce qui fait que ReDim TabTests(Fin) créer un tableau dans les case vont de 0 à 8 (PAS DE 0 à 9 ) !!!

Donc For i = 0 To Fin fait que i va de 0 à 9 alors qu'il doit aller de 0 à 8.

Solution For i = 0 To Fin-1 ou ajouter fin=fin-1 avant la boucle for.

Note que la solution de ucfoutu est la meilleur. ça solution mérite que tu t'y attardes. Avec ma réponse tu sais pour quoi ta solution, qui est louable, ne fonctionne pas.
Commenter la réponse de 4u4me4us
Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
0
Merci
J'ai donc choisi la première solution de Ucfoutu pour créer le tableau TabTests en voulant en afficher les résultats dans une MsgBox.

J'ai essayé 2 cas, avec un seul test trouvé et avec plusieurs, mais j'ai une erreur 13 dans les 2 cas.

'contruction du tableau
'======================
    Dim TabTests()      'Déclaration tableau variable
    Dim Fin As String   'N° de la dernière ligne du tableau
    Fin = Sheets("CertJG").Range("BZ65536").End(xlUp).Row
    If Fin = 1 Then     'un seul test trouvé
        TabTests = Sheets("CertJG").Range("BZ1").Value
        'si un seul test =>Erreur 13 : incompatibilité de type
    Else                'plusieurs tests trouvés
        TabTests = Sheets("CertJG").Range("BZ1:BZ" & Fin).Value
    End If
    MsgBox TabTests 'si plusieurs tests =>Erreur 13 : incompatibilité de type


Je ne vois pas ce que je dois faire pour corriger l'erreur 9 précédente et les erreurs 13 ici...

Merci
ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214 -
Tabtests estr un tableau:
msgbox Tabtests n'a aucun sens, sans précision des index !
exemple/test (à tester ... tu vas comprendre :
Dim tableau
tableau = Range("B1:B3")
For i = 1 To UBound(tableau)
  MsgBox tableau(i, 1)
Next

Cela correspond à ce que je t'ai dit plus haut.
CerberusPau
Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
-
Le tableau peut comporter une seule ou plusieurs lignes.

J'ai donc adapté avec
End(xlUp).Row
comme suit :

Dim tableau
Dim Lst As String
Lst = Range("BZ65536").End(xlUp).Row
tableau = Range("BZ1:BZ" & Lst)
For i = 1 To UBound(tableau)
  MsgBox tableau(i, 1)
Next


1°) Il n'y a pas de problème si Lst > 1

2°) Mais j'ai une erreur 13 quand Lst = 1 à la ligne
For i = 1 To UBound(tableau)


3°) Mon tableau ne comporte qu'une série de données (une seule "colonne" en somme), donc, la syntaxe MsgBox tableau(i) devrait convenir, mais ça n'est pourtant pas le cas : erreur 9, comme au premier code (objet de ma question.initiale).
ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214 -
tout d'abord :
rien (vraiment, ne te gêne dans ces 2 lignes ) :
Dim Lst As String
Lst = Range("BZ65536").End(xlUp).Row

Moi oui !
Ensuite :
si lst = 1 (et non "1", hein, s'il te plait !) : il n'y a plus de tableau, mais une seule cellule....
Je ne vais tout de même pas, CerberusPau, écrire (trop simple) l'expression conditionnelle qui convient ...
FAIS-le, s'il te plait.
Commenter la réponse de CerberusPau
Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
0
Merci
Je ne pensais pas qu'un tableau de une ligne n'était pas reconnu en tant que tableau. Je le saurai, et donc qu'il faille passer par un If.

Effectivement j'ai la mauvaise de déclarer les "valeurs" de colonnes en String pour les Range. Je corrige donc, comme tu me le demandes:
Dim tableau
Dim Lst
Lst = Range("BZ65536").End(xlUp).Row
tableau = Range("BZ1:BZ" & Lst)
If Lst = 1 Then
    MsgBox Range("BZ1:BZ" & Lst).Value
Else
    For i = 1 To UBound(tableau)
        MsgBox tableau(i, 1)
    Next
End If


Dernier point :
MsgBox tableau(i)
n'est donc pas correct quand il n'y a qu'une simple liste (un seule "colonne")?

Commenter la réponse de CerberusPau
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214
0
Merci
Non ! pas correct ! relis donc ce que j'ai écrit plus haut . Le tableau résultant d'une plage a DEUX dimensions et non une. Elles sont en option base 1.
Commenter la réponse de ucfoutu
Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
0
Merci
Donc ça veut dire que pour une seule dimension (une liste), je dois mettre l'option
Option Explicit Option Base 0
en tête de module, pour que
MsgBox tableau(i)
soit correct?
Commenter la réponse de CerberusPau
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214
0
Merci
1) Je n'ai jamais dit cela
2) faire ton expression conditionnelle sir le base de ta variable lst = 1 est maladroit (je t'expliquerai pourquoi ce soir)
3) les tableaux dynamiques créés pour traiter les celluyles de Excel doivent toujours être en option base 1 si l'on veut pouvoir profiter des énormes facilités qu'ils offrent et de leur grande agilité
5) j'ai déjà (il y a entre 6 mois et un an) déjà traité ce problème en créant une procédure polyvalente
4) c'est l'heure de la marée et la pêche est prioritaire. Je reviendrai après dîner avec, à nouveau, l'écriture une procédure polyvalente
A plus (à ce soir après dîner).
Commenter la réponse de ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214
0
Merci
Bon sars et louvines étaient là ... tout va bien).


Alors : voilà la fonction universelle que je viens d'écrire :
Private Function faire_tableau(plage As Range)
 If plage.Cells.Count < 2 Then
    Dim tabli(1 To 1, 1 To 1)
    tabli(1, 1) = plage.Value
    faire_tableau = tabli
    Erase tabli
  Else
    faire_tableau = plage.Value
  End If
End Function
 

Elle est à utiliser ainsi (exemple)

tabl = faire_tableau(Range("A1:A3"))
  
  ' la suite n'est là que comme preuve de la bonne exécution
  For i = 1 To UBound(tabl, 1)
    For j = 1 To UBound(tabl, 2)
      MsgBox tabl(i, j)
    Next
  Next

toujours vrai, quelle que soit la plage (une cellule, une seule colonne, une seule ligne ou plusieurs colonnes et lignes
et le tableau retourné sera toujours en base 1 et contiendra toujours les valeurs de la plage traitée.
Rien ne devrait maintenant te manque, CerberusPau

ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214 -
Ah oui ! j'ai oublié de te dire pourquoi, dans le code que tu avais écrit, ta condition If lst = 1 était maladroite ===>>
Elle ne résout ton problème que si la première ligne de la plage traitée est la ligne 1 et que la plage concerne une seule colonne.
Avec ta méthode (mais toujours si colonne unique ! car pire si non !) , il faudrait dire if lst = 2, if lst = 3, etc ... selon que la plage traitée commence en ligne2, 3, etc ... (pas très adroit).
ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214 -
Je n'ai pas réussi à trouver dans quelle discussion j'avais déjà donné une solution similaire.
Je viens donc de déposer un snippet avec la présente solution.
Commenter la réponse de ucfoutu
Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
0
Merci
Merci Ucfoutu.

Ta fonction "universelle" est beaucoup plus pratique que la solution "If" (je risquai effectivement d'avoir à batailler!).

Il me reste à "construire" le message qui doit afficher chaque valeur du tableau, ligne par ligne :

tabl = faire_tableau(Range("A1:A3"))
  
  ' la suite n'est là que comme preuve de la bonne exécution
 Ligne = "" 
 For i = 1 To UBound(tabl, 1)
    For j = 1 To UBound(tabl, 2)
       If Ligne = "" then 
         Ligne = Ligne & tabl(i, j)
       Else
         Ligne = Ligne & chr(13) & tabl(i, j)
       End if
     Next j
  Next i
 If Ligne <> "" then MsgBox Ligne

ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214 -
Ben ... Il est déjà au-dessus ( les lignes de preuve) :
For i = 1 To UBound(tabl, 1)
    For j = 1 To UBound(tabl, 2)
      MsgBox tabl(i, j)
    Next
  Next

et si une seule cellule ===>> tu n'auras bien qu'une seule valeur présente et affichée !
ucfoutu
Messages postés
18039
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
214 -
Ah ! tu veux ensuite construire un message par concaténation .
Cà, c'est autre chose et c'est simple.
Si la difficulté objet de la présente discussion (fabrication du tableau) est résolue (ce que je pense) ===>> discussion à clore (tag "(résolu")
Bon week-end
CerberusPau
Messages postés
377
Date d'inscription
lundi 3 avril 2006
Statut
Membre
Dernière intervention
22 août 2018
-
Effectivement!
Bon week-end a toi aussi
Commenter la réponse de CerberusPau