VBA: Créer et remplir automatiqmt des fiches

Résolu
Andréa -  
 Andréa -
Bonjour,

Mon classeur Excel compte deux feuilles: la première ("Données") comporte des données (nom, prénom... en colonnes) sur des adhérents situés les uns en-dessous des autres (lignes), et la seconde est un modèle de fiche individuelle ("Fiche"): http://cjoint.com/?ECqnBVGQ0Xn
Mon but est de pouvoir créer automatiquement autant de fiches (autrement dit de feuilles) qu'il y a d'adhérents et que chaque fiche soit complétée des données de l'adhérent concerné, et porte son nom.
Exemple: en feuille "Données" sont indiqués 3 adhérents (Pierre, Paul et Jacques): la macro créera alors à la suite 3 feuilles supplémentaires intitulées Pierre, Paul et Jacques avec les données de chacun.
Pourrait-on m'aider??

Je vous en remercie par avance!

3 réponses

pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761
 
Alors, je ne peux pas tester, ne disposant pas de lotus...
Mais essaye de ton côté.

Il y a trois constantes à adapter à ton cas. Voir dans le code l'entête.

Il te faut ajouter également les adresses mail dans ton fichier initial, en colonne H par exemple.
Cf fichier exemple : https://www.cjoint.com/c/ECqoOeyA0Y9

Le code :
Option Explicit

Const EMBED_ATTACHMENT As Long = 1454

'A ADAPTER*****************************************
'objet du mail :
Const stSubject As String = "Envoi fiche membre"
'corps du mail
Const vaMsg As Variant = "Bonjour," & vbCrLf & vbCrLf & vbCrLf & "Voici votre fiche membre." & vbCrLf & vbCrLf & "Cordialement"
'copie à :
Const vaCopyTo As Variant = "name@mail.com"
'FIN ADAPTATIONS***********************************

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim bCpt As Byte, reponse As Integer, dest As String

If Target.Count > 1 Then Exit Sub
If Target.Column < 2 And Target.Row > 1 And Target.Row < 1500 And Target.Value <> "" Then
    If MsgBox("Voulez-vous envoyer la fiche de : " & Target.Value & "?", vbYesNo, "Envoi par mail") = vbYes Then
        With Sheets("Fiche")
            For bCpt = 3 To 9
                .Range("C" & bCpt) = Target.Offset(0, bCpt - 3)
            Next
            dest = Target.Offset(0, 7).Value
            .Copy
            Call Send_Active_Sheet(dest)
        End With
    End If
End If
End Sub


Sub Send_Active_Sheet(destinataire As String)

Dim stFileName As String
Dim vaRecipients As Variant

Dim noSession As Object
Dim noDatabase As Object
Dim noDocument As Object
Dim noEmbedObject As Object
Dim noAttachment As Object
Dim stAttachment As String

'Copy the active sheet to a new temporarily workbook.
With ActiveSheet
    .Copy
    stFileName = .Range("C3").Value
End With

stAttachment = ThisWorkbook.Path & "\" & stFileName & ".xls"

'Save and close the temporarily workbook.
With ActiveWorkbook
    .SaveAs stAttachment
    .Close
End With


'Instantiate the Lotus Notes COM's Objects.
Set noSession = CreateObject("Notes.NotesSession")
Set noDatabase = noSession.GetDatabase("", "")

'If Lotus Notes is not open then open the mail-part of it.
If noDatabase.IsOpen = False Then noDatabase.OPENMAIL

'Create the e-mail and the attachment.
Set noDocument = noDatabase.CreateDocument
Set noAttachment = noDocument.CreateRichTextItem("stAttachment")
Set noEmbedObject = noAttachment.EmbedObject(EMBED_ATTACHMENT, "", stAttachment)

'Add values to the created e-mail main properties.
With noDocument
    .Form = "Memo"
    .SendTo = destinataire
    '.CopyTo = vaCopyTo
    .Subject = stSubject
    .Body = vaMsg
    .SaveMessageOnSend = True
    .PostedDate = Now()
    .Send 0, vaRecipients
End With

'Delete the temporarily workbook.
Kill stAttachment

