Problème de tableau en liste

Résolu
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 - 4 oct. 2013 à 10:46
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

10 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 4/10/2013 à 11:01
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.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
4 oct. 2013 à 11:04
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)
0
4u4me4us Messages postés 780 Date d'inscription lundi 22 janvier 2007 Statut Membre Dernière intervention 30 octobre 2013 3
4 oct. 2013 à 11:14
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.
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
4 oct. 2013 à 12:05
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
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
4 oct. 2013 à 13:09
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.
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
4 oct. 2013 à 14:09
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).
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
4 oct. 2013 à 14:28
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.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
4 oct. 2013 à 14:55
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")?

0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
4 oct. 2013 à 14:59
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.
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
4 oct. 2013 à 15:08
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?
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
4 oct. 2013 à 16:48
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).
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
4 oct. 2013 à 21:04
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

0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
Modifié par ucfoutu le 5/10/2013 à 08:35
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).
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 oct. 2013 à 10:40
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.
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
5 oct. 2013 à 10:45
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

0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 oct. 2013 à 10:56
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 !
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
5 oct. 2013 à 11:02
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
0
CerberusPau Messages postés 377 Date d'inscription lundi 3 avril 2006 Statut Membre Dernière intervention 22 août 2018 1
5 oct. 2013 à 11:35
Effectivement!
Bon week-end a toi aussi
0
Rejoignez-nous