IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Excel Discussion :

ListObject : NumRow DataBodyRange Vs NumRow Feuille [XL-2010]


Sujet :

Excel

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 139
    Points : 124
    Points
    124
    Par défaut ListObject : NumRow DataBodyRange Vs NumRow Feuille
    bonjour,

    j'ai un problème de compréhension dans les ListObject lors d'une recherche de ligne.
    Exemple, de cette fonction qui est censé me renvoyer -1 si non trouvée, et autrement le numéro de ligne concernée pour travailler dessus.

    travail par la suite :
    - lecture
    - écriture

    le problème dans l'instant est :
    - lors d'une recherche pour écriture : semble fonctionner
    - lors d'une tentative de lecture pour affichage : il ne traite pas correctement la soustraction du numéro de l'entête, il pourrait être à l'origine de la difficulté selon moi.

    Comment si je dois utiliser le numéro de ligne en DataBodyRange ou le numéro de ligne de la feuille.
    Dans les 2 cas, quelle serait la requête nécessaire pour obtenir la bonne valeur...
    je suis perdu dans les différentes doc que j'ai pu lire dans ces 2 cas présents.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    '*
    '* fTrouveLigneDataBddAstreinte
    '* in : néant
    '* out : renvoit le numéro de ligne concerné en BDD, -1 si aucun élément trouvé
    '* recherche du n° de ligne en BDD.
    '************************************************************
    Function fTrouveLigneDataBddAstreinte() As Long
     
        Dim l_rwBdd As Long
     
        Dim lo_bddAstreinte As ListObject
        Dim lo_tabAstreinteDuJour As ListObject
     
        Set lo_tabAstreinteDuJour = Worksheets("Main Courante").ListObjects("t_AstreinteDuJour")
        Set lo_bddAstreinte = Worksheets("bdd_Astreinte").ListObjects("t_bddAstreinte")
     
        With lo_bddAstreinte
     
            Application.ScreenUpdating = False
     
            ' on supprime les éventuels filtres
            If .AutoFilter.FilterMode = True Then .AutoFilter.ShowAllData
     
            ' on tri par ordre croissant de date
            Tri_Table lo_bddAstreinte, 1
     
            ' filtre sur Date / période du jour actuel
            .Range.AutoFilter Field:=.ListColumns("Date").Index, _
                Criteria1:="=" & Format(d_DateDuJour, "dd/mm/yyyy"), Operator:=xlAnd
            .Range.AutoFilter Field:=.ListColumns("Periode").Index, _
                Criteria1:="=" & s_PeriodeGarde
     
     
            ' on test si un résultat a été trouvé
            If .AutoFilter.Range.Columns(1).SpecialCells(xlCellTypeVisible).Cells.Count > 1 Then
     
                l_rwBdd = .DataBodyRange.SpecialCells(xlCellTypeVisible).Row - .HeaderRowRange.Row
                fTrouveLigneDataBddAstreinte = l_rwBdd
     
            ' aucun résultat trouvé en BDD, renvoyer -1 pour gestion erreur et création si nécessaire
            Else
                MsgBox "Aucun résultat"
                fTrouveLigneDataBddAstreinte = -1
            End If
     
            Application.ScreenUpdating = True
     
        End With
    End Function
    pour ma part je l'utilise ainsi l_rwBdd est la variable re passée en paramètre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lo_tabAstreinteDuJour.DataBodyRange.Cells(1, 3).Value = lo_bddAstreinte.DataBodyRange.Cells(l_rwBdd, 3).Value
    Par avance merci de vos lumières éventuelles,

    Ronan

  2. #2
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Bonjour,

    Je ne suis pas entré dans le détail de ton code. Je réponds simplement eu titre de ton message. Pour trouver la ligne de la feuille correspondant à la ligne d'un tableau, utilise :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      With ActiveSheet.ListObjects(1)
        NumLigne = 5
        Ligne_Feuille = .ListRows(NumLigne).Range.Row
      End With
    Où "NumLigne" correspond à la ligne de données du tableau.
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Septembre 2013
    Messages
    783
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Septembre 2013
    Messages : 783
    Points : 1 562
    Points
    1 562
    Par défaut
    Bonjour,

    Ce code semble gérer des tableaux (listobject), donc on peut manipuler en particulier deux types de range: le complet (en-têtes comprises) ou les données uniquement (.databodyRange)

    En ligne 37, vous avez le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     l_rwBdd = .DataBodyRange.SpecialCells(xlCellTypeVisible).Row - .HeaderRowRange.Row
    Donc après, en écriture, soit vous retravaillez sur le même object, soit vous travaillez sur le range absolu de la sheet, suivant la correspondance indiquée par Daniel.C
    Ma suggestion: travaillez sur les tableaux, c'est beaucoup plus portable et facile.... et n'oubliez pas les Debug.Print pour vous aider

    Vincent
    "Idéalement nous sommes ce que nous pensons. Dans la réalité, nous sommes ce que nous accomplissons." A.Senna
    et n'oubliez-pas de développer des .... sourires ^_^

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 139
    Points : 124
    Points
    124
    Par défaut
    Bonjour merci de vos retours,
    Effectivement le debug.print est mon ami incontestable.

    Je n’arrive pas à savoir quand je suis en appel:
    - adresse (absolue)
    - databodyrange (relative)

    Exemple je filtre.
    J’obtiens une ligne en position 1 du databodyrange,
    ** en debug j’appel .address qui renvoi le range exacte.

    Ensuite je fais n’importe quoi .
    J’essaie de rappeler la ligne en question Avec le numéro renvoyé mais tableau filtre actif ou non, y a t il des choses à prendre en compte que je n’ai pas utilisé / pensé ??
    En effet parfois en débug je compte et je tombe avec entête comprise sans en-tête. Je ne comprends pas.

    Mon but serait effectivement de renvoyer la ligne concernée dans le databodyrange et ensuite je pense travailler dessus via cells comme je le fais mais... ça ne semble pas correct, peut être cells n’est pas le bon appel d’ailleurs..

    Question1 : est ce que ma méthode valeur renvoyée est la bonne?
    Question2 : comment travailler sur le bon element absolue / relatif ensuite ?

  5. #5
    Membre chevronné
    Homme Profil pro
    Inscrit en
    Septembre 2013
    Messages
    1 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2013
    Messages : 1 369
    Points : 2 156
    Points
    2 156
    Par défaut
    Bonsoir,

    Si on travaille avec le nom de tableau :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    LigneTableur = Range("Tableau1").Rows(LigneTableau).Row

    Boisgontier

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 364
    Points : 350
    Points
    350
    Par défaut
    Bonsoir
    Feuille et Tableau : syntaxe optimisée dans la simplicité (sans termes abscons) !
    Images attachées Images attachées  

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 139
    Points : 124
    Points
    124
    Par défaut
    bonsoir,

    après lecture de vos exemples et tests, voici le résultat.

    Nom : adresse_relative_absolue.jpg
