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

VBA Access Discussion :

Envoyer les factures par mail


Sujet :

VBA Access

  1. #1
    Membre habitué Avatar de possible924
    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2010
    Messages : 302
    Points : 159
    Points
    159
    Par défaut Envoyer les factures par mail
    Bonjour à tous,
    J'ai une table contenant une liste de factures
    avec un champ "CléP_Facture", un champ "Email", un champ "Destinataire" et un champ "Commentaire"
    Je souhaite imprimer en PDF chaque facture et l'envoyer par messagerie électronique.
    Pouvez vous m'apporter votre aide pour résoudre ce problème,
    surtout sur la boucle pour envoyer chaque facture tour à tour ?
    Merci par avance pour votre aide
    Pierre

  2. #2
    Membre confirmé
    Inscrit en
    Février 2011
    Messages
    465
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 465
    Points : 549
    Points
    549
    Par défaut
    Bonjour,

    Si tu crées tes factures en pdf, pourquoi ne pas enregistrer le nom de fichier dans une table lors de chaque création. Pour te faciliter la vie, mets aussi une colonne avec l'adresse email dans cette table.
    Il te sera alors facile dans une autre Sub ou fonction de lire la table du début à la fin et d'envoyer chaque facture à l'adresse email et de déplacer la facture vers un Folder "archive" ou "emailed" pour éviter de l'envoyer deux fois.

    Une boucle se crée avec l'instruction Do...Loop
    Dans l'exemple que je te donne, j'ouvre un recordset puis je fais un Do où je dis "faire jusqu'à la fin du recordset".

    en pratique :
    J'ai créé une petite table :
    Nom : Capture.PNG
