Remplacer = Sheets("2014").Cells(Target.Row, 5)

bonjour a tous,

je débute dans les macros.

je fais beaucoup d'excell et j'utilise énormement les nom tableau dans mes calculs.

je modifie aussi toujours les strutures des tableaux (ordre des colonnes). mais comme toutes mes formules font référence à des matrices, cela n'a aucun impacte!

dans une feuille excell, je récupère les datas de nom de personne titre et mail pour alimenter oulook et cree des contcat et mail.

je voudrais changer la formule

.FirstName = Sheets("2014").Cells(Target.Row, 5)

par .FirstName = Sheets("2014"). par le nom de la colonne du tableau

un genre de .FirstName = Sheets("2014").Cells(nom_peronne)

suis-je clair??

merci beaucoup de votre aide

Bonjour et bienvenue sur le forum,

Bizarre... on dirait que vous travaillez "à l'envers". Dans Excel les tableaux sont structurés ainsi : Chaque colonne est un type de donnée (commune à chaque élément) et chaque ligne un élément. En d'autres termes vos "titres" sont toujours à l'horizontale, et vous ajoutez des lignes, pas des colonnes.

Maintenant pour répondre à votre question : pour accéder à une colonne d'un ListObject (tableau structuré) à partir de son en-tête, vous pouvez utiliser sa propriété ListColumns, qui permet d'accéder à la colonne à partir de son index ou son titre.

Donc :

Sheets("2014").Range("monTableau").ListObject.ListColumns("mon titre de colonne")  '.DataBodyRange pour récupérer la range de la colonne

Attention, vous récupérez alors toute la colonne. Pour récupérer une ligne spécifique, faites comme ceci :

Sheets("2014").Range("monTableau").ListObject.ListColumns("mon titre de colonne").DataBodyRange.Cells(monNumeroDeLigne)

Bien entendu, il est pratique d'enregistrer certaines étapes dans des variables pour ne pas avoir à taper tout cela.

Et pour Aller un peu plus loin, je vous recommande d'utiliser un module Factory, c'est dans ce module que vous pourrez gérez le nom des colonnes.

Soit Par exemple avec des constantes :

'------------------------ CONSTANTES TABLEAU ARTICLES
Public Const ARTICLES_ID As String = "ID"
Public Const ARTICLES_ID_MENU As String = "Id Menu"
Public Const ARTICLES_CONTROLE As String = "Contrôle"
Public Const ARTICLES_ID_ARTICLE As String = "ID Article"
Public Const ARTICLES_QUANTITY As String = "Quantité"

Que vous pourrez appelez dans votre code :

image

Soit en allant encore un peu plus loin :

'@Folder "System"
Option Explicit

Public Type DataColumns
    ID As String
    Name As String
    Address As String
    City As String
    'Try other....
End Type

'@Description "Retourne un objet ListObject s'il existe sinon retourne Nothing"
Private Function getListObject( _
        ByVal ListName As String, _
        Optional ByVal Workbook As Excel.Workbook _
        ) As Excel.ListObject

    Dim localWorkbook As Excel.Workbook
    Set localWorkbook = Workbook
    If localWorkbook Is Nothing Then Set localWorkbook = ThisWorkbook

    With localWorkbook
        Do
            Dim CounterSheets As Integer
            CounterSheets = CounterSheets + 1
            Dim CounterListObjects As Integer: CounterListObjects = 0
            With .Worksheets(CounterSheets)
                Do While CounterListObjects < .ListObjects.Count And getListObject Is Nothing
                    CounterListObjects = CounterListObjects + 1
                    If StrComp(ListName, .ListObjects(CounterListObjects).Name, vbTextCompare) = 0 Then Set getListObject = .ListObjects(CounterListObjects)
                Loop
            End With
        Loop While CounterSheets < .Worksheets.Count And getListObject Is Nothing
    End With
End Function

