Rapport de message :*
 

Re: Recherche valeur.

Titre du sujet : Re: Recherche valeur.
par Guy le 01/06/2010 19:23:40

Bonjour tout le monde,

J'ai suivi à la trace le code fournit dans le classeur Recap2(2).xls et l'ai commenté ainsi.

Option Base 1

Sub recapituler()
Dim dercol As Byte, entete As String, cptr As Byte, nbre As Integer
Dim tablo
Dim lig As Integer, donnee As Byte

' La variable dercol devrait porter le numéro de colonne du dernier champ
' On suppose implicitement que la première colonne est en 1 ce qui n'est pas le cas dans ce classeur.
' En effet les champs cibles ont été déplacés en AU7:AW7.
' À noter que la dernière colonne de la ligne 7 est donnée par Cells.Columns.Count pour
' permettre une compatibilité avec toutes les versions d'Excel.
' Pour Excel 2003 et antérieur Cells.Columns.Count = 256
' Pour Excel 2007 Cells.Columns.Count = 16 384
' Dans le cas Excel 2007 il faudrait modifier
donnee As Byte en donnee As Long
' L'instruction originale est commenté donc non exécutée.
' À noter aussi l'utilisation du nom de code pour désigner la feuille visée au lieu
' de Sheets("Récap") ce qui rend le code indépendant du nom d'onglet de cette feuille.
' Nous posons la plage notée ("?????") en fin de ligne 7 et nous examinons la suite.

'dercol = Sheets("Récap").Range("?????").End(xlToLeft).Column
dercol = Feuil2.Cells(7, Cells.Columns.Count).End(xlToLeft).Column

' dercol porte 49 puisque c'est le numéro de la première colonne non vide à droite de la ligne 7
' La suite montrera que le déplacement de la plage cible en AU7:AW7 pose problème.

' La variable entete devrait porter une en-tête toutefois on suppose ici que la
' feuille Cible (Récap) est active ce qui n'est pas nécessairement le cas.
' On devrait plutôt utiliser une référence complète à la cellule "AU7" de la feuille Récap.
' Aussi on suppose que la cellule AU7 porte l'une des en-têtes valides ("Partie 1", "Partie C", "Partie 2A").
' Ce qui n'est pas nécessairement le cas non plus.
entete = Range("AU7")

 With Sheets("données")
    ' La fonction CountIf() provoquera une erreur si d'aventure la variable entete est vide ("")
    ' de plus si entete porte une chaîne de caractères différente d'un nom de champ valide
    ' nbre sera zéro. Très mauvais pour la suite.
    nbre = Application.CountIf(.Columns(1), entete)
   
    ' Le dimensionnement du tableau ne sera valide que si dercol > 1 et nbr > 0
    ' Au vu de ce qui précède il y a  risque d'erreur ici aussi
    ReDim tablo(dercol - 1, nbre)
   
    ' En posant le compte initial à 1 on suppose que la première colonne cible est 1
    ' ce qui dans ce classeur est faux. La première colonne cible valide est la colonne 47 (AU).
    ' Les choses s'enveniment.
    For cptr = 1 To dercol
        ' Quelle valeur portera ici la variable entete lors du premier tour de boucle?
        ' La chaîne de caractères de la cellule A3!
        ' Et dans ce classeur qu'y a-t-il en cellule A3 feuille Récap? Rien! Une chaîne vide plus précisément.
        ' Oh! Nous courrons à la catastrophe.
        entete = Sheets("récap").Cells(3, cptr)
       
        lig = 1
        donnee = 1
       
        ' Ici la variable cptr_donn arrive de nulle part. Par défaut une variable est créée.
        ' Il aurait fallu poser une directive Option Explicit au module. Pour l'instant passons.
       
        ' Il se peut que nbre soit zéro et donc que la boucle ne s'exécute pas.
        For cptr_donn = 1 To nbre
            ' Et si par hasard entete est vide, que ce passera-t-il?
            ' Oui, Badaboum!
'            lig = .Columns(1).Find(entete, .Cells(lig, 2)).Row
           
            ' Comme la variable de boucle initiale a été posée à 1, contrairement au code original,
            ' cptr - 1 = 0. Ennuyeux puisque la directive Option Base 1 a été posée.
            ' Conséquence : il n'y a pas d'index 0 dans la première dimension du tableau.
            ' Re-Badaboum! Erreur d'exécution 9, L'indice n'appartient pas à la sélection.
            tablo(cptr - 1, donnee) = Replace(.Cells(lig, 3), "-", 0)
            donnee = donnee + 1
        Next
    Next
End With

Application.ScreenUpdating = False
With Sheets("récap")
    .Range("AU8").Resize(nbre, dercol - 1) = Application.Transpose(tablo)
    .Activate
End With


End Sub

 
La copie de cette procédure prévue pour un classeur spécifique Recap.xls pose de très nombreux problèmes dans le classeur Recap2(2).xls et constitue pour ce dernier une assise sablonneuse.

La lecture des commentaires dans le code devrait te guider dans la réécriture de celui-ci.
Et aussi la lecture de Formation Excel - VBA Débutant est indiquée.

Cordialement,

Guy