IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Transférer Des Fichiers Volumineux avec Outlook

Cet article vous permet d'installer des composants en VBA dans Outlook pour transférer des fichiers qui dépassent la limite admise par votre fournisseur de messagerie, sans avoir besoin de passer par un service externe de partage de fichiers.

Vous pouvez déposer vos commentaires dans cette discussion.

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Image non disponible

Comment envoyer par Outlook un fichier volumineux en pièce jointe lorsque sa taille dépasse la limite autorisée ?

Car comme indiqué dans la documentation officielle :

« Outlook limite la taille des fichiers que vous pouvez envoyer. Cette limite empêche votre ordinateur de tenter continuellement de charger des pièces jointes très volumineuses qui dépassent les limites définies par la plupart des fournisseurs de services Internet. Pour un compte de courrier Internet tel que Outlook.com ou Gmail, la limite de taille cumulée des fichiers est de 20 mégaoctets (Mo), et, pour des comptes Exchange (courrier professionnel), la limite de taille cumulée des fichiers par défaut est de 10 Mo. »

Certes, il existe des solutions de contournement (issues du même lien) :

« Vous recevez un message d'erreur si vous tentez de joindre des fichiers d'une taille supérieure à la limite de taille maximale. Il existe plusieurs façons de contourner cette limite de taille, notamment en utilisant un service de partage de fichiers ou en compressant le fichier. »

En résumé :

  • Pour un fichier volumineux (c'est-à-dire un fichier qui dépasse la limite admise par votre fournisseur de messagerie), à défaut d'utiliser un service de partage de fichiers, le plus simple est d'utiliser un programme de compression qui permet de découper un fichier en plusieurs « petits » fichiers (lots), par exemple avec 7-Zip, en indiquant « 10M » dans la partie « Diviser en volumes, octets » ce qui compresse le fichier source en plusieurs fichiers de 10 Mo.

Il ne vous restera plus qu'à joindre les fichiers en prenant soin de ne pas en oublier.

  • Lorsque c'est l'ensemble des pièces jointes qui dépasse le quota d'un message, par exemple 20 Mo, il suffit d'envoyer les fichiers en plusieurs messages dont la taille respecte le quota admis, ici aussi en prenant soin de ne pas oublier de fichiers.

Mais normalement avec ce niveau de manipulations, surtout s'il y a plusieurs fichiers volumineux à envoyer, vous devriez avoir perdu la majorité des utilisateurs de votre entreprise, quant à ceux qui vont réussir à se débrouiller ils trouveront l'exercice fastidieux et chronophage.

C'est pourquoi je vous propose dans cette documentation une solution plus simple et plus rapide, qui va réaliser automatiquement tous ces traitements de compression et de découpage des pièces jointes d'un message « hors quota », et les envoyer en un ou plusieurs messages avec Outlook.
Plus précisément, une application en VBA pour Outlook que j'ai nommée TDFV.

Seuls prérequis : disposer d'une version Outlook 2010, 2016 ou 365, et être habilité(e) à activer les macros (normalement c'est le cas), et disposer du programme de compression 7-Zip.

II. Envoyer des fichiers volumineux avec Outlook

Pour joindre un ou des fichiers volumineux à un message en contournant les contraintes que nous venons de voir dans l'introduction, j'ai opté pour cette solution qui conserve une ergonomie très proche de celle utilisée ordinairement par les utilisateurs :

  • l'utilisateur rédige son message et ajoute des pièces jointes comme d'ordinaire ;
  • si un fichier dépasse le quota admis ou génère un message trop volumineux, le fichier n'est pas attaché, mais juste une « image » de quelques octets, reprenant le nom du fichier précédé du repère « ~~ » (deux tildes) ;
  • puis il clique sur « Envoyer » comme à son habitude : les fichiers hors quotas sont automatiquement compressés en plusieurs lots de la taille admise, et si besoin plusieurs messages sont générés pour respecter la limite imposée.

Exemple

Pendant la rédaction d'un message, le bouton « Joindre un fichier » du ruban permet de sélectionner un ou des fichiers à joindre au message. Ne vous fiez pas aux apparences, c'est en fait un bouton personnalisé qui lance une procédure en VBA de sélection de fichiers. Ceci afin d'intercepter les fichiers sélectionnés et vérifier leur taille avant leur attachement, ce que le bouton standard ne permet pas de faire.
Le bouton standard est masqué pour éviter son utilisation, nous y reviendrons plus loin.

Ce qui ouvre un explorateur pour sélectionner les fichiers à joindre :

Image non disponible

Cette opération est exécutée autant de fois qu'il le faut pour sélectionner les fichiers désirés, situés parfois dans différents répertoires.
S'ils sont trop volumineux, les fichiers attachés ne sont pas les fichiers sélectionnés mais juste une « image » de quelques octets, reprenant le nom du fichier précédé du repère « ~~ ».
Sinon, ils sont attachés comme d'habitude, c'est donc transparent pour l'utilisateur.
Ces pièces jointes peuvent être supprimées en cas d'erreur, comme pour les pièces jointes classiques.

Image non disponible

Quand l'utilisateur clique sur « Envoyer » les fichiers volumineux sont compressés et découpés en plusieurs lots, une boîte informe l'utilisateur sur l'avancement du traitement :

Image non disponible

Une boîte annonce la fin de la génération des différents messages :

Image non disponible

Les fichiers envoyés sont enregistrés dans le dossier « Éléments envoyés », comme pour tout autre message ordinaire (si Outlook est configuré de la sorte) :

Image non disponible

Notez que chaque objet du message est précédé du libellé « [TDFV: x à y / z] » où x et y indiquent les numéros des fichiers dans le message et z le nombre total de fichiers à transmettre, ceci afin que le destinataire s'assure avoir reçu tous les fichiers.
Ici « 1 à 3 / 5 » signifie que le message contient les fichiers 1, 2 et 3 sur les 5 fichiers à recevoir.
Les fichiers volumineux étant compressés en plusieurs lots, il y a ici 5 fichiers à transférer pour reconstituer les 4 fichiers d'origine.
Une pièce jointe est ajoutée à chaque envoi. Elle est d'extension « .TDFV » et contient la référence unique de traitement qui permettra par la suite d'identifier un transfert de fichiers volumineux.

Vous remarquerez que les fichiers compressés avec 7-Zip en plusieurs lots portent en extension « .zip.001 » à « .zip.nnn », nous y reviendrons plus tard dans cette documentation.