'@Description "Initialise le tableau des données de base."
Public Function InitTabData( _
       Optional ByVal Reset As Boolean _
       ) As ListObject

    Static item As ListObject
    If item Is Nothing Or Reset Then
        Set item = getListObject("vt_Data")
    End If
    Set InitTabData = item
End Function

'@Description "Retourne les noms de colonnes pour le tableau Data."
Public Function GetDataColumnNames( _
       ) As DataColumns

    Dim Columns As DataColumns
    With Columns
        .ID = "ID"
        .Name = "Nom"
        .Address = "Adresse"
        .City = "Ville"
    End With

    GetDataColumnNames = Columns
End Function

Dans :

Public Type DataColumns

Vous ajoutez vos noms de colonnes

Dans :

Public Function GetDataColumnNames( _
       ) As DataColumns

Vous renseignez le nom exact des colonnes par exemple DataColumns.ID sera égal à "Index du client" ect.

Dans :

Public Function InitTabData( _
       Optional ByVal Reset As Boolean _
       ) As ListObject

Vous adaptez la ligne :

Set item = getListObject("vt_Data")

Avec le nom de votre tableau de données.

Ensuite vous n'avez plus qu' a suivre l'intellisense :

image image

Vous remarquerez que dans le code secondaire rien n'est noté en dur, si vous devez pour X raisons que ce soit changer le noms des colonnes ou du tableau vous ne le faite que dans le module Factory (Ici Factory1 pour l'exemple).

Public Sub Tests105()
    Dim maPlage As Excel.Range
    Set maPlage = Factory1.InitTabData.ListColumns(Factory1.GetDataColumnNames.Name).DataBodyRange
End Sub

merci a vous deux...

la franchement, il me faut du temps pour comment comment cela fontionne et comment on l'intègre.

@sabot1267,
je ne sais pas si je travail à l'envers => certainement et sans aucun doute.
en fait, c'est une table excell ou je reprends les infos et par un simple double click sur une ligne, il ouvre un "contact" et intègre les info dans outlook.

voici le code que j'ai fait moi !! donc bricolette qui fait sa cabane au fond du jardin

Dim objOutlook As Outlook.Application
Dim objContact As ContactItem

'Crée l'instance Outlook
Set objOutlook = New Outlook.Application
'Crée un élément pour les contacts
Set objContact = objOutlook.CreateItem(olContactItem)

With objContact
.Title = Sheets("2014").Cells(Target.Row, 4)
.FirstName = Sheets("2014").Cells(Target.Row, 5) 'Si le prénom se trouve en colonne 2
.LastName = Sheets("2014").Cells(Target.Row, 6) 'Si le nom se trouve en colonne 3
.Email1Address = Sheets("2014").Cells(Target.Row, 7) 'Si l'addresse email se trouve en colonne 1

.CompanyName = Sheets("2014").Cells(Target.Row, 2) 'Si l'addresse email se trouve en colonne 1
.JobTitle = Sheets("2014").Cells(Target.Row, 3)

.BusinessTelephoneNumber = Sheets("2014").Cells(Target.Row, 8)

.BusinessAddressStreet = Sheets("2014").Cells(Target.Row, 9)
.BusinessAddressCity = Sheets("2014").Cells(Target.Row, 10)

.BusinessAddressState = Sheets("2014").Cells(Target.Row, 11)

.BusinessAddressPostalCode = Sheets("2014").Cells(Target.Row, 12)

.BusinessAddressCountry = Sheets("2014").Cells(Target.Row, 13)

@jean-paul.
cette solution à l'ai vachement bien. on coihit tout mais cela est vachement trop compliqué pour moi.
je en serais jamais deguuguer un truc pareil.
mon niveau n'est même pas débutant !!
mais c''est genial car on peux choisir les colonnes....
si j'ai bien compris le truc c'est "--- constante tableau qui déclare les variables.
il faut vraiment que je creuse.

Bonjour,