Affichages : 699
Taille : 12,5 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
    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
    Function liste_des_Factures()
    'dimensionner la base de données et le recordset en DAO.
    'DAO est le moteur de base de MS Access et VBA, c'est sans doute la définition la plus simple.
    Dim db As DAO.Database
    Dim rstFact As DAO.Recordset
    Dim strEmailAddress As String
    Dim strFactName As String
    Dim strPathAttachement As String
    Dim strStep As String
     
    'ne pas oublier l'instruction SET pour établir la connection avec ta table.  Il faut un SET pour la base de données et puis
    'un SET pour chaque recordset (table)
    Set db = CurrentDb
    Set rstFact = db.OpenRecordset("TBL_LISTE_FACTURES")
     
    'Je parcours ma table du début à la fin:
    Do Until rstFact.EOF
        'pour chaque enregistrement, je recupère le nom complet (avec chemin d'accès) du fichier et l'adresse email où la facture doit être envoyée
        strFactName = "C:\Compta\Factures\a_Envoyer\" & rstFact!FileName
        strPathAttachement = "C:\Compta\Factures\a_Envoyer\" & strFactName
        strEmailAddress = rstFact!email
        'J appelle une autre fonction VBA qui va m'envoyer l'email
        'Cette autre fonction VBA va me retourner une chaine de caractères (string) avec le résultat de l'envoi
        strStep = EnvoiEmail(strPathAttachement, strEmailAddress)
        If strStep = "OK" Then
            'L'email a été envoyé, je déplace le fichier vers un Folder d'archive pour eviter de l'envoyer 2 fois
            Name strPathAttachement As "C:\Compta\Factures\deja_Envoye\" & strFactName
        Else
            'Oula-la !  J'ai une erreur...
            MsgBox strStep, vbCritical, "erreur d'envoi d'email"
        End If
        'quand on parcourt un recordset, il faut toujours indiquer à VBA qu'il faut aller à la ligne suivante :
        rstFact.MoveNext
    Loop
    'et voila, ma boucle est bouclée.
     
    'libérer les pointeurs :
    Set rstFact = Nothing
    Set db = Nothing
     
    End Function
    Public Function EnvoiEmail(strPathAttachement, strEmailAddress) As String
     
    EnvoiEmail = "debut"
     
    'je prepare l'email
    'Si qqch coince
    EnvoiEmail = "STOP, il y a une erreur quelque part ...."
     
     
    'tout se passe bien
    EnvoiEmail = "OK"
     
    End Function

  3. #3
    Membre habitué Avatar de possible924
    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2010
    Messages : 302
    Points : 159
    Points
    159
    Par défaut Merci
    Merci pour ta réponse détaillée.
    Je n'ai pas encore repris le travail sur ce sujet, mais ta réponse doit pouvoir me permettre de régler le problème
    Bon week-end
    Pierre

  4. #4
    Membre habitué Avatar de possible924
    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2010
    Messages : 302
    Points : 159
    Points
    159
    Par défaut Me revoilà
    Je reprend le travail sur ce sujet
    J'ai eu une interruption d'activité pour cause de déménagement de la région parisienne vers le département du Var.

    Sur le problème de l'envoi des factures par messagerie électronique,
    je bute sur un premier problème qui est de générer autant de fichier pdf qu'il y a de factures.

    Dans la situation actuelle, les factures sont éditées en fin de mois et toutes ensemble
    Elles sont imprimées à partir d'un état Access qui comporte toutes les factures du mois
    et c'est à la mise sous enveloppe qu'elles sont adressées au destinataire,
    mais pour préparer l'envoi par messagerie, il faut que je génère un fichier pdf par facture

    Je dispose d'une requête qui comporte un identifiant unique de la facture à imprimer,
    mais je n'ai aucune idée comment faire en VBA.

    Les imprimantes pdf dont je dispose sont "Microsoft Print to PDF" et "PDFcreator"

    Merci de m'indiquer comment générer les fichiers pdf en VBA
    Pierre

  5. #5
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    À mon avis, il faut faire un peu de VBA et générer un fichier par facture.
    Le problème c'est que la génération de PDF ne t'offre pas la possibilité de filtrer la facture qui t'interesse.
    Personnellement je ferai (et je ne suis pas certain que cela marche mais cela me paraît prometteur).

    • un formulaire [frmFactureAImprime] avec un champ texte basé sur ta liste de facture à imprimer.
      un truc du genre :

      Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      select tblFacture.* from tblFacture 
          where
              tblFacture.[EstImprime]=false

      Je vais supposer qu'il y a un champ texte [NumFacture] et une case à cocher EstImprime.
      Un bouton avec le code suivant dans la procédure événementielle associée à l'événement sur click.

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      dim r as dao.recordset:set r=me.recordset
      r.movefirst
       
      '=== Parcourt toutes les factures affichées.
      do while not r.eof
         call docmd.OutputTo(acOutputReport, "rptUneFactureAImprimer", acformatPDF, "x:\TonChamin\" & r![NumFacture] & ".pdf") 'crée le pdf
         r.edit
         r![EstImprime]=true 'indique que le pdf a été créé
         r.update
         r.movenext : doevents
      loop
      '=== Parcourt toutes les factures affichées.
       
      set r=nothing
    • une requête qui va te donner une seule facture :
      Quelque chose comme :

      reqUneFactureAImprime
      Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      select tblFacture.* from tblFacture 
          where
              tblFacture.[EstImprime]=false
              tblFacture.[NumFacture]=[forms]![FrmFactureAImprime]![NumFacture]
    • Un état [rptUneFactureAImprimer] qui se base sur [reqUneFactureAImprime] et qui fait une facture.
      À priori c'est celui dont tu te sers actuellement, avec simplement une autre source.


    Tu ouvres le formulaire.
    Tu appuis sur le bouton.
    Access crée les X factures dans le répertoire.

    Éventuellement tu ajoutes la création des courriels à la boucle.
    Ici la FAQ à ce propos, le chemin et nom du fichier sont le 4ième paramètres de la fonction.
    HautPageComment envoyer un mail avec Outlook ?
    https://access.developpez.com/faq/?page=Outlook#outlook

    Passer par un formulaire avant de lancer te permet de valider la liste des factures et éventuellement d'en "cocher" certaines à la main pour qu'elle ne s'imprime pas.

    Note que savoir si la facture a bien été envoyée est sans doute possible mais que je ne sais pas le faire.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  6. #6
    Membre habitué Avatar de possible924
    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2010
    Messages : 302
    Points : 159
    Points
    159
    Par défaut
    Bonjour à tous
    merci pour vos réponses qui m'ont permis de bien progresser.
    J'ai un gros souci sur la ligne "DoCmd.OutputTo acOutputReport, "E_Facture", "PDFFormat(*.pdf)", Strfile, False, "", , acExportQualityScreen"

    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
    DoCmd.SetWarnings False
    Dim NbFactNoPrintPDF As Integer
    Dim FirstFactNuméro As Variant
    Dim Strfile As String
     
    Do
     
        NbFactNoPrintPDF = DCount("FeM_Facture_Imprimé_PDF", "T_Factures_envoi_Messagerie", "FeM_Facture_Imprimé_PDF = 0")
        Me.Test = NbFactNoPrintPDF
        FirstFactNuméro = DMin("FeM_Facture_Numéro", "T_Factures_envoi_Messagerie", "FeM_Facture_Imprimé_PDF = 0")
        Strfile = "W:\Bases\Iris\FacturesEnvoiMessagerie\" & DLookup("FeM_PDF_Nom", "T_Factures_Envoi_Messagerie", "FeM_Facture_Numéro =" & FirstFactNuméro)
        Dim qdf As DAO.QueryDef
            Set qdf = CurrentDb.QueryDefs!R_Factures_Etat
            qdf.SQL = "SELECT R_Factures.*, R_Facture_Contenu.* FROM R_Factures LEFT JOIN R_Facture_Contenu ON R_Factures.CléP_Facture = R_Facture_Contenu.FC_Clé_Facture " & _
                        "WHERE R_Factures.Fact_Numéro = " & FirstFactNuméro
            Set qdf = Nothing
        DoCmd.OutputTo acOutputReport, "E_Facture", "PDFFormat(*.pdf)", Strfile, False, "", , acExportQualityScreen
        DoCmd.RunSQL "UPDATE T_Factures_Envoi_Messagerie SET T_Factures_Envoi_Messagerie.FeM_Facture_Imprimé_PDF = -1 " & _
                        "WHERE T_Factures_Envoi_Messagerie.FeM_Facture_Numéro = " & FirstFactNuméro
     
    Loop Until NbFactNoPrintPDF = 1
    DoCmd.SetWarnings True
    Tout se passerait bien, sauf qu'à la 28ème facture imprimée en pdf, je reçois un message d'erreur :
    "Erreur d'exécution '2501'
    L'action OutputTo a été annulée"

    Pourquoi ? je n'en ai aucune idée !
    Merci par avance pour votre aide
    Pierre

  7. #7
    Membre éprouvé

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Novembre 2007
    Messages
    904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Novembre 2007
    Messages : 904
    Points : 1 229
    Points
    1 229
    Par défaut
    Bonjour

    28ème sur combien ?
    Vérifie l’évolution des valeurs des variables et champs dans la boucle.
    Un problème bien posé est à moitié résolu

  8. #8
    Modérateur

    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    15 331
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2005
    Messages : 15 331
    Points : 23 786
    Points
    23 786
    Par défaut
    Bonjour.

    Tout se passerait bien, sauf qu'à la 28ème facture imprimée en pdf, je reçois un message d'erreur :
    "Erreur d'exécution '2501'
    L'action OutputTo a été annulée"
    Vérifie qu'il y a bien des données pour cette facture.
    Cette erreur se produit sur les rapports quand Access ne trouve pas l'information demandée donc la cause est peut-être la même.

    Vérifie aussi que le fichier de sortie ne porte pas le nom d'un fichier existant.

    A+
    Vous voulez une réponse rapide et efficace à vos questions téchniques ?
    Ne les posez pas en message privé mais dans le forum, vous bénéficiez ainsi de la compétence et de la disponibilité de tous les contributeurs.
    Et aussi regardez dans la FAQ Access et les Tutoriaux Access. C'est plein de bonnes choses.

  9. #9
    Membre habitué Avatar de possible924
    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2010
    Messages : 302
    Points : 159
    Points
    159
    Par défaut
    Le système s'arrête à la 28ème facture sur 86, mais ce nombre de 86 est variable d'un mois sur l'autre.
    Toutes les factures ont un contenu
    Si un fichier porte le même nom dans le répertoire de destination, il est écrasé.
    J'ai fait de nombreux essais et j'ai effacé tous les fichiers contenu dans le répertoire de destination

    J'ai modifié le code de cette façon mais le résultat est toujours le même :
    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
    Private Sub EnvoyerAvec_Click()
    'On utilise le Numéro de facture et non pas CléP_Facture
    On Error GoTo Fin
    If Me.NbFactSélectionnées >= 1 Then
        DoCmd.SetWarnings False
            'Purge de la table des factures à envoyer par messagerie
            DoCmd.RunSQL "Delete T_Factures_Envoi_Messagerie.CléP_Facture_Envoi_Messagerie FROM T_Factures_Envoi_Messagerie"
            'Peuplement de la table des factures à envoyer par messagerie
            DoCmd.OpenQuery "R_Factures_Envoi_Messagerie_PeuplementTable"
     
        DoCmd.SetWarnings False
     
    Dim NbFactNoPrintPDF As Integer
    Dim FirstFactNuméro As Variant
    Dim Strfile As String
     
    Dim qdf As DAO.QueryDef
        Set qdf = CurrentDb.QueryDefs!R_Factures_Etat
     
    Do
        NbFactNoPrintPDF = DCount("FeM_Facture_Imprimé_PDF", "T_Factures_envoi_Messagerie", "FeM_Facture_Imprimé_PDF = 0")
        Me.Test = NbFactNoPrintPDF
        FirstFactNuméro = DMin("FeM_Facture_Numéro", "T_Factures_envoi_Messagerie", "FeM_Facture_Imprimé_PDF = 0")
        Strfile = "W:\Bases\Iris\FacturesEnvoiMessagerie\" & DLookup("FeM_PDF_Nom", "T_Factures_Envoi_Messagerie", "FeM_Facture_Numéro =" & FirstFactNuméro)
            qdf.SQL = "SELECT R_Factures.*, R_Facture_Contenu.* FROM R_Factures LEFT JOIN R_Facture_Contenu ON R_Factures.CléP_Facture = R_Facture_Contenu.FC_Clé_Facture " & _
                        "WHERE R_Factures.Fact_Numéro = " & FirstFactNuméro
        DoCmd.OutputTo acOutputReport, "E_Facture", "PDFFormat(*.pdf)", Strfile, False, "", , acExportQualityScreen
        DoCmd.RunSQL "UPDATE T_Factures_Envoi_Messagerie SET T_Factures_Envoi_Messagerie.FeM_Facture_Imprimé_PDF = -1 " & _
                        "WHERE T_Factures_Envoi_Messagerie.FeM_Facture_Numéro = " & FirstFactNuméro
    Loop Until NbFactNoPrintPDF = 1
     
    Else
        If MsgBox("Il n'y a aucune facture sélectionnée !" & (Chr(10) & Chr(10)) & _
        "Vous devez sélectionner des factures" & Chr(10) & _
        "pour pouvoir les voir, les imprimer" & Chr(10) & _
        "ou bien les envoyer par messagerie." & Chr(10) & _
        "" & (Chr(10)), vbApplicationModal, CurrentDb.Properties("AppTitle")) = vbOK Then Exit Sub
    End If
    Fin:
        DoCmd.SetWarnings True
     
            qdf.SQL = "SELECT R_Factures.*, R_Facture_Contenu.* FROM R_Factures LEFT JOIN R_Facture_Contenu ON R_Factures.CléP_Facture = R_Facture_Contenu.FC_Clé_Facture"
            Set qdf = Nothing
    End Sub

  10. #10
    Membre habitué Avatar de possible924
    Homme Profil pro
    Inscrit en
    Mars 2010
    Messages
    302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 81
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Mars 2010
    Messages : 302
    Points : 159
    Points
    159
    Par défaut
    Il me semble avoir le problème
    Dans le nom du fichier, la raison sociale du client est repris,
    mais pour certains clients le nom comportait un "/" et l'enregistrement du pdf était rejeté
    car le "/" indiquait un répertoire qui n'existait évidement pas !
    ça fonctionne après avoir placé un replace([RS_Client];"/";"-")

    Bonnes Pâques à toutes et tous
    Pierre

Discussions similaires

  1. Envoyer des factures par mail en masse via SAP
    Par rickblood dans le forum SAP
    Réponses: 3
    Dernier message: 05/10/2016, 12h41
  2. [Mail] Envoyer pièce jointe par mail
    Par Le Mad dans le forum Langage
    Réponses: 2
    Dernier message: 04/09/2006, 15h58
  3. envoyer des données par mail
    Par zorba49 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 16/12/2005, 11h00
  4. Réponses: 1
    Dernier message: 03/12/2005, 12h24
  5. [Mail] Envoyer un fichier par mail
    Par Oberown dans le forum Langage
    Réponses: 3
    Dernier message: 24/10/2005, 15h55

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