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 colonneAttention, 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 :
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 FunctionDans :
Public Type DataColumnsVous ajoutez vos noms de colonnes
Dans :
Public Function GetDataColumnNames( _
) As DataColumnsVous 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 ListObjectVous 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 :
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 Submerci 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 WithSalut à 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.
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 :
@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 Withpourquoi => 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 Withsurtout, 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 Functionje 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.
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:
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