Pour qu'on puisse vous accompagner dans l'établissement d'une solution plus concrète, il faudrait que vous joigniez le fichier sur lequel vous travaillez. Ce qui compte surtout est ce tableau depuis lequel vous tirez vos données (tout ce que n'utilise pas la macro vous pouvez le retirer). De même, si il y a des infos sensibles anonymisez-les.

A partir de là on verra comment vous aider/guider. Je pense qu'une solution hybride qui intègre les conseils de Jean-Paul (salut !) tout en restant simple à utiliser pourrait vous convenir (sauvegarder les en-têtes dans des constantes/enum/dict...). Mais pour cela, il faut du concret !

Dans l'attente de votre fichier.

autre méthode

Dim objOutlook As Outlook.Application
     Dim objContact As ContactItem
     Dim LO, r

     Set LO = Me.Range("TableauX").ListObject     'votre tableau structuré se trouve dans la même feuille !!!!!!!!
     r = target.Row - LO.Range.Row

     'Crée l'instance Outlook
     Set objOutlook = New Outlook.Application
     'Crée un élément pour les contacts
     Set objContact = objOutlook.CreateItem(olContactItem)

     With objContact
          .Title = LO.ListColumns("Title").DataBodyRange.Cells(r, 1).Value2
          .FirstName = LO.ListColumns("Prenom").DataBodyRange.Cells(r, 1).Value2     'Si le prénom se trouve en colonne 2
          .LastName = LO.ListColumns("Nom").DataBodyRange.Cells(r, 1).Value2     'Si le nom se trouve en colonne 3
          .Email1Address = LO.ListColumns("Emailadresse").DataBodyRange.Cells(r, 1).Value2

          .CompanyName = LO.ListColumns("Company").DataBodyRange.Cells(r, 1).Value2     'Si l'addresse email se trouve en colonne 1

          'etc
     End With

Salut à tous,

Puisqu'il dit faire des mouvements sur l'ordre des colonnes un ligne basée sur un index de colonne ne pourras jamais faire l'affaire, il faut travailler avec le nom de colonne.

comment j'ajoute, le drag and drop ne fonctionne pas

Comme @saboh l'a si bien dit. Fournissez un fichier pour avoir toute l'aide disponible.

comment j'ajoute, le drag and drop ne fonctionne pas

Quand vous écrivez un message,

image

je ne l'avais pas trouvé désolé....

re, voir mon poste de 15:46

@Jean-Paul, votre "factory", il est intéressant dans l'éditeur VBA pour son intellisense ou il a encore des autres avantages ?

@jean-paul j'aimerais avoir un explication de texte, une discutions avec vous pour beaucoup plus d'explication....

Bonjour à tous,

@BsAlv, La plus importante à mon avis c'est la déclaration des tableaux à un seul endroit cela évite les fautes de frappes et simplifie le code; Exemple :

Public Sub Test105()
    ' Ici on initialise le tableau
    Dim Table As Excel.ListObject
    Set Table = Factory.InitTabData                         ' // Initialisation du tableu "vt_Data".
    With Table
        '...
        '...
    End With

    ' // On peut travailler directement avec une ligne du tableau.
    Dim newRow As Excel.ListRow
    Set newRow = Factory.InitTabData.ListRows.Count
    With newRow
        .Range(.Parent.ListColumns(Factory.GetDataColumnNames.Qso_Notes).Index).value = "Nouvelle valeur"
        '...
        '...
    End With
End Sub

@jean-paul j'aimerais avoir un explication de texte, une discutions avec vous pour beaucoup plus d'explication....

Dites-moi ce qui vous interpelle je me ferais un plaisir d'y répondre.

Je suis sur le point de finaliser une classe pour la gestion des tableaux structurés. je la partagerais une fois finie.

Voici une partie des fonctions et méthodes disponibles :

image

@jean paul j'ai envie de dire tous!!

il fait peur le code...

je regarde plus profondément. et je reviendrais vers vous.

Je suis sur le point de finaliser une classe pour la gestion des tableaux structurés. je la partagerais une fois finie.

je prends...

bonjour a vous,