'Release objects from memory.
Set noEmbedObject = Nothing
Set noAttachment = Nothing
Set noDocument = Nothing
Set noDatabase = Nothing
Set noSession = Nothing

MsgBox "Email crée et envoyé avec succès", vbInformation
End Sub

4
Andréa
 
Je retourne à l'association demain matin et pourrai ainsi tester l'envoi par Lotus Notes, que je n'ai pas chez moi. Quel que soit le résultat, merci pour l'investissement Pijaku. Je fais un retour demain matin suite à l'essai. Merci encore
0
Andréa
 
Bonjour,

Je viens de faire l'essai du code avec Lotus Notes et ça marche!!!
Par contre, vu sa complexité, il me sera difficile de le réadapter à d'autres formulaires, mais j'essaierai de le décortiquer.

Merci encore!
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761 > Andréa
 
Bonjour,

N'hésite pas à demande...
En gros, tu ne dois rien changer dans la procédure Send_Active_Sheet(destinataire) qui envoie, la feuille active, par mail lotus au ... destinataire.

Par contre, si tu souhaites adapter à d'autres formulaires, il conviendra de modifier, le cas échéant, la procédure événementielle Worksheet_SelectionChange

A+
0
Andréa
 
Merci! Si je comprends bien le code, qui convient parfaitement à ma demande, il ne s'applique que pr les bases de données d'origine et les formulaires de destination ayant des champs qui se succèdent? Mais comment faire si, par exemple, je souhaite effectuer les transfert de A4 de la feuille Données à B6 de la Fiche, puis la A6 de Données à C4 de la Fiche et ainsi de suite sans logique entre les cellules? A quel endroit du code et de quelle manière le préciser?? Merci encore!
J'ai par ailleurs un cas à vous soumettre dans le même esprit que celui-ci, mais en plus complexe je pense. J'en indiquerai le lien ici des que j'aurai préparé le fichier de test.
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761 > Andréa
 
Dans la macro :
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim bCpt As Byte, reponse As Integer, dest As String

If Target.Count > 1 Then Exit Sub
If Target.Column < 2 And Target.Row > 1 And Target.Row < 1500 And Target.Value <> "" Then
    If MsgBox("Voulez-vous envoyer la fiche de : " & Target.Value & "?", vbYesNo, "Envoi par mail") = vbYes Then
        With Sheets("Fiche")
            For bCpt = 3 To 9
                .Range("C" & bCpt) = Target.Offset(0, bCpt - 3)
            Next
            dest = Target.Offset(0, 7).Value
            .Copy
            Call Send_Active_Sheet(dest)
        End With
    End If
End If
End Sub


Je l'ai fait sous forme de boucle :
        With Sheets("Fiche")
            For bCpt = 3 To 9
                .Range("C" & bCpt) = Target.Offset(0, bCpt - 3)
            Next
        End With


cela se traduit par :

Sheets("Fiche").Range("C3") = ActiveSheet.Range("Ax") 'ou x est la ligne de la cellule sélectionnée
Sheets("Fiche").Range("C4") = ActiveSheet.Range("Bx") 
Sheets("Fiche").Range("C5") = ActiveSheet.Range("Cx") 
'etc
Sheets("Fiche").Range("C9") = ActiveSheet.Range("Gx") 


A toi de l'écrire, rigoureusement comme cela.

Target = cellule cliquée dans la procédure événementielle Worksheet_SelectionChange

Offset(Ligne, Colonne) décale d'autant de lignes et de colonnes qu'indiqué.
Target.Offset(3, 5) désigne la cellule 3 lignes en dessous et 5 colonnes à droite...
Target.Offset(-2, 0) désigne la cellule située deux lignes au dessus et dans la même colonne...
0
hoodoo2310 Messages postés 4 Date d'inscription   Statut Membre Dernière intervention   2
 
Bonjour,

