Bonjour, voilà pour gérer mes devis j'ai créé une feuille descriptive par devis sur un classeur Excel.
Je souhaiterais balayer l'ensemble des feuilles afin d'envoyer un mail récapitulatif des devis. Ci-dessous la boucle de façon simplifiée afin de comprendre le codage.
Merci par avance pour votre aide.
Sub projet()
Dim mail As Variant
Set mail = CreateObject("outlook.Application")
Dim derniereLigne As Long
Dim premiereLigne As Long
premiereLigne = 26
Dim ContenuFichier As String
Dim MonFichier As String
MonFichier = "C:\Utilisateurs\XXXX\Documents\projet.txt"
Dim f As Integer
f = freeFile
'Outerture du fichier texte
Open MonFichier For Output As #f
'ETAPE 1 => CREATION DE LA BOUCLE POUR PARCOURIR LES FEUILLES DU CLASSEUR
Dim i
For i = 1 To Worksheets.Count
derniereLigne = Worksheets(i).Cells(Rows.Count, 1).End(xlUp).Row
Print #f, Range("D1") & " TOTAL = " & Range("B7") & " Euros"
'ETAPE 2 => CREATION D'UNE BOUCLE POUR PARCOURIR UN TABLEAU DANS CHAQUE FEUILLE
For Ligne = premiereLigne To derniereLigne
Print #f, Tab, Range("B" & Ligne), Range("C" & Ligne), Range("G" & Ligne)
Next Ligne
Print #f, "********"
Print #f,
MsgBox "Le texte a été sauvegardé"
Next
Next i
'fermeture du fichier texte
Close #f
'ETAPE 2 => ENVOYER LE MAIL
ContenuFichier = LireFichierTexte(MonFichier)
With mail.CreateItem(olMailItem)
.Subject = "Devis"
.To = ""
.Body = ContenuFichier
.Display
End With
End Sub
Salut umfred, tout d'abord merci pour ta réponse. J'ai modifié le code et il se déroule sans bug.
Constats:
Le message MsgBox apparaît 8 fois car j'ai feuilles MAIS le fichier projet.txt ne garde que les données de la feuille active et pas les autres !!
A+
Sub projet()
Dim mail As Variant
Set mail = CreateObject("outlook.Application")
Dim derniereLigne As Long
Dim premiereLigne As Long
premiereLigne = 26
Dim ContenuFichier As String
Dim MonFichier As String
MonFichier = "C:\Users\xxxx\Documents\projet.txt"
Dim f As Integer
f = freeFile
'Outerture du fichier texte
Open MonFichier For Output As #f
'ETAPE 1 => CREATION DE LA BOUCLE POUR PARCOURIR LES FEUILLES DU CLASSEUR
Dim i
For i = 1 To Worksheets.Count
derniereLigne = Worksheets(i).Cells(Rows.Count, 1).End(xlUp).Row
Print #f, Range("D1") & " TOTAL = " & Range("B7") & " Euros"
'ETAPE 2 => CREATION D'UNE BOUCLE POUR PARCOURIR UN TABLEAU DANS CHAQUE FEUILLE
For Ligne = premiereLigne To derniereLigne
Print #f, Tab, Range("B" & Ligne), Range("C" & Ligne), Range("G" & Ligne)
Next Ligne
Print #f, "********"
Print #f,
MsgBox "Le texte a été sauvegardé"
Next i
'fermeture du fichier texte
Close #f
'ETAPE 2 => ENVOYER LE MAIL
ContenuFichier = LireFichierTexte(MonFichier)
With mail.CreateItem(olMailItem)
.Subject = "Devis"
.To = ""
.Body = ContenuFichier
.Display
End With
End Sub
Tu dois bien avoir 8 parties dans ton fichier texte, mais toutes identiques; c'est parce que le range va s'appliquer que la feuille active puisque tu ne spécifies la feuille concerné par le range.
Je propose de les parcourir depuis la collection des WorkSheets avec un For Each
Sub projet()
Dim mail As Variant
Set mail = CreateObject("outlook.Application")
Dim derniereLigne As Long
Dim premiereLigne As Long
premiereLigne = 26
Dim ContenuFichier As String
Dim MonFichier As String
MonFichier = "C:\Users\xxxx\Documents\projet.txt"
Dim f As Integer
f = freeFile
'Outerture du fichier texte
Open MonFichier For Output As #f
'ETAPE 1 => CREATION DE LA BOUCLE POUR PARCOURIR LES FEUILLES DU CLASSEUR
Dim ws as WorkSheet
For Each ws in Worksheets
derniereLigne = ws.Cells(Rows.Count, 1).End(xlUp).Row
Print #f, ws.Range("D1") & " TOTAL = " & ws.Range("B7") & " Euros"
'ETAPE 2 => CREATION D'UNE BOUCLE POUR PARCOURIR UN TABLEAU DANS CHAQUE FEUILLE
For Ligne = premiereLigne To derniereLigne
Print #f, Tab, ws.Range("B" & Ligne), ws.Range("C" & Ligne), ws.Range("G" & Ligne)
Next Ligne
Print #f, "********"
Print #f,
MsgBox "Le texte a été sauvegardé"
Next i
'fermeture du fichier texte
Close #f
'ETAPE 2 => ENVOYER LE MAIL
ContenuFichier = LireFichierTexte(MonFichier)
With mail.CreateItem(olMailItem)
.Subject = "Devis"
.To = ""
.Body = ContenuFichier
.Display
End With
End Sub
Sinon en conservant les indices
Sub projet()
...
Dim i
For i = 1 to Worksheets.count
Dim ws as WorkSheet
Set ws = Worksheets(i)
[...]
Next i
...
End Sub
J'ai préfixé par VBA parce que parfois, dans certains cas, il peut ne pas trouver la fonction ou utiliser la "mauvaise" fonction (la fonction d'excel de même nom, et pas la fonction vba); Je crois que ça vient des références cochées dans le projet vba.
Bon, je rouvre le sujet afin d'améliorer le code :). Bon je vais être honnête je n'ai pas encore chercher ... mais le ferai !
Rappel:
ma boucle balai toutes les feuilles du classeur pour envoyer un mail synthétisant les devis. Le truc c'est que maintenant je souhaiterais joindre dans le mail les devis qui sont en format PDF. Pour ça chaque devis à une référence et je souhaiterais que la boucle parcoure le dossier contenant le devis en question et le joigne.
Exemple:
Feuille 1 => 1 devis pour référence 001 / Aller chercher dans le dossier devis le fichier (format PDF) qui contient 001 (colonne E ) si oui le joint dans le mail => passe à la feuille 2
Feuille 2 => 2 devis pour référence 002 & 003 / Aller les chercher dans le dossier devis si oui le joint et ainsi de suite ....
Ci-dessous le code actuel:
Sub envoyerDevis()
Dim dateAujourdhui As Date
dateAujourdhui = Date
Dim mail As Variant
Set mail = CreateObject("outlook.Application")
Dim derniereLigne As Long
Dim premiereLigne As Long
premiereLigne = 26
Dim ContenuFichier As String
Dim MonFichier As String
MonFichier = "M:\Users\xxx\Dossiers\devis.txt"
Dim f As Integer
f = FreeFile
Open MonFichier For Output As #f
'ETAPE 1 => CREATION DE LA BOUCLE POUR PARCOURIR LES FEUILLES DU CLASSEUR
Dim i
For i = 1 To Worksheets.Count
Dim ws As Worksheet
Set ws = Worksheets(i)
derniereLigne = ws.Cells(Rows.Count, 1).End(xlUp).Row
'CONDITION IF pour copier les données
' si ça commence par 23 (quelque soit la suite)
If Left(ws.Name, 2) = "23" And ws.Range("B18") = "DEVIS" And ws.Range("B1") <> "" And ws.Range("D1") <> "" And ws.Range("B11") = "" And ws.Range("B12") = "NON COMMUNIQUE" Then
Print #f, ws.Range("D1") '& " Total = " & ws.Range("B7") & " E"
'ETAPE 2 => CREATION D'UNE BOUCLE POUR PARCOURIR UN TABLEAU DANS CHAQUE FEUILLE
For Ligne = premiereLigne To derniereLigne
Print #f, Tab, ws.Range("B" & Ligne), ws.Range("C" & Ligne), ws.Range("G" & Ligne)
Next Ligne
Print #f,
Print #f,
MsgBox "Le texte a été sauvegardé"
ws.Range("B4").Value = dateAujourdhui
ws.Range("B11").Value = dateAujourdhui
ws.Range("B12").Value = "ATTENTE"
End If
Next i
'fermeture du fichier texte
Close #f
'ETAPE 2 => ENVOYER LE MAIL
ContenuFichier = LireFichierTexte(MonFichier)
With mail.CreateItem(olMailItem)
.Subject = "Devis pour accord"
.To = "xxxx"
.Body = ContenuFichier
.Display
End With
End Sub
le dossier des devis est constant ? (ou correspond à un dossier facilement identifiable?)
comment apparait la référence du devis dans le nom du fichier pdf ? si référence 001ça veut dire que le fichier s'appelle '001.pdf" ou "001_devis.pdf" ou ...
l'idée c'est plutôt de mettre les infos ici dans le forum pour tout le monde (et éventuellement me prévenir par mp)
doudoufly a écrit:
Salut, excuses moi pas mal pris avec le boulot
En fait, l'idée c'est de joindre dans le mail les devis que j'ai en format PDF des fournisseurs.
Ces devis se situent dans un dossier sur le serveur qui porte le même nom que l'onglet de la feuille.
Après je peux peut-être ajouter une colonne à mon tableau excel et y mettre la localisation du fichier et comme ça la boucle parcour le tableau et joint le fichier.
Tu en penses quoi ? Si t'as besoin de plus d'info n'hésites pas. En pièce jointe une photo d'un exemple de feuille excel.
A+
Si les devis sont tous dans le même répertoire de base et que le chemin se présente sous la forme RepBase\[nom_onglet]\[fichier_devis].pdf, définir une variable pour le répertoire de base et récupérer les morceaux du chemin pour avoir les chemins et lors du parcours de la feuille excel, les ajouter dans un tableau (ou une collection) au fur et à mesure. Ensuite, à la création du mail, rajouter ces chemins en parcourant ce tableau à nouveau
Récupération dans un tableau avec redimensionnement dynamique (pas testé mais ça devrait fonctionner, sauf peut-être l'initialisation
Dim RepBase as string
RepBase="c:\devis\"
Dim tableau_fichier() as String
...
ReDim Preserve tableau_fichier(0) as String
For Ligne = premiereLigne To derniereLigne
...
'on ajoute à la fin le chemin vers le fichier
tableau_fichier(ubound(tableau_fichier))= RepBase & ws.Name & "\" & ws.Range("E" & ligne).value & ".pdf"
'on redimensionne en préservant les données à n+1
Redim Preserve tableau_fichier(ubound(tableau_fichier)+1)
Next Ligne
'retire le dernier élement qui doit être vide normalement
if UBound(tableau_fichier >0) then ReDim Preserve tableau_fichier(UBound(tableau) - 1)
Récupération dans une collection
Dim RepBase as string
RepBase="c:\devis\"
...
Dim liste_fichier(0) as new collection 'initialise une collection vide
For Ligne = premiereLigne To derniereLigne
...
'on ajoute à la fin le chemin vers le fichier
liste_fichier.Add RepBase & ws.Name & "\" & ws.Range("E" & ligne).value & ".pdf"
Next Ligne
With oMailItem
'...
.To = "comptabilite@entreprise.fr"
.Subject = "Factures pour le mois de juin"
.BodyFormat = olFormatRichText
.Body = Body
'...
.Attachments.Add "C:\MonDossier\MonFichier.xlsx"
.Attachments.Add "C:\MonDossier\MonFichier1.docx"
.Attachments.Add "C:\AutreDossier\Facture_123.pdf"
.Attachments.Add "C:\AutreDossier\Devis_234.pdf"
'...
.Send
End With
En fait les devis sont bien dans le répertoire de base "C:\devis\" mais dans ce répertoire on a un dossier portant le nom de la feuille du classeur.
Exemple : feuille 2350 bien les devis se trouvent dans C:\devis\2350\ et après ok on va récupérer le nom dans la colonne E
Faut juste que j'arrive à récupérer le ws.name. Peut-être plus compliqué je sais pas ce que tu en penses.
1)C'est peut-être ce que tu as voulu faire en écrivant oups j'avais pas vu => tableau_fichier(ubound(tableau_fichier))= RepBase & ws.Name & "\" & ws.Range("E" & ligne).value & ".pdf"
2)Du coup pour faire une boucle avec .Attachments.Add l et la variable tableau_Fichier ? encore une fois je débute désolé si c'est évident :)
3) J'ai une erreur en rouge sur le code suivant:
if UBound(tableau_fichier >0) then ReDim Preserve tableau_fichier(UBound(tableau) - 1)
En gros c'est comment je peux récupérer les données de la variable tableau pour joindre les fichiers au mail. je vais pas pouvoir les taper un par un si j'ai 10 devis à joindre
Dim i as integer ' si pas déjà existant
for i = lbound(tableai) to ubound(tableau)
.Attachments.Add tableau(i)
Next i
'ou
Dim nom as variant
For Each nom in tableau
.Attachments.Add nom
Next nom
Les deux ne marchent pas. J'ai la même erreur sur le .Attachments.add que je ne m'explique pas peut-être dans une erreur dans le nom du tableau ou d'emplacement de la boucle.
ContenuFichier = LireFichierTexte(MonFichier)
With mail.CreateItem(olMailItem)
.Subject = "Devis pour accord"
.To = "xxx@xxxx.fr"
.Body = ContenuFichier
'Dim j As Integer
'For j = LBound(tableau_fichier) To UBound(tableau_fichier)
'.attachments.Add tableau_fichier(j)
'Next j
Dim nom As Variant
For Each nom In tableau_fichier
.Attachments.Add nom
Next nom
.Display
End With
Sub envoyerDevis()
'VARIABLE mail
Dim mail As Variant
Set mail = CreateObject("outlook.application")
'VARIABLE CONTENU DU MAIL
Dim contenuMail As String
Dim MonFichier As String
MonFichier = "M:\Users\testdevis.txt"
Dim f As Integer
f = FreeFile
Open MonFichier For Output As #f
'VARIABLES premières et dernières lignes du tableau des devis d'une feuille
Dim derniereLigne As Long
Dim premiereLigne As Long
premiereLigne = 2
'VARIABLE répertoire devis
Dim RepBase As String
RepBase = "M:\Users\DEVIS"
'VARIABLE tableau qui récupere la liste des devis colonne A
Dim tableau_fichier() As String
ReDim Preserve tableau_fichier(0) As String
'BOUCLE FEUILLE PAR FEUILLE
Dim i
For i = 1 To Worksheets.Count
Dim ws As Worksheet
Set ws = Worksheets(i)
derniereLigne = ws.Cells(Rows.Count, 1).End(xlUp).Row
For Ligne = premiereLigne To derniereLigne
'on ajoute à la fin le chemin vers le fichier
tableau_fichier(UBound(tableau_fichier)) = RepBase & ws.Name & "\" & ws.Range("A" & Ligne).Value & ".pdf"
Print #f, Tab, tableau_fichier(UBound(tableau_fichier))
'on redimensionne en préservant les données à n+1
ReDim Preserve tableau_fichier(UBound(tableau_fichier) + 1)
Next Ligne
'retire le dernier élement qui doit être vide normalement
If UBound(tableau_fichier) > 0 Then ReDim Preserve tableau_fichier(UBound(tableau_fichier) - 1)
Next i
Close #f
Sheets("A").Range("A1") = tableau_fichier(UBound(tableau_fichier))
'ENVOYER MAIL
Dim j As Integer
ContenuFichier = LireFichierTexte(MonFichier)
With mail.CreateItem(olMailItem)
.Subject = "Devis pour accord"
.To = "xxx@xxxx.fr"
.Body = ContenuFichier
For j = LBound(tableau_fichier) To UBound(tableau_fichier)
.attachments.Add tableau_fichier(j)
Next j
'Dim nom As Variant
'For Each nom In tableau_fichier()
'.Attachments.Add nom
'Next nom
.Display
End With
End Sub
l'erreur est : J'ai vérifier l'emplacement ça parait bon.
et le message d'erreur ? (je suppose que c'est la même erreur quelque soit la boucle utilisée)
voir si ce n'est pas la ligne qui semble manqué par rapport à l'exemple, ce qui donnerait
With mail.CreateItem(olMailItem)
.Subject = "Devis pour accord"
.To = "xxx@xxxx.fr"
.Body = ContenuFichier
Set myAttachments = .Attachments
For j = LBound(tableau_fichier) To UBound(tableau_fichier)
myAttachments.Add tableau_fichier(j)
Next j
'Dim nom As Variant
'For Each nom In tableau_fichier()
'.Attachments.Add nom
'Next nom
.Display
End With
Mais là le code génére un seul mail, dans lequel il attache tous les fichiers présent dans le tableau_fichier, c'est bien le but recherché ?
Question subsidiaire: la boucle plante avec quelle valeur de j ? et est-ce que le chemin contient un espace? si oui, il faut sans doute rajouter des guillemets autour du chemin
if InStr(tableau_fichier(j)," ") >0 Then
myAttachments.Add """" & tableau_fichier(j) & """"
else
myAttachements.Add tableau_fichier(j)
End If
'on peut aussi l'écrire avec l'opérateur ternaire
' myAttachements.Add IIF(InStr(tableau_fichier(j)," ") >0, """" & tableau_fichier(j) & """", tableau_fichier(j))
Salut Umfred, merci pour ta réponse. J'ai peut-être trouvé l'erreur mais je ne vois pas d'où dans le code
Quand j'enlève la boucle et que je laisse que le code suivant pour envoyer le mail:
ContenuFichier = LireFichierTexte(MonFichier)
With mail.CreateItem(olMailItem)
.Subject = "Devis pour accord"
.To = "xxx@xxxx.fr"
.Body = ContenuFichier
.Display
End With
ça fonctionne et voilà ce que contient le contenuFichier:
ça vient de ce code là: on ajoute au RepBase, le nom de la feuille (donc sans doute 1, 2, ....) => "M:\users\DEVIS1\[valeur].pdf"; "M:\users\DEVIS2\[valeur].pdf". Dans le code que j'avais proposé initialement, j'avais bien terminé le chemin de RepBase par un "\" => "M:\users\DEVIS\".
Je n'arrive toujours pas à insérer les pièces jointes dans mon mail avec la boucle suivante. La variable tableau() contient les emplacements des fichiers PDF. Mais j'ai une erreur à myAttachements.Add tableau(j). Merci à vous pour votre aide.
ContenuFichier = LireFichierTexte(fichierTxt)
With mail.CreateItem(olMailItem)
.Subject = "Devis pour accord"
.To = "xxx@xxxx.fr"
.Body = ContenuFichier
Dim j As Integer
For j = 0 To UBound(tableau)
Set myAttachments = .attachments
myAttachements.Add tableau(j)
'.attachments.Add
Next j
Salut umfred, j'ai sorti la variable mayAttachments et ça ne marche pas. J'ai l'erreur suivante:
Erreur d'éxécution '424':
Objet requis
J'espère que c'est ça que tu souhaite savoir si non dis moi comment faire stp
Ci-dessous le code dans son intégralité. Je vais continuer de mon côté à chercher également. Merci A plus.
Sub essai1()
'VARIABLE MAIL
Dim mail As Variant
Set mail = CreateObject("outlook.application")
Dim contenuMail As String
Dim fichierTxt As String
fichierTxt = "XXX"
Dim f As Integer
f = FreeFile
Open fichierTxt For Output As #f
'VARIABLES LIGNES
Dim derniereLigneF, derniereLigneT, premiereLigneF, ligne As Long
premiereLigneF = 2
'VARIABLE DEVIS
Dim repDevis As String
repDevis = "XXX"
'VARIABLES TABLEAU
Dim tableau() As String
ReDim Preserve tableau(0) As String
Dim counter As Integer
counter = 0
'BOUCLE FEUILLE PAR FEUILLE
Dim fl As Integer
For fl = 1 To Worksheets.Count
Dim ws As Worksheet
Set ws = Worksheets(fl)
derniereLigneF = ws.Cells(Rows.Count, 1).End(xlUp).Row
'BOUCLE POUR ENREGISTRER DANS LE TABLEAU
For ligne = premiereLigneF To derniereLigneF
ReDim Preserve tableau(counter) As String
tableau(counter) = repDevis & ws.Name & "\" & ws.Range("A" & ligne).Value & ".pdf"
Print #f, Tab, tableau(counter)
counter = counter + 1
Next ligne
Next fl
'VERIFICATION
For Each valeur In tableau
res = res & valeur & vbLf
Next
MsgBox res
Close #f
'ENVOYER MAIL
ContenuFichier = LireFichierTexte(fichierTxt)
With mail.CreateItem(olMailItem)
.Subject = "Devis pour accord"
.To = "xxx@xxxx.fr"
.Body = ContenuFichier
'ERROR ICI
Dim j As Integer
Set myAttachments = .attachments
For j = 0 To UBound(tableau)
myAttachements.Add tableau(j)
Next j
End With
End Sub
ContenuFichier = LireFichierTexte(fichierTxt)
Dim mymail
Set mymail = mail.CreateItem(olMailItem)
With mymail
.Subject = "Devis pour accord"
.To = "xxx@xxxx.fr"
.Body = ContenuFichier
'ERROR ICI
Dim j As Integer
Dim myAttachments
Set myAttachments = .attachments
For j = 0 To UBound(tableau)
myAttachements.Add tableau(j)
Next j
End With
L'erreur est la même que dans ton message précédent ? sur ta ligne 68 ? quelle valeur de j ? (voir dans la fenêtre Variables Locales ou en tapant dans la fenêtre d'exécution ?j , si les fenêtres ne sont pas visibles passer par le menu affichage pour les activer)
L'erreur est la même que dans ton message précédent ? => j'ai modifié le code donc peux pas te dire
quelle valeur de j ? => C'est la référence de la variable tableau (0, 1, 2, 3 etc) pour localiser la donnée enregistrée qui est une variable string (l'emplacement du fichier PDF).
voir dans la fenêtre Variables Locales ou en tapant dans la fenêtre d'exécution ?j , si les fenêtres ne sont pas visibles passer par le menu affichage pour les activer) => Tu veux savoir quoi ? Dans la fenêtre exécution il y a rien et dans la fenêtre variable ça met J vide
Par contre avec le code suivant ça marche uniquement si le fichier PDF est bien présent. Mais si il ne l'ai pas alors qu'il est sensé être pour la variable tableau il met l'erreur
"fichier introuvable. vérifier que le chemin d'accès et le nom du fichier soit correct". Il faudrait peut-être mettre une condition pour vérifier la présence du fichier dans le répertoire avant de faire l'attachments
'essai 2
For Each valeur In tableau
.attachments.Add valeur
Next
l'erreur de ta capture indique qu'il ne trouve pas le fichier que tu passes à .attachments.add donc oui tu pourrais rajouter un test vérifiant la présence du fichier.
Quand je demandais la valeur de j c'est sa vraie valeur au moment de l'erreur, pour que tu puisses regarder la valeur correspondante dans ton tableau; là comme tu as changé de type de boucle, ce n'est plus d'actualité pour j, mais ça le reste pour la valeur du chemin (ta variable valeur)
Lors de l'erreur, si tu cliques sur débogage, tu vas pouvoir voir la valeur de ton chemin (ici dans ta variable valeur) soit dans les variables locales soit en tapant dans la fenêtre exécution:
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
L'erreur est la même que dans ton message précédent ? sur ta ligne 68 ?