mauvaise nouvelle pour vous tous, je veux comprendre comment cela fonctionne!! mon objectif est d'abord de comprendre pour mieux le réutiliser dans d'autre cas.

je lis et relis les post et il y a telement de chose inintéressante....et obscure pour moi.

je reprends le sujet depuis une page blanche...

j'adore, et donc je prends et batir, =>

le nom du tableau => mis nom contact.

les constante de tableau... => je pars sur deux le nom et premon (une fois que cela fonctionnera dessus, je mettrais tous les autre champs

j'aime bâtir en mode "brick lego" => je peux annoter , comprendre et surtout reprendre et reutiliser dans le temps....

@jean-paul

Public Sub Test105()
' Ici on initialise le tableau
    Dim Table As Excel.ListObject
    Set Table = Factory.InitTabData                         ' // Initialisation du tableu "vt_Data".
    With Table
        '...
        '...
    End With

pourquoi => public sub test 105()

est-ce que l'on peux nome des sub? si l'on met des nom dans les parenthese cela donne quoi => sub( creation tableau contact) ??

je ne comprends pas le liens

Set Table = Factory.InitTabData                         ' // Initialisation du tableu "vt_Data".

le "vt_data => c'est dans excel? le nom du tableau?

with table =>

' les nom des colonne dans excell => donc

With Table
        prenom
        nom
    End With

surtout, comment je vois ce que cela donne entre le code macro et ce que cela donne dans excell/outlook, exct...

je vous souhaite bon courage..

Bonjour,

Si je peux me permettre un conseil, ne pas mettre la charrue avant les bœufs. Vous trouverez la réponse à beaucoup de vos questions en suivant ce Cours VBA gratuit.

Questions 1 & 2 notamment : Cours VBA : les procédures et fonctions

oui c'est vrai sans aucun doute....

je vais regarder cela....

je vous tiens au courant.

Bonjour à tous,

pourquoi => public sub test 105()

C'est tout simplement une petite habitude quand je propose un code en test je le mets dans une procédure qui se nome TestXXX, il est évident que l'on peut changer le nom, c'est même recomandé. (Mettre des noms explicites)

si l'on met des nom dans les parenthese cela donne quoi => sub( creation tableau contact) ??

Cela devient des argument de la procédure ou fonction. Exemple :

Public Function MultiplicationResult(Byval Arg1 As Double, Byval Arg2 As Double) As Double
    MultiplicationResult = Arg1 * Arg2
End Function

je ne comprends pas le liens

Set Table = Factory.InitTabData                         ' // Initialisation du tableu "vt_Data".

Ce n'est pas un lien c'est une affectation

  • Set c'est pour l'initialisation d'une variable Objet
  • Table c'est le nom de la variable
  • Factory c'est le nom du module ou je vais chercher InitTabData
  • IniTabData c'est le nom de la fonction (celle-ci retourne si elle le trouve un ListObjet)

Cela permet de ne déclarer le ListObjet que dans un seul endroit (Si vous changer le nom du tableau, vous ne le changer que dans le module Factory)

le "vt_data => c'est dans excel? le nom du tableau?

Exact, vous lui donner le nom que vous voulez (Changer-le aussi dans le module Factory)

with table =>

' les nom des colonne dans excell => donc

C'est presque cela...
Vous travailler avec table qui est un ListObjet donc quand vous faite Whith End With vous aurez accès aux propriétés et méthode de ce ListObjet.

image

Pour le nom des colonnes c'est un peu plus dur, soit vous passer l'index de la colonne directement exemple ici ligne peut-être une ligne spécifique du tableau:

image

Je ne le conseille pas car sur un tableau structuré nous pouvons changer les colonnes de place, 3 n'est pas très explicite non plus...

Je conseille de passer par le nom de la colonne et au lieu de la noter en dur prévoir soit une constante toujours dans le module Factory ou autre par exemple 'PublicConstants'

Et pour l'appel vous passer directement avec le nom de la constante

image
Rechercher des sujets similaires à "remplacer sheets 2014 target row"