Et si vous ne disposez pas de 7-Zip ?
La procédure est identique. Les fichiers volumineux sont compressés avec Windows (l'équivalent du clic droit qui ouvre le menu contextuel « Envoyer vers / Dossier compressé », voir l'annexe 1) puis, si besoin, sont découpés en plusieurs lots reconnaissables par leur extension « .P000 » à « .Pnnn » (voir l'annexe 2).

III. Recevoir des fichiers volumineux avec Outlook

Nous venons d'étudier l'envoi des fichiers volumineux, parfois en plusieurs messages.
Voyons maintenant comment ça se passe du côté du destinataire.

En fait, rien de spécial non plus ici. Le destinataire détache les pièces jointes dans le dossier de son choix (sauf celle d'extension « .TDFV ») comme d'ordinaire, en s'assurant qu'il a bien reçu l'intégralité des fichiers attendus. C'est facile, car l'objet des messages contient le libellé « [TDFV: x à y / z] » où x et y indiquent les numéros des fichiers dans le message et z le nombre total de fichiers à recevoir.

Et pour décompresser les fichiers compressés en lots avec 7-Zip d'extension « .zip.001 » à « .zip.nnn », pas de problème, il suffit de décompresser le fichier « .zip.001 » qui retrouvera automatiquement les autres « zip » qui lui sont associés.
L'utilisateur peut archiver ces messages dans le dossier de son choix, comme il le ferait avec des messages ordinaires.

Pour automatiser tout cela, j'ai développé trois fonctions que vous retrouverez dans le groupe « TDFV » du ruban lorsque vous ouvrez un message :

Le premier bouton « Récupérer les fichiers » permet d'extraire tous les fichiers d'un transfert de fichiers volumineux (ceux comportant le libellé clé « [TDFV:] » du message en cours de lecture) et de décompresser automatiquement ceux d'extension « .zip.nnn » (et recomposer ceux d'extension « .Pnnn »).
Ces fichiers sont enregistrés dans le répertoire de l'utilisateur « Transfert Des Fichiers Volumineux\Réceptions ».
L'explorateur s'ouvre automatiquement à la fin du traitement, ce qui permet à l'utilisateur de les visualiser.

Le second bouton « Archiver les messages » déplace tous les fichiers d'un transfert de fichiers volumineux dans le dossier Outlook que choisit l'utilisateur.

Le troisième bouton « Faire suivre les messages » permet de faire suivre tous les fichiers d'un transfert de fichiers volumineux à d'autres destinataires. C'est l'équivalent de « Transférer » pour les messages classiques.


Exemple 1 :

L'utilisateur a reçu plusieurs messages suite à un transfert de fichiers volumineux. Il ouvre l'un de ces messages (pas forcement le premier) et clique sur le bouton « Récupérer les fichiers » :

Image non disponible

Outlook reconnaît automatiquement tous les messages du dossier actif contenant les fichiers du transfert, et décompresse les fichiers volumineux.
Une boîte informe l'utilisateur sur l'avancement du traitement :

Image non disponible

Puis ouvre l'explorateur sur le dossier de réception :

Image non disponible


Exemple 2 :

Le bouton « Archiver les messages » ouvre la liste des dossiers disponibles :

Image non disponible

L'utilisateur sélectionne le dossier de son choix et clique sur « OK » pour déplacer tous les messages du transfert en cours de lecture :

Image non disponible


Exemple 3 :

L'utilisateur a reçu plusieurs messages suite à un transfert de fichiers volumineux. Il souhaite les faire suivre à un collègue qui en a également besoin. Il ouvre l'un de ces messages (pas forcement le premier) et clique sur le bouton « Faire suivre les messages » :

Image non disponible

Outlook reconnaît automatiquement tous les messages du dossier actif contenant les fichiers du transfert, et détache leurs pièces jointes dans un répertoire temporaire.
Une boîte informe l'utilisateur sur l'avancement du traitement :

Image non disponible

Puis un nouveau message est généré.
Ce message reprend le message d'origine et les images des pièces jointes. Comme pour un clic sur le bouton « Transférer » d'un message classique, l'utilisateur peut compléter le corps du texte, ajouter ou supprimer des pièces jointes, et cliquer sur « Envoyer » après avoir renseigné les destinataires.

Image non disponible

Un nouvel envoi de fichiers volumineux est déclenché, comme vu dans le premier exemple, en tenant compte des limitations de l'utilisateur (qui peuvent être différentes de celles de l'émetteur).

IV. Installer (et désinstaller) TDFV dans Outlook – Automatiquement avec Excel

Si vous disposez d'Excel 2010 ou 2016 (version 32 bits) vous trouverez en annexe le fichier « Installation_TDFV.xlsm » qui automatise l'installation des fonctionnalités et des boutons dans Outlook.
Pensez à activer les macros en lançant ce programme.

Après vérification de la présence d'Outlook (il est ouvert automatiquement s'il était fermé) et de sa disponibilité à être modifié, une boîte vous informe :

Image non disponible

Avant de cliquer sur « Installer l'application TDFV », vous pouvez modifier les valeurs par défaut de la taille maximale d'une pièce jointe et de la taille maximale d'un envoi.

Image non disponible

Par sécurité, veillez à ne pas utiliser la souris et le clavier pendant l'installation des différents composants.
À mesure de l'avancement du traitement, les différentes étapes réalisées correctement se cochent.
Si tout se passe bien, un message vous informe qu'Outlook va être relancé.
Après avoir vérifié que les nouveaux menus sont bien installés, revenez dans Excel pour confirmer la bonne réalisation de l'installation.

Si vous avez reçu un message vous invitant à autoriser les macros, procédez ainsi : dans Outlook sur l'onglet Fichier, sélectionnez Options, Centre de gestion de la confidentialité, Paramètres du Centre de gestion de la confidentialité, Paramètres des macros, et cochez Activer toutes les macros.

Pour désinstaller automatiquement l'application
Lancez ce programme et cliquez sur l'onglet « Désinstaller l'application TDFV », puis sur le bouton correspondant.

V. Installer (et désinstaller) TDFV dans Outlook – Manuellement