Affichages : 2225
Taille : 302,0 Ko


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Option Explicit
     
    Private Sub CommandButton1_Click()
     
        Dim lo_bddAstreinte As ListObject
        Set lo_bddAstreinte = Worksheets("bdd_Astreinte").ListObjects("t_bddAstreinte")
     
        Worksheets("bdd_Astreinte").Range("F10").Value = "CDS10"
     
        MsgBox "Cellule F10" & Chr(10) _
        & "Adresse dans la feuille " & Worksheets("bdd_Astreinte").Range("F10").Address & Chr(10) _
        & "Adresse dans le tableu " & Cells(Worksheets("bdd_Astreinte").Range("F10").Row - [t_bddAstreinte].Row + 1, Worksheets("bdd_Astreinte").Range("F10").Column - [t_bddAstreinte].Column + 1).Address & Chr(10) & Chr(10) _
        & "Ligne dans la feuille " & Worksheets("bdd_Astreinte").Range("F10").Row & Chr(10) _
        & "Colonne dans la feuille " & Worksheets("bdd_Astreinte").Range("F10").Column & Chr(10) & Chr(10) _
        & "Ligne dans tableau " & Worksheets("bdd_Astreinte").Range("F10").Row - [t_bddAstreinte].Row + 1 & Chr(10) _
        & "Colonne dans tableau  " & Worksheets("bdd_Astreinte").Range("F10").Column - [t_bddAstreinte].Column + 1 & Chr(10) & Chr(10)
    End Sub
    voici comment le code a été écrit, 2 choses avec vos explications...

    je n'avais pas utilisé le Cells(......) sans passer par lo_bddAstreinte.DataBodyRange.Cells(.....) et encore moins combiné en VBA avec l'écriture [t_nomTableau].
    d'où mes confusions je pense.

    cette seconde écriture avec les tuto je l'ai utilisé en formule directement dans les cellules uniquement.
    J'ai vu plusieurs tuto, dont certains des tiens Jacques utilisant en VBA la méthode des crochets mais je trouvais peut être à tord et en ayant mal saisie le sens que définir un lo_ avec la feuille / nom tableau dès le début était plus pratique pour aussi le passer en paramètre au besoin. Ai je tords ? Pourquoi utiliser cet autre écriture ?

    Je vais tester l'extraction d'une donnée triée, puis la réutiliser par la suite, si cela est validé je classerais ce topic .

    merci pour vos retours

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 139
    Points : 124
    Points
    124
    Par défaut résolu
    Bonjour à vous,

    Ayant continué à travailler sur mon projet je propose ici une partie du code que j'utilise.

    j'ai crée un module ModuleListObject destiné uniquement à travailler sur les listobjects.

    un élément pas au point je pense est le set xx= nothing dans les function.
    Variable remise à nothing vraiment utile ou pas et le cas échéant, comment le faire sur Function.
    > Je pense possible que la variable soit utilisée via son adresse en mémoire donc le Set nothing du retour en sub/Function appelante supprimera l'élément de cette dite Function ??


    A bientôt,
    Ronan

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
     
    '  Module destiné à travailler sur les ListObject.
    '-----------------------------------------------------
    '
    ' fRechercherData : trouver un élément dans un listobject, renvoi un Range sinon Nothing
    '---
    ' fLoRelativeRow fLoRelativeColumn : renvoient la position de l'élément dans le listobject
    ' fLoAbsoluteRow fLoAbsoluteColumn :  renvoient la position de l'élément dans la feuille
    '---
    ' fLoRelativeAddress : renvoit l'adresse de l'élément dans le listobject
    ' fLoAbsoluteAddress : renvoit l'adresse de l'élément dans la feuille
    '---
    ' sDebugInfoDataLo : Affichage d'une MsgBox avec tous les appels pour visualiser rapidement une donnée (destiné au Debug)
    ' testfRechercherData : test pour exemple
     
    Option Explicit
     
    '*
    '*
    '**************************************************
    Public Function fRechercherData(s_Item As String, s_loTabName As String, s_loColID As String) As Range
     
        Dim r_Item As Range
     
        ' si erreur lors du code qui suivra on saute en gestion d'erreur
        On Error GoTo ErrorHandler
     
        ' recherche de l'élément dans le tableau
        Set r_Item = sheet_bdd.ListObjects(s_loTabName).ListColumns(s_loColID).DataBodyRange.Find(s_Item)
     
        ' on renvoit l'item trouvé sous forme de Range
        Set fRechercherData = r_Item
     
        'on sort de la fonction pour ne pas interférer avec la gestion d'erreur
        Exit Function
     
    ErrorHandler:
        Debug.Print "Description: " & Err.Description & Chr(10) & "numero: " & Err.Number, _
                vbCritical + vbOKOnly + vbDefaultButton2, _
                "Dans fRechercherData"
     
        ' sur erreur, aucun élément trouvé, on renvoit nothing
        Set fRechercherData = Nothing
     
    End Function
     
    '*
    '*
    '***********************************************************************
    Public Function fLoRelativeRow(r_Item As Range, s_loTabName As String) As Long
        ' si erreur lors du code qui suivra on saute en gestion d'erreur
        On Error GoTo ErrorHandler
     
        fLoRelativeRow = sheet_bdd.Range(r_Item.Address).Row - sheet_bdd.ListObjects(s_loTabName).DataBodyRange.Row + 1
     
        Exit Function
    ErrorHandler:
        Debug.Print "Description: " & Err.Description & Chr(10) & "numero: " & Err.Number, _
                vbCritical + vbOKOnly + vbDefaultButton2, _
                "Dans fLoRelativeRow"
        ' sur erreur, aucun élément trouvé, on renvoit -1
        fLoRelativeRow = -1
     
    End Function
     
    '*
    '*
    '***********************************************************************
    Public Function fLoAbsoluteRow(r_Item As Range, s_loTabName As String) As Long
        ' si erreur lors du code qui suivra on saute en gestion d'erreur
        On Error GoTo ErrorHandler
     
        fLoAbsoluteRow = sheet_bdd.Range(r_Item.Address).Row
     
        Exit Function
    ErrorHandler:
        Debug.Print "Description: " & Err.Description & Chr(10) & "numero: " & Err.Number, _
                vbCritical + vbOKOnly + vbDefaultButton2, _
                "Dans fLoAbsoluteRow"
        ' sur erreur, aucun élément trouvé, on renvoit -1
        fLoAbsoluteRow = -1
     
    End Function
     
    '*
    '*
    '***********************************************************************
    Public Function fLoRelativeColumn(r_Item As Range, s_loTabName As String) As Long
        ' si erreur lors du code qui suivra on saute en gestion d'erreur
        On Error GoTo ErrorHandler
     
        fLoRelativeColumn = sheet_bdd.Range(r_Item.Address).Column - sheet_bdd.ListObjects(s_loTabName).DataBodyRange.Column + 1
     
        Exit Function
    ErrorHandler:
        Debug.Print "Description: " & Err.Description & Chr(10) & "numero: " & Err.Number, _
                vbCritical + vbOKOnly + vbDefaultButton2, _
                "Dans fLoRelativeColumn"
        ' sur erreur, aucun élément trouvé, on renvoit -1
        fLoRelativeColumn = -1
     
    End Function
     
    '*
    '*
    '***********************************************************************
    Public Function fLoAbsoluteColumn(r_Item As Range, s_loTabName As String) As Long
        ' si erreur lors du code qui suivra on saute en gestion d'erreur
        On Error GoTo ErrorHandler
     
        fLoAbsoluteColumn = sheet_bdd.Range(r_Item.Address).Column
     
        Exit Function
    ErrorHandler:
        Debug.Print "Description: " & Err.Description & Chr(10) & "numero: " & Err.Number, _
                vbCritical + vbOKOnly + vbDefaultButton2, _
                "Dans fLoAbsoluteColumn"
        ' sur erreur, aucun élément trouvé, on renvoit -1
        fLoAbsoluteColumn = -1
     
    End Function
     
    '*
    '*
    '***********************************************************************
    Public Function fLoAbsoluteAddress(r_Item As Range, s_loTabName As String) As String
        ' si erreur lors du code qui suivra on saute en gestion d'erreur
        On Error GoTo ErrorHandler
     
        fLoAbsoluteAddress = sheet_bdd.Range(r_Item.Address).Address
     
     
        Exit Function
    ErrorHandler:
        Debug.Print "Description: " & Err.Description & Chr(10) & "numero: " & Err.Number, _
                vbCritical + vbOKOnly + vbDefaultButton2, _
                "Dans fLoAbsoluteAddress"
        ' sur erreur, aucun élément trouvé, on renvoit -1
        fLoAbsoluteAddress = ""
     
    End Function
     
    '*
    '*
    '***********************************************************************
    Public Function fLoRelativeAddress(r_Item As Range, s_loTabName As String) As String
        ' si erreur lors du code qui suivra on saute en gestion d'erreur
        On Error GoTo ErrorHandler
     
        fLoRelativeAddress = Cells((sheet_bdd.Range(r_Item.Address).Row - sheet_bdd.ListObjects(s_loTabName).DataBodyRange.Row + 1), (sheet_bdd.Range(r_Item.Address).Column - sheet_bdd.ListObjects(s_loTabName).DataBodyRange.Column + 1)).Address
        'fLoRelativeAddress = Cells(sheet_bdd.Range(r_Item.Address).Row - [t_bdd].Row + 1, sheet_bdd.Range(r_Item.Address).Column - [t_bdd].Column + 1).Address
     
        Exit Function
    ErrorHandler:
        Debug.Print "Description: " & Err.Description & Chr(10) & "numero: " & Err.Number, _
                vbCritical + vbOKOnly + vbDefaultButton2, _
                "Dans fLoRelativeAddress"
        ' sur erreur, aucun élément trouvé, on renvoit -1
        fLoRelativeAddress = ""
     
    End Function
     
    '*
    '*  Affichage en message popup pour debug et compréhension.
    '***************************************
    Public Sub sDebugInfoDataLo(r_Item As Range, s_loTabName As String)
     
           MsgBox "Inter n° " & r_Item.Value & Chr(10) _
            & "------------------" & Chr(10) _
            & "Absolute Adresse: " & fLoAbsoluteAddress(r_Item, "t_bdd") & Chr(10) _
            & "Relative Adresse: " & fLoRelativeAddress(r_Item, "t_bdd") & Chr(10) _
            & Chr(10) _
            & "Absolute Row : " & fLoAbsoluteRow(r_Item, "t_bdd") & Chr(10) _
            & "Relative Row : " & fLoRelativeRow(r_Item, "t_bdd") & Chr(10) _
            & Chr(10) _
            & "Absolute Col : " & fLoAbsoluteColumn(r_Item, "t_bdd") & Chr(10) _
            & "Relative Col : " & fLoRelativeColumn(r_Item, "t_bdd")
    End Sub
     
    '*
    '* test pour exemple utilisateur
    '*********************************
    Public Sub testfRechercherData()
     
        Dim r_Item As Range
     
        Set r_Item = fRechercherData("10", "t_bdd", "col_Numero")
     
        If Not r_Item Is Nothing Then
            sDebugInfoDataLo r_Item, "t_bdd"
        Else
            MsgBox "Aucun élément trouvé "
        End If
     
        Set r_Item = nothing
    End Sub

  9. #9
    Expert éminent sénior

    Profil pro
    Conseil, Formation, Développement - Indépendant
    Inscrit en
    Février 2010
    Messages
    8 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Conseil, Formation, Développement - Indépendant

    Informations forums :
    Inscription : Février 2010
    Messages : 8 419
    Points : 16 262
    Points
    16 262
    Par défaut
    Bonjour

    Comparer adresse dans la feuille et adresse dans le tableau avec une notation lettre pour la colonne prête à confusion et ne me parait pas une bonne approche.

    La cellule F10 est dans la 6eme colonne et la 10 ligne de la feuille mais dans la 5ème colonne ou colonne CDS et 8ème ligne du DataBodyRange du tableau.
    Chris
    PowerQuery existe depuis plus de 13 ans, est totalement intégré à Excel 2016 &+. Utilisez-le !

    Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson.
    Confucius

    ----------------------------------------------------------------------------------------------
    En cas de résolution, n'hésitez pas cliquer sur c'est toujours apprécié...

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 139
    Points : 124
    Points
    124
    Par défaut
    je n'utilise pas l'adressage complet format lettre/chiffre (col/ligne) pour le databodyrange.

    Comme me l'avait présenté OrDonc, j'ai aussi pour une forme de recherche et compréhension personnelle crée cette fonction.

    j'avoue par contre que cela porte à confusion d'où le nom absolute / relative dans le nom des appels.

    je l'ai laissée pour le forum dans le cas où quelqu'un pourrait en avoir besoin et se demande comment le réaliser

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 364
    Points : 350
    Points
    350
    Par défaut Des mots et des maux
    Bonjour !
    Citation Envoyé par WuKoDLaK Voir le message
    Comme me l'avait présenté OrDonc ...
    Pour rappel : une Table, un Tableau que d'aucun qualifie de structuré, est avant tout un objet (une collection) Range. Il est donc plus commode d'utiliser le vocabulaire classique, de base, pour éviter des phrases chargées de nouveaux mots (souvent longs et pas commodes à écrire)*.
    En reprenant ton exemple de recherche dans des tableaux dispersés dans le classeur, j'écrirais simplement
    Routine principale
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Sub cherche()
       Call Recherche(10, [ç1], 3, "ç1")
       Call Recherche("Chose", [ç2], 1, "ç2")
       Call Recherche("10", [ç2], 2, "ç2")
       Feuil2.Select 'juste pour voir
       Call Recherche("Truc", [ç3], 6, "ç3")
     End Sub
    Sous routine commune aux différents cas (dans un Module standard)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Sub Recherche(Quoi, T As Range, x As Long, nom As String)
      DimAs Range, L As Long, C As Long
      Dim T1 As String, T2 As String 'pour scinder le message
      Set là = T.Columns(x).Find(Quoi, MatchCase:=1)
      IfIs Nothing Then MsgBox Quoi & " est absent du tableau " & nom: Exit Sub
      là.Interior.Color = vbYellow 'pour mieux contrôler mais non indispensable
      L = là.Row - T.Row + 1: C = là.Column - T.Column + 1 'peuvent faire l'objet d'une autre petite sous-routine
      T1 = "est dans la ligne " & L & " et la colonne " & C & " du tableau " & nom
      T2 = "est dans la ligne " & là.Row & " et la colonne " & là.Column & " de la feuille"
      MsgBox T1 & vbLf & vbLf & T2, , Quoi & "..."
    End Sub
    Dans ton développement, il y a des variables qui sont mal définies, déclarées.
    Ici, dans
    Sub Recherche(Quoi, T As Range, x As Long, nom As String )
    - la variable Quoi correspond au mot ou nombre cherché donc de type Variant.
    - la variable T correspond à un tableau (ici, il y en a 2 dans la feuille 1, nommés respectivement ç1 et ç2 et 1 autre dans la feuille 2, nommé ç3. T est donc de type Range
    - la variable x est un nombre désignant un numéro de colonne (du tableau incriminé) donc de type Byte, Integer, … selon la taille des tableaux.
    - nom est le nom du tableau sélectionné donc de type String.

    Nota : un des nombreux avantages de tels tableaux est de n'avoir pas à se préoccuper de l'endroit où ils se trouvent (ligne, colonne et surtout onglet). On peut oublier de les référencer avec la feuille où ils ont été définis sans remords !
    J'ai gardé la fonction Find bien qu'elle ne soit pas bien adaptée pour des critères en doublons
    Si on en a besoin dans d'autres macros, on peut ajouter une petite sous routine pour la détermination de la ligne L et de la colonne C de la cellule d'un Tableau.

    Tu avais déjà posé la question concernant le vocabulaire. Cet exemple t'en donne une réponse.
    Le fond ne changeant pas, c'est à toi de voir quels mots, quelles expressions tu vas utiliser par la suite.

    *Je pense que beaucoup hésitent, hélas, hélas, hélas, à utiliser ces tableaux en croyant qu'il faille ingurgiter bon nombre d'appellations, de choses nouvelles - or ce n'est pas le cas !
    Je crois ne pas me tromper en disant que bien des utilisateurs pointus, même très pointus (dont je ne fais pas partie), ne connaissent et ne dominent qu'une partie des possibilités mises à notre disposition.
    Fichiers attachés Fichiers attachés

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 364
    Points : 350
    Points
    350
    Par défaut
    Re !
    Pour donner suite à une remarque qui m'a été faite dans une autre discussion, je n'exclus en aucune façon l'objet ListObject *.
    Je donnais simplement un exemple avec une syntaxe de base déjà acquise.
    En utilisant la propriété Name de l'objet, on peut simplifier les codes. Ici, ils seraient
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Sub cherche()
      Feuil1.Select                        'juste pour voir mais peut être inutile si le bouton qui y figure
      Call Recherche(10, [ç1], 3)
      Call Recherche("Chose", [ç2], 1)
      Call Recherche("10", [ç2], 2)
      Feuil2.Select                        'juste pour voir
      Call Recherche("Truc", [ç3], 6)
    End Sub
    Sub Recherche(Quoi, T As Range, x As Long)
      DimAs Range, L As Long, C As Long
      Dim Nom As String, T1 As String, T2 As String
      Nom = T.ListObject.Name               'nom du Tableau concerné (pas T.Name !)
      Set là = T.Columns(x).Find(Quoi, MatchCase:=1)
      IfIs Nothing Then MsgBox Quoi & " est absent du tableau " & Nom: Exit Sub
      là.Interior.Color = vbYellow                       'pour mieux contrôler
      L = là.Row - T.Row + 1: C = là.Column - T.Column + 1
      T1 = "est dans la ligne " & L & " et la colonne " & C & " du tableau " & Nom
      T2 = "est dans la ligne " & là.Row & " et la colonne " & là.Column & " de la feuille"
      MsgBox T1 & vbLf & vbLf & T2, , Quoi & "..."
    End Sub
    *une de mes sources d'apprentissage est ici

  13. #13
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 122
    Points : 55 921
    Points
    55 921
    Billets dans le blog
    131
    Par défaut
    Salut

    Puisque Ordonc m'y invite, je viens vous dire bonjour dans cette discussion, pour redire et affiner ce que j'ai dit dans l'autre. J'apporte simplement des précisions sur ce qu'à dit Ordonc et j'appuie certains de ces dires et en "critique" d'autres (Bien lire ma signature avant de poursuivre ...)

    Une table n'est pas un tableau! Une table est un tableau structuré. Et une table ou un tableau structuré, ce n'est pas un objet Range, c'est un objet ListObject, alors qu'un tableau (<> de table ou de tableau structuré) est un objet Range. Un objet ListObject expose différentes Range (.Range, .DataBodyRange, HeaderRowRange, InsertRowRange, TotalsRowRange). Mais un objet ListObject en tant que tel n'est pas un objet Range.

    Ainsi, dans l'illustration suivante, A1:C10 est un table (= tableau structuré) et peut donc être manipulé en VBA en tant qu'objet ListObject. F1:J6, par contre, n'est pas une table ou un tableau structuré, mais un tableau, et ne peut donc être considéré comme un Listobject, mais est un simple Range.

    Nom : 2019-01-13_102501.png
Affichages : 2145
Taille : 19,5 Ko



    Vouloir "simplifier" et ne pas utiliser de termes soi-disant abscons amène à une méprise entre gens de métier, ainsi qu'à des tentatives malheureuses au niveau du code (comme par exemple [Clients].Columns(1) donné ailleurs, car il y a ici confusion en plage nommée et tableau structuré, qui n'est pas une plage nommée . C'est pourquoi je suis si attentif à bien nommer les choses

    Si A1:C10 est le tableau structuré t_Choix, la plage A1:C10 correspond à la référence structurée t_Choix[#Tout] et à ListObject.Range. La plage A2:C10 correspond à la référence structurée t_Choix et à ListObject.DataBodyRange. Si une ligne de total était ajoutée au tableau structuré (je tiens à ce terme ), alors A1:C11 correspondrait la la référence structurée t_Choix[#Tout] et à ListObject.Range. Dès lors, Range("t_Choix") est un objet Range alors que Range("t_Choix").ListObject n'est pas un objet Range, mais un objet ListObject.

    Bien que les tableaux ne soient pas des plages nommées (ils n'appartiennent pas à la collection Names du classeur!), il est possible d'utiliser les références structurées en VBA. Si l'on considère le tableau structuré A1:C10 comme étant nommé t_Choix, on peut dire que A1:C10 est "nommé" t_Choix[#Tout] et A2:B10 t_Choix. Il est dès lors possible d'utiliser les Range correspondants en VBA, Range("t_Choix[#All]") pour ListObject.Range ou A1:C10 (ou A1:C11 si ligne de total) et Range("t_Choix") pour ListObject.databodyrange ou A2:C10.

    Dans la mesure ou l'utilisation des références structurées en VBA dispense de connaître l'emplacement du tableau structuré (feuille et place dans la feuille), on préfèrera les utiliser pour pointer vers le listobject correspondant. Ainsi, on utilisera avantageusement Set T = Range("t_Choix").ListObject pour récupérer le ListObject correspondant au tableau structuré t_Choix, puisque ce code fonctionnera même après déplacement du tableau sur une autre feuille, alors que Set T = SheetX.ListObjects("t_Choix") "verrouille" l'emplacement du tableau structuré sur une feuille précise.

    Comme cela a été dit par Chris, il n'est pas pertinent de "comparer" les adresses "Feuille" et "tableau structuré". L'utilisation des références structurées permettant de travailler en VBA en ne se souciant justement pas de la position du tableau dans la feuille, ni du nombre de lignes ou de colonnes de celui-ci. Le code VBA continue à fonctionner sur les bonnes références même si le tableau grandit, diminue, est déplacé sur la feuille ou sur une autre. Grâce aux tables (tableaux structurés) pour le stockage des données, on peut ainsi libérer le code VBA des recherches de limites des données, des plages nommées avec DECALER, etc... Par rapport aux version <=2003, c'est un gain extraordinaire de souplesse au niveau du code à produire.




    Au passage, avis personnel et donc subjectif, je n'aime pas du tout la notation [Clients] ou [A1]... (notamment parce qu'elle ne permet pas la saisie semi-automatique derrière, ne permettant dès lors pas d'obtenir la liste des méthodes/propriétés de l'objet, et/ou de bien comprendre que l'on utilise un Range).
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 139
    Points : 124
    Points
    124
    Par défaut
    Au passage, avis personnel et donc subjectif, je n'aime pas du tout la notation [Clients] ou [A1]... (notamment parce qu'elle ne permet pas la saisie semi-automatique derrière, ne permettant dès lors pas d'obtenir la liste des méthodes/propriétés de l'objet, et/ou de bien comprendre que l'on utilise un Range).
    c'est exactement pour cela que j'ai strictement basé mon code sur des notations vba sans appeler les listobjects via [t_tab] ma lecture et la compréhension du code s'en trouve vraiment améliorée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [PDO] Numrows & result
    Par Gaetan_ dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 15/02/2015, 17h11
  2. numRows : méthode inconnue
    Par Toulousaing dans le forum SQLite
    Réponses: 0
    Dernier message: 25/02/2013, 12h28
  3. [XL-2007] Insertion ligne dans un tableau (ListObject) sur feuille protégée
    Par Damran dans le forum Conception
    Réponses: 4
    Dernier message: 22/08/2012, 16h32
  4. [MySQL] problème avec $_SESSION[numrows]
    Par edwithenwisdom dans le forum PHP & Base de données
    Réponses: 13
    Dernier message: 27/04/2012, 08h56
  5. Réponses: 0
    Dernier message: 25/02/2008, 17h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo