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
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)
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.
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...
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).
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.
Vous n’avez pas trouvé la réponse que vous recherchez ?
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")?
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.
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).
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
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).
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.
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
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