Si l'installation automatique par Excel n'est pas possible, vous devrez installer manuellement les fichiers source en VBA et les boutons dans Outlook.
Vous trouverez en annexe quatre fichiers source : « Module_TDFV.bas », « Evenements_TDFV.cls », « UserForm_TDFV.frm » et « UserForm_TDFV.frx », repris dans le fichier « TDFV.zip » qu'il faut décompresser.
Voici comment les installer dans Outlook en quelques manipulations.

En premier lieu il faut ouvrir l'éditeur Visual Basic par la combinaison des touches [Alt]+[F11].
Puis importer les trois fichiers « Module_TDFV.bas », « Evenements_TDFV.cls », « UserForm_TDFV.frm » par le menu « Fichier / Importer un fichier ». Le fichier « UserForm_TDFV.frx » n'est pas à importer, mais sa présence est indispensable pour configurer le formulaire « UserForm_TDFV ».

Quittez l'éditeur et revenez sur l'écran d'accueil pour ajouter maintenant le bouton personnalisé « Joindre un fichier » et les commandes standards « Joindre un élément » et « Signature » au ruban des messages créés :

  • cliquez sur « Nouveau message électronique » ;
  • placez la souris au niveau du ruban et faites un clic droit et cliquez sur « Personnaliser le Ruban » ;
  • dans la partie de droite, « Personnaliser le Ruban », activez « Nouveau message électronique » et cliquez sur « Nouveau groupe » ;
  • dans la partie de gauche, « choisir les commandes dans les catégories suivantes », sélectionnez « Macros » et faites glisser/déposez la macro « Projet 1.TDFV_JoindrePieces » sur le nouveau groupe qui s'est créé, puis cliquez sur « Renommer » ;
  • sélectionnez le symbole de votre choix dans la liste qui s'affiche (par exemple la puce) et modifiez le nom de la macro en « Joindre un fichier » puis validez sur « OK » ;

