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

  1. #1
    Candidat au Club
    Copier coller depuis Access 365 vers Outlook 365
    D'abord, je souhaite à tous un 20/20 pour cette année... ("jeu de mot" de de copains profs ).

    Ensuite, mon petit souci : je gère un fichier sous Access, et on me demande de réaliser des mailings via Outlook 365 à partir de sélections réalisées sur Access.
    Pas de souci pour les requêtes et les sélections d'adresses email, et la création d'un état de contrôle comportant la liste des emails des destinataires.

    Problème pour la suite : ma macro comprend bien la commande "SelectionnerTousLesEnregistrements" (elle le fait), mais :
    - je ne trouve pas de commande pour "copier",
    - si je copie "à la main", lorsque je "colle" dans le champ "cci" du mail Outlook, le presse-papier me colle aussi le nom du champ, ce que Outlook apprécie moyennement.

    Voilà. Ce n'est pas très grave ; au pire, mes utilisateurs sont capables de comprendre qu'il faut copier/coller à la main, puis, retirer le nom du champ dans la zone "cci" d'Outlook, mais ce n'est pas très propre, non ?

    J'ai évidemment cherché partout avant de poser ma question, mais je ne maîtrise pas VBA, et à peine les macros Access (et encore).

    Merci pour votre aide.
    Arsène.

  2. #2
    Candidat au Club
    Petit à petit, l'oiseau fait son nid
    Faute de mieux (du genre "solution toute prête gentiment offerte par un amical contributeur"), je m'y suis collé (c'est le cas de le dire).
    Donc, quelques ligne de code pour réussir la première étape, c'est à dire une variable string contenant les emails sélectionnés par la requête ad hoc séparés par des point virgule (ci-dessous, et merci à celui que j'ai plagié).
    Mais : je ne sais pas récupérer ma variable inListe pour coller son contenu dans le champ ccc d'Outlook.
    Je continue à chercher, mais le temps commence à presser (et ma femme à s'agacer).

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Public Sub TransposePourOutlook()
    Dim oDB As DAO.Database
    Dim inListe As String
    Dim Email1 As DAO.Recordset
    Set oDB = CurrentDb
    Set Email1 = oDB.OpenRecordset("SELECT [Adresse de messagerie] FROM Sélection")
    inListe = ""
    While Not Email1.EOF
        inListe = inListe & Email1.Fields("Adresse de messagerie") & "; "
        Email1.MoveNext
    Wend
    inListe = Left(inListe, Len(inListe) - 2)
    MsgBox inListe
    End Sub

  3. #3
    Membre expert
    Salut
    Si ce n'est que pour faire copier/coller
    Dans un module, à copier
    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
    Public Function ListAdsEmail() As String
    Dim dbs As Database
    Dim rst As Recordset
    Dim strListAdsEmail As String
     
    Set dbs = CurrentDb
    Set rst = dbs.OpenRecordset("SELECT emailto_emp FROM tbl_emp") 'modifier nom du champ et de la tbl
    If rst.RecordCount > 0 Then
        rst.MoveFirst
        Do Until rst.EOF
            If Not IsNull(rst!emailto_emp) Then
                strListAdsEmail = strListAdsEmail & rst!emailto_emp & "; "
                rst.MoveNext
            Else
                rst.MoveNext
            End If
        Loop
    End If
    ListAdsEmail = strListAdsEmail
    End Function

    Créer une req, à copier
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    SELECT ListAdsEmail() AS MaListAds;

    Exécuter la req

  4. #4
    Candidat au Club
    Merci Hypérion13 : ça fonctionne.
    Merci Hypérion13 : ça fonctionne.

  5. #5
    Candidat au Club
    Et maintenant, avec une requête (et non plus sur la table)
    Bonjour,

    Mon problème se complique :

    - La solution d'Hypérion13 est parfaite si on fait référence à une table, mais VBA s'embrouille si j'indique le nom d'une requête à la place du nom d'une table (après dbs.OpenRecordset).
    Je ne peux même pas insérer le code SQL correspondant, beaucoup trop long.

    - Et de plus, le résultat de la fonction ne peut pas être collé en l'état dans un champ Cci d'Outlook : la liste commence par le nom de la variable.

    Comment faire ?

    Merci pour votre aide.

  6. #6
    Rédacteur/Modérateur

    Bonsoir,

    Vous pouvez le faire en VBA en utilisant l'automation :

    https://access.developpez.com/faq/?page=Outlook#outlook

    En affectant le résultat de votre liste à la propriété BCC ou CC de l'e-mail :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    oEmail.BCC = ListAdsEmail()


    Cdlt,
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information en abondance, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON


    Quand on a la tête dans le guidon,...

  7. #7
    Candidat au Club
    Reste le premier souci : faire référence au résultat d'une requête et non à la table source elle-même
    Merci "User" : je n'ai pas encore pu regarder la solution "automation" pour Outlook ; je vais voir si on peut étendre la méthode à d'autres logiciels de messagerie (certains de mes utilisateurs sont accros au WebMail, et ils aimeraient que je leur propose une solution comparable à un simple copié/collé).

    Mais je butte d'abord sur la première question : comment modifier mon module pour extraire ma liste à partir d'une requête, et non pas de la table source ?

    Merci pour votre aide,
    Arsène.

  8. #8
    Membre confirmé
    Salut, perso je pilote outlook 365 via une procedure VBA access2010.
    je crée mon mail, j'y insere mes destinataires, mes pieces jointes,etc le tout en VBA.
    Cela fonctionne tres bien en client "lourd" ... apres en Webmail je ne vois pas.. apres copier la liste de destinataires dans le presse papier et de la coller manuellement dans ton navigateur (webmail).
    ++

  9. #9
    Expert éminent sénior
    bonjour,
    - La solution d'Hypérion13 est parfaite si on fait référence à une table, mais VBA s'embrouille si j'indique le nom d'une requête à la place du nom d'une table (après dbs.OpenRecordset).
    Je ne peux même pas insérer le code SQL correspondant, beaucoup trop long.
    VBA ne s'embrouille pas, il ne fait que signaler si la syntaxe n'est pas respectée ...
    Si c'est une requête enregistrée, il suffit de mettre le nom:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    Set rst = dbs.OpenRecordset("Nomdelarequete")
    Quand on est derrière l'écran on n'a aucun clavier sous les mains ...

  10. #10
    Rédacteur/Modérateur

    Bonjour,

    Je ne peux même pas insérer le code SQL correspondant, beaucoup trop long.

    - Et de plus, le résultat de la fonction ne peut pas être collé en l'état dans un champ Cci d'Outlook : la liste commence par le nom de la variable.
    Pouvez-vous nous montrez comment vous composez le code SQL de votre requête qui plante ?

    Cdlt
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information en abondance, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON


    Quand on a la tête dans le guidon,...

  11. #11
    Candidat au Club
    Merci James68
    J'ai bien vu la procédure d'automation permettant de piloter Outlook, mais j'aimerais offrir la possibilité alternative (pour du Webmail) d'un simple "copié/collé) ; et là, la bât blesse un peu, puisque je copie/colle aussi le nom de la liste, en plus des adresses mail.
    Bon, c'est pas dramatique, mais ça agace.
    Cdt;

  12. #12
    Candidat au Club
    Merci Tee-Grandbois
    C'est bien la syntaxe que j'utilise, mais qui génère un message d'erreur d'éxécution "3061" "Trop peu de paramètres. 39 attendu".
    Effectivement ma requête (qui fonctionne bien par ailleurs), comprend 39 conditions.
    Je la reproduis ci-dessous en réponse à une autre contribution.
    Cdt.

  13. #13
    Candidat au Club
    Merci User
    Voilà la requête en question, opérationnelle en direct sous Access, rebelle en VBA (message d'erreur reproduit ci-dessus).

    Code SQL :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT Fichier.Nom, Fichier.Prénom, Fichier.[Adresse de messagerie]
    FROM Fichier
    WHERE (((Fichier.[G1)=[Formulaires]![Mailing]![G1]))
    OR (((Fichier.[G2])=[Formulaires]![Mailing]![G2))
    OR (((Fichier.[G3])=[Formulaires]![Mailing]![G3]))
    OR 
     
    Etc etc.
     
    ));


    Cdt.

  14. #14
    Expert éminent sénior
    bonjour
    C'est bien la syntaxe que j'utilise, mais qui génère un message d'erreur d'éxécution "3061" "Trop peu de paramètres. 39 attendu".
    Effectivement ma requête (qui fonctionne bien par ailleurs), comprend 39 conditions.
    il n'était pas précisé que c'était une requête paramétrée avec des champs de formulaire. Ce n'est, en effet, pas possible d'ouvrir un RecordSet avec une requête contenant des paramètres venant de contrôles de formulaire.
    Il faut passer par la définition de requête (QueryDef) avant d'ouvrir le RecordSet comme dans cet exemple:
    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
    Dim i As Integer 
    Dim oQryDef As DAO.QueryDef
    Dim oRst As Recordset
    Dim oDb As Database
    Set oDb = CurrentDb
    ' chargement de la définition de la requête
    Set oQryDef = oDb.QueryDefs("NomdeLaRequete")
     
    ' chargement des paramètres nommés
    For i = 0 To oQryDef.Parameters.Count - 1
        oQryDef.Parameters(i).Value = [Forms].[Mailing].Controls("G" & i + 1) ' pour autant que les contrôles du formulaire se nomment G1 à G39
    Next
     
    ' chargement du Recordset
    Set oRst = oQryDef.OpenRecordset()
    ' on peut enfin utiliser le recordset normalement
    ' ...



    Juste une précision afin de pouvoir résoudre au mieux le problème : j'espère que le formulaire Mailing est déjà ouvert, car saisir les 39 paramètres à la main sans erreur risque de poser un gros souci
    Quand on est derrière l'écran on n'a aucun clavier sous les mains ...

  15. #15
    Candidat au Club
    N'est-il pas plus simple de passer par la création d'une table temporaire ?
    Merci beaucoup : je suis presque rassuré de savoir que ce n'était pas possible simplement.
    La solution élégante que vous suggérez ne peut hélas pas être mise en oeuvre : les champs n'ont pas de libellé permettant de renseigner le querydef aisément (j'hérite d'un fichier déjà conçu et déjà utilisé par ailleurs, qui ne peut plus être modifié dans sa structure).
    Je vais tenter de "contourner" la difficulté en ajoutant une étape : requête action pour créer une table, puis exécution de la fonction.
    Si ça fonctionne, il restera une petite difficulté agaçante : le copié/collé du résultat sans le nom de la variable... Si vous avez une idée...

    Cdt.

  16. #16
    Expert éminent sénior
    Merci beaucoup : je suis presque rassuré de savoir que ce n'était pas possible simplement.
    La solution élégante que vous suggérez ne peut hélas pas être mise en oeuvre : les champs n'ont pas de libellé permettant de renseigner le querydef aisément (j'hérite d'un fichier déjà conçu et déjà utilisé par ailleurs, qui ne peut plus être modifié dans sa structure).
    d'où viennent les paramètres de la requête alors ? cela veut-il dire que le formulaire Mailing n'est pas utilisé dans cette procédure ?
    Quand on est derrière l'écran on n'a aucun clavier sous les mains ...

  17. #17
    Candidat au Club
    Formulaire Mailing
    Non, effectivement, le formulaire "Mailing" n'est pas utilisé dans la fonction ; l'appel de la fonction se fait après que l'utilisateur a "coché" le ou les champs (G1, G2 etc) dans le formulaire "Mailing", et contrôlé que la sélection résultant de la requête "Sélection" correspond bien à son souhait.
    C'est après cette étape que la fonction VBA doit créer la liste des emails à copier/coller dans le champ Cci d'Outlook (ou ailleurs si l'utilisateur utilise un autre outil de messagerie).
    Cdt.

  18. #18
    Expert éminent sénior
    Non, effectivement, le formulaire "Mailing" n'est pas utilisé dans la fonction ; l'appel de la fonction se fait après que l'utilisateur a "coché" le ou les champs (G1, G2 etc) dans le formulaire "Mailing", et contrôlé que la sélection résultant de la requête "Sélection" correspond bien à son souhait.
    oui mais le formulaire Mailing reste ouvert sinon à quoi bon ?

    [EDIT]: j'ai parlé de procédure pas de fonction et je voulais plutôt parler de processus. Est-ce que la requête "Sélection" est ouverte dans un formulaire ou sous-formulaire ?
    Quand on est derrière l'écran on n'a aucun clavier sous les mains ...

  19. #19
    Expert éminent sénior
    - Et de plus, le résultat de la fonction ne peut pas être collé en l'état dans un champ Cci d'Outlook : la liste commence par le nom de la variable.

    Comment faire ?
    - première solution la plus simple (avec un contrôle dans ton formulaire Mailing qui devrait être ouvert) c'est de copier la liste directement dans le presse-papier avec la commande Copy:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    Me.LaListe.SetFocus
    DoCmd.RunCommand acCmdCopy
    MsgBox "la liste des destinataires est dans le presse-papier, prête à être collée."
    ensuite, il ne reste plus qu'à faire Ctrl+V dans Outlook (ou autre WebMail)

    - deuxième solution, à mettre à la fin de ta fonction TransposePourOutlook():
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ' avec la référence Microsoft Forms 2.0 Object Library cochée
    Dim oClipBd As MSForms.DataObject
    Set oClipBd = New MSForms.DataObject
     
    oClipBd.SetText inListe
    oClipBd.PutInClipboard
    Set oClipBd = Nothing
    MsgBox "la liste des destinataires est dans le presse-papier, prête à être collée."
    Quand on est derrière l'écran on n'a aucun clavier sous les mains ...

  20. #20
    Expert éminent sénior
    voici comment récupérer le Recordset du formulaire ou sous-formulaire ouvert dans ta fonction:
    (remplacer FormulairePrincipal par le nom du formulaire et SousFormulaire par le nom du sous-formulaire, si il y a lieu:
    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
    Public Sub TransposePourOutlook()
    Dim inListe As String
    Dim Email1 As DAO.Recordset
     
    ' Récupération du Recordset d'un formulaire
    Set Email1 = Forms.[FormulairePrincipal].RecordsetClone
     
    '------------------------------------
    ' ou bien si c'est un sous-formulaire:
    ' Récupération du Recordset d'un sous-formulaire
    'Set Email1 = Forms.[FormulairePrincipal].[SousFormulaire].Form.RecordsetClone
     
    ' création de la liste des destinataires
    If Email1.RecordCount > 0 Then
        Email1.MoveFirst
        Do Until Email1.EOF
            inListe = inListe & Email1.Fields("Adresse de messagerie") & "; "
            Email1.MoveNext
        Loop
    End If
    inListe = Left(inListe, Len(inListe) - 2)
     
    ' copie de la liste dans le presse-papier
    Dim oClipBd As MSForms.DataObject
    Set oClipBd = New MSForms.DataObject
     
    oClipBd.SetText inListe
    oClipBd.PutInClipboard
    Set oClipBd = Nothing
    Set Email1 = Nothing
    MsgBox "la liste des destinataires est dans le presse-papier, prête à être collée."
     
    End Sub
    Quand on est derrière l'écran on n'a aucun clavier sous les mains ...

###raw>template_hook.ano_emploi###