Voici un petit truc rapide, mais qui peut certainement être améliorer par des experts (je suis loin d'en être une).

Sub Macro2()

Application.ScreenUpdating = False

Sheets("Données").Select
Range("A2").Select
Do Until ActiveCell.Value = ""
Nom = ActiveCell.Value
Prénom = ActiveCell.Offset(0, 1).Value
Genre = ActiveCell.Offset(0, 2).Value
Date_N = ActiveCell.Offset(0, 3).Value
Adresse = ActiveCell.Offset(0, 4).Value
CP = ActiveCell.Offset(0, 5).Value
Ville = ActiveCell.Offset(0, 6).Value

Sheets.Add.Name = Nom
Sheets("Fiche").Select
Cells.Select
Selection.Copy
Sheets(Nom).Select
ActiveSheet.Paste
Range("C3").Value = Nom
Range("C4").Value = Prénom
Range("C5").Value = Genre
Range("C6").Value = Date_N
Range("C7").Value = Adresse
Range("C8").Value = CP
Range("C9").Value = Ville
Sheets("Données").Select
ActiveCell.Offset(1, 0).Select
Loop
End Sub
1
Andréa
 
La solution proposée tient vraiment la route, je n'ai constaté ni incohérence dans le résultat, ni message d'erreur, merci! J'ai simplement ajouté les deux lignes suivantes après "Loop" afin que mes deux feuilles initiales ne soient pas déplacées à la fin:
Sheets("Données").Move before:=Sheets(1)
Sheets("Fiche").Move after:=Sheets("Données")

Merci encore!
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761
 
Bonjour,

Pourquoi vouloir créer une fiche par membre?

Essaye cette macro :
  • Clic droit sur l'onglet de la feuille Données
  • visualiser le code
  • copier-coller ce code :

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim bCpt As Byte
If Target.Column < 2 And Target.Row > 1 And Target.Row < 1500 And Target.Count = 1 And Target.Value <> "" Then
    With Sheets("Fiche")
        For bCpt = 3 To 9
            .Range("C" & bCpt) = Target.Offset(0, bCpt - 3)
        Next
        .Select
    End With
End If
End Sub


Pour le faire fonctionner, sélectionner une cellule non vide de la colonne A de la feuille Données...
0
Andréa
 
Bonjour Pijaku,

et merci pour le code. Je souhaite créer une fiche par membre car je souhaite par la suite pouvoir les séparer du classeur et les envoyer individuellement. Dans cette optique, le code proposé ne semble pas tout à fait convenir...
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761 > Andréa
 
pouvoir les séparer du classeur et les envoyer individuellement

Je ne vois toujours pas l'intérêt.
Mais bon.
Comment souhaiterais tu envoyer tes fiches individuelles?
0
Andréa
 
Je voudrais les envoyer par mail à chaque membre concerné sans que celui-ci ait connaissance des données des autres membres, d'où la nécessité de les séparer.
Pour la séparation, j'ai trouvé le code suivant, qui semble répondre à mon besoin:
Sub ExportGroupe()

'créer des classeurs à partir de feuilles
Application.ScreenUpdating = False
Dim Feuille As Worksheet
Dim Nom2 As String
Nom2 = InputBox("Combien de feuilles exporter?" & Chr(10) & "Indiquer le nombre de feuilles en partant de la fin", "Export")
If Nom2 = "" Then
Exit Sub
End If
For Each Feuille In ActiveWorkbook.Sheets
If Feuille.Index > Sheets.Count - Nom2 Then
Feuille.Copy
With ActiveWorkbook
.Title = Feuille.Name
.Subject = Feuille.Name
.SaveAs Filename:=ThisWorkbook.Path & "\" & Feuille.Name + ".xlsx"
End With
End If
Next
Application.ScreenUpdating = True
End Sub
0
pijaku Messages postés 12263 Date d'inscription   Statut Modérateur Dernière intervention   2 761 > Andréa
 
Je voudrais les envoyer par mail à chaque membre concerné sans que celui-ci ait connaissance des données des autres membres, d'où la nécessité de les séparer.

Je ne vois toujours pas l'intérêt ni la nécessité de les séparer...

Quel logiciel de messagerie?
Outlook?
ou alors un mail style gmail ou hotmail??
0
Andréa
 
Si les fiches peuvent être transmises séparément sans avoir été préalablement séparées dans le fichier alors partons sur une autre solution, je n'y suis absolument pas fermée.
Elles seront transmises par Lotus Notes.
Merci.
0