Image non disponible

  • sélectionnez le nouveau groupe et cliquez sur « Renommer » pour le renommer en « Inclure » (il n'est pas nécessaire de choisir un symbole, car aucune icône ne sera affichée) ;
  • dans la partie de gauche, « Choisir les commandes dans les catégories suivantes », sélectionnez maintenant « Toutes les commandes » et faites glisser/déposez les commandes « Joindre un élément » et « Signature » sur le groupe « Inclure (personnalisé) » ;
  • utilisez les flèches de la partie droite pour remonter le groupe créé sous le groupe « Inclure » ;
  • sélectionnez le groupe « Inclure » et cliquez sur « Supprimer » ;

Image non disponible

  • validez vos modifications du ruban en cliquant sur « OK » en bas à droite.

Le ruban est modifié et doit ressembler à cela :

Image non disponible

Le choix des icônes proposées par Outlook est restreint, mais une astuce permet d'en changer en modifiant le fichier de configuration du ruban (au format XML). Ici c'est le fichier « olkmailitem.officeUI » qui se trouve :

  • soit dans « C:\Users\USER\AppData\Local\Microsoft\Office » ;
  • soit dans « C:\Users\USER\AppData\Roaming\Microsoft\Office ».

Ouvrez ce fichier avec un éditeur tel que le bloc-notes et repérez l'emplacement de l'icône (imageMso) utilisée (dans notre exemple c'est l'icône « Pushin »).

Image non disponible

Remplacez le nom (« Pushin » dans notre exemple) par « AttachFile » et fermez le bloc-notes en enregistrant.

Vous trouverez la galerie des imagesMso à cette adresse : https://codekabinett.com/download/Microsoft-Office-2010-imageMso-Gallery.pdf

Après avoir ouvert un message pour accéder à son ruban, procédez de la même façon pour ajouter les boutons « Récupérer les fichiers », « Archiver les messages » et « Faire suivre les messages » au ruban.

Les macros concernées sont respectivement : « Projet 1.TDFV_Extraction », « Projet 1.TDFV_Archiver » et « Projet 1.TDFV_FaireSuivre », à glisser dans le groupe à créer « TDFV ».

Le fichier de configuration du ruban est « olkmailread.officeUI ».
Les imageMso que j'ai utilisées sont : « GroupControls » pour récupérer les fichiers, « CreateMailRule » pour les archiver, et « ForwardAsAttachment » pour les faire suivre.

La dernière étape est d'activer les macros : dans Outlook sur l'onglet Fichier, sélectionnez Options, Centre de gestion de la confidentialité, Paramètres du Centre de gestion de la confidentialité, Paramètres des macros, et cochez Activer toutes les macros.

Image non disponible

Quittez Outlook en confirmant l'enregistrement du projet VBA.

Pour désinstaller manuellement l'application

  • Pour le code : ouvrir l'éditeur Visual Basic et pour chacun des éléments « UserForm_TDF », « Module_TDFV », « Evenements_TDFV » faire un clic droit et choisir « Supprimer… ».
  • Pour les boutons : ouvrir la personnalisation des deux rubans comme vu ci-dessus pour sélectionner les groupes créés et cliquer sur « Supprimer » ;
  • pour réinstaller les commandes standards du groupe « Inclure » : dans la partie de gauche, « choisir les commandes dans les catégories suivantes », sélectionnez « Onglets principaux » puis « Nouveau message électronique » et sélectionnez « Inclure » et glisser/déposez sous le groupe « Noms ».

Image non disponible

  • Validez vos modifications du ruban en cliquant sur « OK » en bas à droite.

Quittez Outlook sans oublier d'enregistrer le projet VBA.

Pour modifier la configuration
Par défaut, la taille maximale d'une pièce jointe est de 10 Mo et la taille d'un envoi de 20 Mo. Ces valeurs étant enregistrées dans le registre « ConfigPerso » de l'utilisateur (lors de la première utilisation des macros), elles peuvent être modifiées depuis l'explorateur en tapant « regedit » dans la barre d'adresse (mise ici en surbrillance bleue) :

Image non disponible

Pour modifier la taille maximale d'une pièce jointe : double-cliquez sur « TDFV_TaillePieceJointe ».
Pour modifier la taille maximale d'un envoi : double-cliquez sur « TDFV_TailleCumulee ».

Image non disponible

VI. Remarques sur le code VBA utilisé dans Outlook

Ces quelques remarques sur le code VBA utilisé dans Outlook, sans entrer dans le détail des 1600 lignes du module « Module_TDFV », vous permettront de mieux comprendre pourquoi j'ai retenu certaines solutions.

  • Un clic sur « Joindre un fichier » lance la procédure « TDFV_JoindrePieces ».

Cette procédure ouvre un explorateur pour sélectionner un ou plusieurs fichiers. Or il n'existe pas dans le VBA Outlook l'équivalent de la boîte de dialogue FileDialog(msoFileDialogFilePicker) bien connue dans le VBA Excel.
Une solution de contournement consiste à créer une session Excel et l'utiliser pour appeler cette boîte de dialogue. Voir ici.
Seulement, j'ai constaté que parfois, et sans comprendre pourquoi, cet appel faisait planter Outlook. J'ai donc recherché une autre solution, et trouvé l'API GetOpenFileName. Voir ici pour la source d'inspiration et ici pour la configuration. Son usage est simplifié par la fonction GetOpenFile qui permet l'ajout d'éventuels filtres (option non utilisée dans cette application).

Pour chaque sélection faite, un contrôle de la taille des pièces jointes existantes et du fichier à joindre est réalisé :

 
Sélectionnez
For Each PJ In ActiveInspector.CurrentItem.Attachments
    TaillePJ = TaillePJ + PJ.Size
Next PJ

Si les quotas sont respectés (avec une marge de sécurité de 1 Mo incluse dans TailleMaxi et TailleMaxiCumulee) le fichier est attaché :

 
Sélectionnez
If FileLen(Fichiers(i)) < TailleMaxi  _
And FileLen(Fichiers(i)) + TaillePJ < TailleMaxiCumulee  Then
        
            ActiveInspector.CurrentItem.Attachments.Add Fichiers(i)

Sinon un fichier texte est créé dans le répertoire temporaire de l'application. Ce fichier ne contient que le chemin et le nom du fichier sélectionné :

 
Sélectionnez
Set f = CreateObject("Scripting.FileSystemObject").CreateTextFile(DossierTDFV & "~~" & StrNom & "." & StrExtension, True)
f.WriteLine (Fichiers(i))
f.Close

Et c'est ce fichier qui est ajouté aux pièces jointes du message actif :

 
Sélectionnez
ActiveInspector.CurrentItem.Attachments.Add DossierTDFV & "~~" & StrNom & "." & StrExtension

Par la suite, la lecture de cette image permettra de connaître les fichiers à compresser (chemin et nom) et à joindre au message.
Puis cette procédure initialise l'événement ItemSend : « qui survient à chaque envoi d'éléments Microsoft Outlook, que ce soit par l'utilisateur … ou lorsque la méthode Send est utilisée dans un programme pour un élément Outlook, par exemple MailItem ».

 
Sélectionnez
Set MyClassTDFV.MyOlAppTDFV = Outlook.Application

Contenu dans le module de classe « Evenements_TDFV » :

 
Sélectionnez
'--------------------------------------------------------------------------------------------------
Private Sub MyOlAppTDFV_ItemSend(ByVal Item As Object, Cancel As Boolean)
'--------------------------------------------------------------------------------------------------
Cancel = Main_TDFV(Item)
End Sub

C'est ce qui permettra d'intercepter un clic de l'utilisateur sur le bouton « Envoyer » et lancera la procédure publique « Main_TDFV » (du module Module_TDFV) qui se chargera d'analyser les pièces jointes et de découper les fichiers volumineux si besoin. Elle retourne « Vrai » en cas d'erreur ce qui annule l'envoi (car Cancel = True).

Il est possible d'initialiser l'événement à l'ouverte d'Outlook, avec la procédure Application_Startup placée dans ThisOutlookSession, mais cela nécessite d'intervenir dans cet objet qui peut contenir d'autres instructions, ce qui n'est pas sans risque.

À noter : à chaque message généré contenant des fichiers volumineux, une référence de traitement est attribuée sous la forme d'une pièce jointe attachée au message d'extension « .TDFV ». Ceci pour retrouver par la suite tous les messages qui constituent le même envoi volumineux, et partagent donc cette référence.
Je me sers de cette méthode, car Outlook ne propose pas une propriété « commentaire » disponible pour les programmeurs qui puisse être enregistrée et liée au message. Il existe bien la propriété FlagRequest, mais l'inconvénient est qu'elle est effacée lorsque l'utilisateur met un suivi sur le message (les drapeaux du menu « Assurer un suivi »).

  • Utilisation de 7-Zip pour compresser un fichier en plusieurs fichiers.

La fonction Shell permet de lancer l'exécutable « 7z.exe » avec une ligne de commande qui contient les informations nécessaires, mais elle a l'inconvénient d'être asynchrone, la suite du code VBA s'exécute alors que 7-Zip n'a pas terminé son traitement. Or, savoir quand la compression est terminée est indispensable pour envoyer les messages avec leurs pièces jointes correctement compressées.
L'astuce que j'ai retenue est d'utiliser les API OpenProcess et GetExitCodeProcess qui permettent de savoir quand un processus est terminé et donc de rendre Shell synchrone. Ce qui donne le code simplifié :

 
Sélectionnez
StrCommand = Chr(34) & ZipExe & Chr(34) & " a -tzip " _
            & Chr(34) & StrDossierDest & StrNom & ".zip" & Chr(34) & " " _
            & Chr(34) & StrFichier & Chr(34) _
            & " -v" & TailleMo & "m -sdel"

ShellAndWait(StrCommand, vbHide)

Où les variables représentent : 

  • ZipExe = le chemin et nom de l'exécutable (par exemple « C:\Program Files\7-Zip\7z.exe »). 
  • StrDossierDest = le dossier destination. 
  • StrNom = le nom du fichier, sans l'extension .zip qui est ajoutée. 
  • StrFichier = le chemin et le nom du fichier source. 
  • TailleMo = la taille maximale d'un fichier en Mo. 

Chr(34) correspond aux guillemets.

 
Sélectionnez
'-----------------------------------------------------------------------------------------------------
Public Function ShellAndWait(ByVal ShellStr As String, ByVal WindowState) As Long
'-----------------------------------------------------------------------------------------------------
Dim hProg As Long, hProcess As Long, ExitCode As Long
    
hProg = Shell(ShellStr, WindowState)
hProcess = OpenProcess(&H400, False, hProg) ' PROCESS_QUERY_INFORMATION
   
Do
    GetExitCodeProcess hProcess, ExitCode
    DoEvents
Loop While ExitCode = &H103 'STILL_ACTIVE

End Function
  • Un clic sur « Récupérer les fichiers » lance la procédure « TDFV_Extraction ».

La première opération consiste à identifier la référence de traitement du message actif. Puis à boucler sur les messages de la boîte active à la recherche des messages contenant une référence de traitement compatible.
Vient ensuite le traitement des pièces jointes de chacun des messages pour les décompresser avec 7-Zip (ou les recomposer s'ils ont été découpés) dans un fichier temporaire sur le disque dur.
Les fichiers « .zip » sont supprimés, les fichiers définitifs sont déplacés dans le répertoire « Réceptions », puis l'explorateur est ouvert sur ce répertoire, sur le principe du répertoire « Téléchargements ».
L'utilisateur peut consulter les fichiers, les déplacer, les supprimer.

Vous remarquerez que si un utilisateur réceptionne des fichiers compressés par 7-Zip d'extension « .zip.nnn », il peut toujours les décompresser manuellement avec un logiciel compatible, mais pour les fichiers découpés (ceux d'extension « .Pnnn »), il lui faut impérativement l'application TDFV pour les reconstituer.

  • Utilisation de 7-Zip pour décompresser un fichier.

Ici aussi ShellAndWait est utilisée pour lancer l'exécutable « 7z.exe » de façon synchrone, dans une fenêtre active, mais masquée :

 
Sélectionnez
'----------------------------------------------------------------------------------------
Private Function TDFV_UnZip(StrSource As String, StrDest As String) As Long
'----------------------------------------------------------------------------------------
Dim StrCommand As String

StrCommand = Chr(34) & ZipExe & Chr(34) & " e " _
            & Chr(34) & StrSource & Chr(34) _
            & " -o" _
            & Chr(34) & StrDest & Chr(34) & ""
            
TDFV_UnZip = ShellAndWait(StrCommand, vbHide)

End Function

Le fichier à décompresser ayant été préalablement détaché sur le disque dur, le traitement prend rarement plus de deux secondes. Puis l'explorateur est lancé :

 
Sélectionnez
Call Shell("Explorer.exe " & DossierReception, vbMaximizedFocus)
  • Un clic sur « Archiver les messages » lance la procédure « TDFV_Archiver ».

Là aussi, la première chose à faire est d‘identifier la référence de traitement du message actif. Puis à boucler sur les messages de la boîte active à la recherche des messages contenant une référence de traitement compatible.
La sélection d'un dossier de destination peut se faire, cette fois, à l'aide d'une fonction du VBA Outlook :

 
Sélectionnez
Dim OLF As Outlook.MAPIFolder
Set OLF = olApp.GetNamespace("MAPI").PickFolder
Dim myDestFolder As Outlook.Folder
Set myDestFolder = GetFolder(OLF.FolderPath) ' GetFolder : exemples dans la documentation Outlook.

Le dossier source est connu :

 
Sélectionnez
Dim MaBoite As Outlook.Folder 
Set MaBoite = ActiveExplorer.CurrentFolder

Chaque message est déplacé (en commençant par la fin et remontant vers le début pour ne pas en oublier) :

 
Sélectionnez
For i = MaBoite.Items.Count To 1 Step -1
    MaBoite.Items(i).Move myDestFolder
Next i
  • Un clic sur « Faire suivre les messages » lance la procédure « TDFV_FaireSuivre ».

Après avoir identifié la référence de traitement du message actif, un nouveau message de type Forward est généré :

 
Sélectionnez
Dim ObjMail As MailItem
Set ObjMail = ActiveInspector.CurrentItem.Forward

Il faut supprimer les pièces jointes qui ont été reprises automatiquement du message actif (en commençant par la fin et remontant vers le début pour ne pas en oublier) :

 
Sélectionnez
For i = ObjMail.Attachments.Count To 1 Step -1
    ObjMail.Attachments(i).Delete
Next i

Le dossier actif est connu :

 
Sélectionnez
Dim MaBoite As Outlook.Folder
Set MaBoite = ActiveExplorer.CurrentFolder

Puis l'on boucle sur les éléments de ce dossier à la recherche des autres messages qui partagent la référence de traitement, et dans ce cas, détacher les pièces jointes dans un dossier temporaire et les attacher au nouveau message créé : soit intégralement, soit uniquement leur image s'ils sont volumineux.

 
Sélectionnez
' Boucle sur la boîte active pour détacher les messages :
For i = 1 To MaBoite.Items.Count
    ' Si le message contient le mot clé:
     If Left(ReferenceTDFV(MaBoite.Items(i)), 21) = Left(StrRéférence, 21) Then
         ' Détache les pièces jointes:
         For Each PJ In MaBoite.Items(i).Attachments
             If Right(PJ.FileName, 5) <> ".TDFV" Then
                 PJ.SaveAsFile DossierFaireSuivre & PJ.FileName
                 DoEvents
                 ' Décompose le fichier:
                 Call DétailFichier(DossierFaireSuivre & PJ.FileName, StrRépertoire, StrNom, StrExtension)
                 ' Compte la taille des pièces jointes existantes:
                 TaillePJ = 0
                 For Each NewPJ In ObjMail.Attachments
                     TaillePJ = TaillePJ + NewPJ.Size
                     If Left(NewPJ.FileName, 2) = "~~" Then TaillePJ = TailleMaxiCumulee + 1
                 Next NewPJ
                 ' Si taille du fichier + taille pièces existantes le permet alors attache:
                 If FileLen(DossierFaireSuivre & PJ.FileName) < TailleMaxi _
                 And FileLen(DossierFaireSuivre & PJ.FileName) + TaillePJ < TailleMaxiCumulee Then
                     ObjMail.Attachments.Add DossierFaireSuivre & PJ.FileName
                 ' Sinon attache l'image et pas le fichier:
                 Else
                     ' Fait une image:
                     Set f = CreateObject("Scripting.FileSystemObject").CreateTextFile(DossierTDFV & "~~" & StrNom & "." & StrExtension, True)
                     f.WriteLine (DossierFaireSuivre & PJ.FileName)
                     f.Close
                     Set f = Nothing
                     ' Et attache cette image (au lieu du fichier):
                     ObjMail.Attachments.Add DossierTDFV & "~~" & StrNom & "." & StrExtension
                 End If
             End If
         Next PJ
     End If
Next i
 
Sélectionnez
'--------------------------------------------------------------------------------
Private Function ReferenceTDFV(ByVal Item As Object) As String
'--------------------------------------------------------------------------------
Dim i As Long
If Item.Class <> Olmail Then Exit Function
' Analyse les pièces jointes du message et retourne la référence TDFV:
For i = 1 To Item.Attachments.Count
    If Right(Item.Attachments(i).fileName, 5) = ".TDFV" Then
        ReferenceTDFV = Left(Item.Attachments(i).fileName, Len(Item.Attachments(i).fileName) - 5)
        Exit For
    End If
Next i
End Function

VII. Remarques sur le code VBA utilisé pour l'installation automatique avec Excel

S'il est possible depuis certains langages de programmation de créer une cession Outlook pour naviguer dans ses dossiers, ses messages et autres éléments, le VBA Outlook n'a pas d'instruction pour importer un fichier ou personnaliser le ruban. Créer une cession Outlook n'est alors d'aucun recours.
La seule façon d'installer l'application TDFV est de simuler les mêmes interventions clavier que celles réalisées manuellement. Par exemple importer un fichier correspond à la combinaison des touches [Alt]+[F11] pour ouvrir l'éditeur Visual Basic, [Ctrl]+[m] pour ouvrir la boîte de dialogue d'importation, renseigner le chemin et nom du fichier, tabuler deux fois et envoyer [Entrée].
Pour simuler ces interventions j'ai utilisé Excel, mais il est possible de réaliser la même chose avec d'autres langages de programmation.

Avec Excel l'envoi de touches peut se faire avec l'instruction SendKeys du VBA, mais j'ai préféré utiliser les API :

  • pour trouver le handle (numéro attribué par le système à une application) de la fenêtre concernée et donner le focus à cette fenêtre avant de lui simuler une intervention clavier ;
  • pour envoyer une combinaison de touches, j'utilise l'API keybd_event qui reconnaît les constantes des touches vbKeys : [Alt] = vbKeyMenu ; [F11] = vbKeyF11 ; [Ctrl] = vbKeyControl ; [m] = vbKeyM ;
  • pour envoyer une chaîne, j'ai repris la solution utilisée pour CryptoVBA : copier la chaîne dans le presse-papiers, puis la coller avec [Ctrl]+[v].

Vous retrouverez toutes ces API, et les fonctions développées pour les utiliser facilement, dans le module « Module_API ».
Et bien d'autres fonctions. Exemples…
La fonction Hdc_EnumérationHandle alimente la variable EnumChildListe() de la liste des noms des boutons d'une fenêtre et retourne le nombre de boutons.
Je m'en sers après avoir quitté Outlook pour m'assurer que la fenêtre de confirmation d'enregistrement du projet, qui contient les trois boutons « Oui, Non, Annuler » s'ouvre, preuve que le traitement s'est déroulé correctement. Ne reste alors qu'à « cliquer » le premier bouton avec la fonction Hdc_BoutonCliquer pour enregistrer les modifications.
La fonction RegScanKey scanne les clés du registre de l'utilisateur pour retrouver l'emplacement de la clé Outlook\Security\Level où est enregistré le niveau de sécurité d'accès aux macros (cet emplacement change suivant les versions d'Outlook). La fonction OutlookSecurity modifie cette clé à 1 pour forcer l'autorisation.

La mise à jour du ruban se fait en modifiant les fichiers de configuration olkmailitem et olkmailread.
Si le fichier n'existe pas, il faut le créer (au format XML) ; s'il existe, plusieurs situations sont possibles :

  • il n'y a pas encore le groupe TDFV : on recherche la position de la balise TabNewMailMessage ou TabReadMessage pour savoir où ajouter le code du nouveau groupe ;
  • le groupe existe déjà (cas d'une mise à jour) : on remplace la partie Visible = Faux par Visible = Vrai.

Pour désinstaller le groupe, il n'est pas nécessaire de supprimer le code, il suffit de remplacer la partie Visible = Vrai par Visible = Faux.
Le groupe « Inclure » standard se nomme GroupIncludeMainTab.
Toutes les fonctions sont dans le module « Module_Outlook ».

Le dernier module de l'application, « Module_Fichiers », contient les fonctions pour :

  • copier, en binaire dans une feuille de calcul, les fichiers source à importer dans Outlook ;
  • reconstituer les fichiers source à partir des données binaires stockées dans la feuille.

Cette méthode permet de n'avoir qu'un fichier à télécharger pour l'installation automatique.

VIII. Conclusion

Nous venons de voir dans cette documentation qu'il est possible avec Outlook d'envoyer des fichiers volumineux (c'est-à-dire hors des quotas admis par votre fournisseur de messagerie) en les découpant en plusieurs fichiers et si besoin en les envoyant en plusieurs messages ; soit manuellement pour un usage ponctuel, soit de façon automatisée à l'aide du VBA de l'application TDFV.

Avant d'installer l'application TDFV, je vous invite à contacter votre administrateur pour vous assurer que vous êtes en conformité avec les règles de sécurité et les consignes de votre entreprise si vous utilisez Outlook pour le transfert de fichiers volumineux au lieu d'un service de partage.

À noter : la taille des quotas dépend de votre fournisseur de messagerie et peut varier des exemples présentés ici, qui sont les valeurs minimales des anciens standards.

Celles et ceux qui vont s'intéresser au code VBA utilisé par l'application TDFV et qui ne sont pas habitués à programmer sous Outlook trouveront une foule d'astuces dans la « FAQ Outlook » de developpez.com : https://outlook.developpez.com/faq/
Je n'ai pas souhaité ici détailler davantage le code de l'application, car la FAQ très fournie, et qui m'a permis de réaliser une grande partie du code, répondra à toutes vos interrogations.
Quant aux débutants en VBA, je les invite à consulter le tome 1 de mes mémentos pour acquérir les bases de la programmation.

Attention, vous devez disposer de 7-Zip (version 4.14 de 2005 ou supérieure, voir ici) pour profiter de l'option qui permet de compresser un fichier en plusieurs lots, ce qui est utilisé par l'application pour optimiser l'envoi des pièces jointes volumineuses.
En cas de besoin vous pouvez télécharger une version récente sur ce site : https://www.7-zip.fr/.

Les tests ont été réalisés sous Windows 10 avec Outlook 2010, 2016 et 365, et Excel 2010 et 2016 versions 32 bits.

Laurent OTT.
2021.

IX. Fichiers Joints

Les codes source des modules à importer dans Outlook pour une installation manuelle de l'application TDFV, contenus dans le fichier « TDFV.zip » :

  • Module_TDFV.bas ;
  • Evenements_TDFV.cls ;
  • UserForm_TDFV.frm ;
  • UserForm_TDFV.frx.

Un fichier pour Excel 32 bits qui contient les macros pour une installation (et une désinstallation) automatique de l'application TDFV :

X. Annexe 1 – Compresser et décompresser un fichier avec Windows

Il existe une autre méthode en VBA pour compresser et décompresser un fichier au format « zip ».
Elle est utilisée dans cette application quand 7-Zip n'est pas présent. Ici aussi le traitement est asynchrone. Donc pour s'assurer que la compression est terminée, il faut boucler dans la cible en testant la présence du fichier source, avec une durée maximale (par exemple de 30 secondes) pour sortir de la boucle au cas où l'utilisateur clique sur le bouton « Annuler » de la boîte de dialogue qui s'ouvre lors de la compression des gros fichiers (qu'il est impossible de ne pas afficher en VBA).
Le principe pour compresser : un fichier est créé, ne contenant que les 23 caractères d'en-tête d'un zip. La source à compresser est copiée dans ce fichier avec CopyHere. Windows reconnaît le format zip et fait l'équivalent du clic droit qui ouvre le menu contextuel « Envoyer vers / Dossier compressé ».
Le principe pour décompresser : la méthode CopyHere est utilisée en indiquant la source et la destination.
Plus d'informations ici.
Un code simplifié, mais opérationnel :

 
Sélectionnez
'---------------------------------------------------------------------------------------
Public Sub ShellZip(ByVal ZipArchivePath As String, ByVal AddPath As String)
'---------------------------------------------------------------------------------------
' ZipArchivePath = Le fichier zip à créer (chemin + non).
' AddPath = Soit un fichier source (chemin + nom) soit un répertoire (sans le \ final).
' Exemple : call ShellZip("C:\_Temporaire\Test.zip", "C:\ADO_FiduLSB\ADO_FiduLSB_Bases_3.accdb")
' Remarque : Si le fichier est trop long à compresser, une boîte de message système s'affiche.
'---------------------------------------------------------------------------------------
Dim ShellApp As Object, fSource As Object, fTarget As Object, iSource As Object, SourceItem As Object
Dim i As Long, lTimer As Variant, ContainingFolder As String, ItemToZip As String

If Dir(ZipArchivePath) <> "" Then Kill ZipArchivePath

Set ShellApp = CreateObject("Shell.Application")
CreateZipFile ZipArchivePath
Set fTarget = ShellApp.Namespace((ZipArchivePath))

ContainingFolder = Left(AddPath, InStrRev(AddPath, "\"))
ItemToZip = Mid(AddPath, InStrRev(AddPath, "\") + 1)

Set fSource = ShellApp.Namespace((ContainingFolder))
For i = 0 To fSource.Items.Count - 1
    If fSource.Items.Item((i)).Name = ItemToZip Then
        Set SourceItem = fSource.Items.Item((i))
        Exit For
    End If
Next i

fTarget.CopyHere SourceItem

lTimer = Timer
Do
    DoEvents
Loop While fTarget.Items.Count <> 1 And lTimer + 30 > Timer

End Sub

'---------------------------------------------------------------------------------------
Private Sub CreateZipFile(ByVal fileName As String)
'---------------------------------------------------------------------------------------
Dim FileNo As Integer
Dim ZIPFileEOCD(0 To 22) As Byte

ZIPFileEOCD(0) = Val("&H50") ' 80
ZIPFileEOCD(1) = Val("&H4b") ' 75
ZIPFileEOCD(2) = Val("&H05") '  5
ZIPFileEOCD(3) = Val("&H06") '  6

FileNo = FreeFile
Open fileName For Binary Access Write As #FileNo
Put #FileNo, , ZIPFileEOCD
Close #FileNo

End Sub

'---------------------------------------------------------------------------------------
Public Sub ShellUnZip(ZippedFileFullName As Variant, UnzipToPath As Variant)
'---------------------------------------------------------------------------------------
' ZippedFileFullName = chemin + nom du fichier .zip
' UnzipToPath = répertoire de destination.
' Exemple : call UnzipAFile("C:\_Temporaire\Test.zip", "C:\_Temporaire")
'---------------------------------------------------------------------------------------
Dim ShellApp As Object

Set ShellApp = CreateObject("Shell.Application")
ShellApp.Namespace(UnzipToPath).CopyHere ShellApp.Namespace(ZippedFileFullName).Items

End Sub

XI. Annexe 2 – Découper un fichier en lots et le recomposer

La compression au format zip vu ci-dessus avec ShellZip ne permet pas de compresser un fichier en plusieurs lots, comme le fait 7-Zip. L'idée ici est de découper soi-même un fichier par lots. Les lots seront d'extension Pnnn, où P000 est un fichier qui ne contient que le nom du fichier source, son extension, la taille des lots (en octets), la taille du fichier source, le nombre de lots générés.
Passez en arguments de la fonction DecoupeFichier : l'adresse du fichier à compresser ; la taille en Mo des lots.
Pour recomposer le fichier source, passez en argument de la fonction RecomposeFichier l'adresse du P000.
Un code simplifié, mais opérationnel :

 
Sélectionnez
'---------------------------------------------------------------------------------------
Type RecordP000
    Nom As String * 255
    Extension As String * 16
    TaillePaquet As Long
    TailleTotale As Long
    NbPaquets As Integer
End Type

'---------------------------------------------------------------------------------------
Public Sub DecoupeFichier(StrFichier As String, TailleMo As Long)
'---------------------------------------------------------------------------------------
Dim EnteteP000 As RecordP000
Dim FileNumberSource As Long, FileNumberDest As Long
Dim LenSource As Long, LenCopie As Long
Dim Paquet As Integer, i As Integer
Dim StrRépertoire As String, StrNom As String, StrExtension As String
Dim RecordUnK As String * 1024
Dim TailleMaxi As Long

' Conversion en Mo:
TailleMaxi = TailleMo * 1024 * 1024
       
' Décompose StrFichier en répertoire, nom, extension:
StrRépertoire = Left(StrFichier, InStrRev(StrFichier, "\"))
StrNom = Mid(StrFichier, InStrRev(StrFichier, "\") + 1)
StrNom = Left(StrNom, InStrRev(StrNom, ".") - 1)
StrExtension = Mid(StrFichier, InStrRev(StrFichier, ".") + 1)

' Ouverture du fichier source par lot de 1 ko:
LenSource = FileLen(StrFichier)
FileNumberSource = FreeFile
Open StrFichier For Random As #FileNumberSource Len = Len(RecordUnK)

' Boucle sur le fichier en lisant 1024 octets à la fois (et pas un à un):
While LenCopie < LenSource

    ' Création du fichier (paquet) Destination si besoin,
    ' c'est-à-dire, 1er paquet ou taille maxi de l'ancien atteinte:
    If LenCopie Mod TailleMaxi = 0 Then
        If Paquet > 0 Then Close #FileNumberDest
        Paquet = Paquet + 1
        FileNumberDest = FreeFile
        Open StrRépertoire & StrNom & ".P" & Format(Paquet, "000") For Random As #FileNumberDest Len = Len(RecordUnK)
    End If
        
    ' Lecture du fichier source:
    Get #FileNumberSource, , RecordUnK
    
    ' Ecriture dans le fichier destination:
    Put #FileNumberDest, , RecordUnK
        
    LenCopie = LenCopie + Len(RecordUnK)
    
Wend

' Fermeture des fichiers:
Close #FileNumberDest
Close #FileNumberSource

' Enregistrement de l'en-tête:
FileNumberSource = FreeFile
Open StrRépertoire & StrNom & ".P000" For Random As #FileNumberSource Len = Len(EnteteP000)

    EnteteP000.Nom = StrNom & "?"
    EnteteP000.Extension = StrExtension & "?"
    EnteteP000.TaillePaquet = CLng(TailleMo)
    EnteteP000.TailleTotale = CLng(LenSource)
    EnteteP000.NbPaquets = CInt(Paquet)
    ' Ecriture dans le fichier P000:
    Put #FileNumberSource, , EnteteP000
    
Close #FileNumberSource

End Sub
'---------------------------------------------------------------------------------------
 
Sélectionnez
---------------------------------------------------------------------------------------
Public Sub RecomposeFichier(ByRef StrFichier As String)
'---------------------------------------------------------------------------------------
Dim EnteteP000 As RecordP000
Dim FileNumberSource As Long, FileNumberDest As Long, LenSource As Long, LenCopie As Long
Dim Paquet As Integer, i As Long, Taille As Long, TailleTotale As Long
Dim StrRépertoire As String, StrNom As String, StrExtension As String, 
Dim RecordUnK As String * 1024

' Lecture de l'en-tête:
FileNumberSource = FreeFile
Open StrFichier For Random As #FileNumberSource Len = Len(EnteteP000)

    Get #FileNumberSource, , EnteteP000
    StrNom = EnteteP000.Nom
    StrExtension = EnteteP000.Extension
    Taille = EnteteP000.TaillePaquet
    TailleTotale = EnteteP000.TailleTotale
    Paquet = EnteteP000.NbPaquets

Close #FileNumberSource

' Décompose StrFichier en nom, extension, répertoire:
StrNom = Left(StrNom, InStr(1, StrNom, "?") - 1)
StrExtension = Left(StrExtension, InStr(1, StrExtension, "?") - 1)
StrRépertoire = Left(StrFichier, InStrRev(StrFichier, "\"))

'  Conversion en Mo:
Taille = Taille * 1024 * 1024

' Ouverture du fichier Destination d'extension provisoire ".~":
FileNumberDest = FreeFile
Open StrRépertoire & StrNom & ".~" For Random As #FileNumberDest Len = Len(RecordUnK)
Paquet = 0

' Boucles sur les différents paquets par lot de 1024 octets (1 ko):
While LenCopie < TailleTotale

    ' Ouverture du fichier Source, c'est-à-dire le premier paquet ou le suivant
    ' quand la taille maxi est atteinte:
    If LenCopie Mod Taille = 0 Then
        ' Fermeture de l'ancien paquet:
        If Paquet > 0 Then Close #FileNumberSource
        ' Ouverture du nouveau paquet:
        Paquet = Paquet + 1
        FileNumberSource = FreeFile
        Open StrRépertoire & StrNom & ".P" & Format(Paquet, "000") For Random As #FileNumberSource Len = Len(RecordUnK)
    End If

    ' Lecture de la source:
    Get #FileNumberSource, , RecordUnK

    ' Cas particulier pour la fin:
    If TailleTotale - LenCopie < Len(RecordUnK) Then
        Close #FileNumberDest
        FileNumberDest = FreeFile
        Open StrRépertoire & StrNom & ".~" For Binary As #FileNumberDest Len = TailleTotale - LenCopie
        Dim VarString As String
        VarString = Left(RecordUnK, TailleTotale - LenCopie)
        Put #FileNumberDest, LenCopie + 1, VarString
    ' Cas normal:
    Else
        Put #FileNumberDest, , RecordUnK
    End If

    ' Compte le nombre d'octets copiés:
    LenCopie = LenCopie + Len(RecordUnK)

Wend

' Fermeture des fichiers:
Close #FileNumberDest
Close #FileNumberSource

' Supprime le fichier d'origine:
Kill StrRépertoire & StrNom & "." & StrExtension

' Renomme le fichier temporaire en fichier d'origine:
Name StrRépertoire & StrNom & ".~" As StrRépertoire & StrNom & "." & StrExtension

' Supprime les paquets:
For i = 0 To Paquet
    Kill StrRépertoire & StrNom & ".P" & Format(i, "000")
Next i

' Mémorise le nom définitif du fichier recomposé:
StrFichier = StrRépertoire & StrNom & "." & StrExtension

End Sub
'---------------------------------------------------------------------------------------

XII. Remerciements

Je remercie Chrtoph et Pierre Fauconnier pour l'intérêt qu'ils ont porté à cette documentation, pour leurs conseils et leurs encouragements.
Oliv- pour tous les tests qu'il a réalisés, qui ont permis de relever des bogues.
Ainsi que Claude Leloup pour la correction orthographique.

Sans oublier celles et ceux qui voudront tester cette application et apporter un commentaire.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

Licence Creative Commons
Le contenu de cet article est rédigé par laurent_ott et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale 3.0 non transposé.
Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright © 2021 Developpez.com.