Nettoyer des liens hypertexte à la volée

Dans une table, j’ai un champ de type Lien hypertexte. Ça marche très bien dans Access, mais lorsque j’exporte la table vers Excel ou Word, les liens sont réécrits différemment et deviennent inexploitables. Comment faire ?

Le problème

Les liens hypertextes permettent de stocker des adresses de sites Web (http://), des adresses e-mail (mailto:), ou des fichiers de votre réseau informatique, et de les rendre cliquable dans l’interface d’Access (dans une table, une requête, un formulaire par exemple). Très pratique…

Le problème est que, lorsque ces liens sont exportés sous forme de données brutes, ils s’affichent de cette manière :

Cette forme empêche certains types d’exploitations, comme l’envoi de mails, puisque le lien complet n’est pas une adresse e-mail valide. Ce qui est un comble, puisque c’était l’objectif de départ !

Structure des liens hypertexte

En fait, un lien hypertexte peut être découpé en 3 parties, séparées par un signe # (certaines parties étant facultatives).
Partie affichée#Adresse#Sous-adresse

De gauche à droite :

  • La partie affichée (lisible par l’utilisateur) ;
  • L’adresse du lien proprement dite ; elle débute par mailto: dans le cas d’un e-mail ;
  • La sous-adresse, si l’adresse du lien doit être complétée par d’autres informations. Par exemple, si le lien pointe vers un fichier Excel, la sous-adresse peut être une feuille et une plage de cellules. Dans le cas d’un fichier Word, la sous-adresse peut-être un signet dans le document. La sous-adresse n’est pas utilisée dans le cas d’un e-mail.

Quelques exemples :

  • herve.inisan@provider.com#mailto:herve.inisan@provider.com#
  • Le site Self-Access.com#http://www.self-access.com#
  • CV#C:\Users\Hervé\Documents\CV.docx#
  • Statistiques 2011#stats.xlsx#Feuil3!B5

Solution 1

La première solution pour éviter ce problème serait finalement de ne plus utiliser les liens hypertexte, et de les remplacer par des champs Texte.

  • Avantage : un champ Texte ne contient que ce que vous y tapez ; plus de codes parasites !
  • Inconvénient : vous perdez le côté « cliquable » des liens hypertexte. (Vous pouvez cependant obtenir des équivalent grâce à la méthode FollowHyperlink).

Solution 2

Vous souhaitez peut être conserver le meilleur des 2 mondes : garder les liens hypertextes cliquables, et pouvoir les exploiter correctement. C’est ce que nous allons faire ici.
Dans le cas d’un e-mail, seule la partie Adresse nous intéresse. Cette partie est toujours située après le premier signe # (et avant le second #). Il suffit d’extraire cette portion de chaîne pour obtenir l’e-mail. Autre précaution à prendre, quand même : il faut pouvoir enlever le mailto: dans certains cas (il sera généralement inutile).

Le code VBA

Voici un bout de code VBA à recopier dans un module standard de votre base de données. L’énumération (le bloc Enum / End Enum) sera placé en haut du module.

Explications

La fonction GetHyperlink() reçoit 2 paramètres :

  1. Une chaîne qui donne le lien hypertexte d’origine (avec ses signes #), et de laquelle nous allons extraire l’adresse véritable ;
  2. Une valeur qui indique s’il faut « nettoyer » l’adresse obtenue. Par « nettoyer », il faut entendre :
  • Supprimer le mailto: à gauche de l’adresse (utilisez la valeur HyperlinkPrefix.mailto)
  • Supprimer le http:// à gauche de l’adresse (utilisez la valeur HyperlinkPrefix.http)
  • Supprimer les mailto: et les http:// (utilisez la valeur HyperlinkPrefix.all)
  • Ne rien supprimer (utilisez la valeur HyperlinkPrefix.none, ou n’alimentez pas le second paramètre).

Pour tester…

  1. Ouvrez la fenêtre Exécution (CTRL + G).
  2. Tapez dans cette fenêtre :
    ? GetHyperlink("inisan@provider.com#mailto:inisan@provider.com#")
    puis Entrée.
    Vous obtenez comme résultat : mailto:herve.inisan@provider.com
  3. Tapez :
    ? GetHyperlink("herve.inisan@provider.com#mailto:herve.inisan@provider.com#", mailto)
    puis Entrée.
    Vous obtenez : herve.inisan@provider.com

Vous auriez pu aussi utiliser all à la place de mailto, ou leurs valeurs numériques : 1 pour all, 3 pour mailto (cf. l’énumération en début de listing). En VBA, passez plutôt par l’énumération. Par contre, dans un objet graphique d’Access comme une requête, vous devrez taper les valeurs numériques.

Un exemple pratique

L’objectif de départ, rappelez-vous, était d’exporter une requête Access et ses liens hypertexte vers Excel, en ne transmettant que l’adresse du lien. Voici comment faire :

  1. Créez une nouvelle requête basée sur la table à exporter.
  2. Placez les champs à exporter sur la grille de requête, sauf l’e-mail d’origine (sa syntaxe avec signes # le rend inutile).
  3. Ajoutez le champ calculé suivant sur la grille de requête :
    Email réel: GetHyperlink([Email]; 3)


Une fois exécutée, la requête devrait donner ceci :
Capture2
Vous pouvez maintenant exporter cette requête vers Excel (entre autres) : le lien hypertexte obtenu est enfin exploitable !

Vous aimerez aussi...

13 réponses

  1. Massart Christian dit :

    Bonjour,

    Magnifique… Merci.
    Juste un petit bemol:
    Pour certains enregistrements, je n’ai pas d’adresse mail ce qui provoque un message d’erreur à l’exportation.
    Comment éviter ce message d’erreur.

  2. MARICHAL Christine dit :

    Bonjour Hervé, (Christine CCI il y a longtemps !)
    J’ai triché, j’ai résolu mon problème différemment :

    Longueur = Len(Me.Mail.Value)
    Longueur = Longueur – 9
    Longueur = Longueur / 2
    strdest = Left(Me.Mail.Value, Longueur)
    (Le 9 correspondant aux deux # et au « mailto: »
    Ma foi, ça a l’air de fonctionner…

    • Hervé Inisan dit :

      Salut Christine ! 🙂
      Effectivement, ça marche, mais pour des adresses mail uniquement. Dans le cas d’une adresse HTTP, le préfixe n’est plus le même, et la valeur 9 sera incorrecte.
      Mais si l’usage est uniquement « Mail », c’est parfait !

  3. Un immense merci pour cette fonction qui comble une lacune d’Access qui me gênait depuis fort longtemps.

  4. Hervé Inisan dit :

    otam > 🙂 Content que ça fonctionne.

  5. otam dit :

    La focale est parfaitement ajustée à la longueur du nez. Cela fonctionne à merveille. Merci

  6. Hervé Inisan dit :

    otam > A vue de nez, il faudrait que le lien inséré soit sous cette forme : titre#chemin# comme dans le 3ème exemple de l’article.

  7. otam dit :

    Bonjour,

    Je ne suis pas certain d’être dans la bonne rubrique, mais certainement pas très loin. Je m’inspire beaucoup de votre site ; vous le verrez ci-dessous dans les quelques lignes de code que je vous joins.

    Problème :
    Je gère un entrepôt logistique rempli de palettes. Lorsqu’une palette sort du dépôt, j’édite un bon de livraison (imprimer plusieurs PDF à partir d’un seul état (vous connaissez?)), l’enregistrement part dans une table Palettes_Archives et je met le champ BL à jour avec le chemin du fichier du bon de livraison.

    Voici un bout du code :
    ‘ Nom de base du fichier PDF à créer
    Jour = Format(Now, « YYYYMMDDHHMM »)
    strFichier = « C:BaseBL » & Format(Now, « YYYYMMDDHHMM ») &  » BL {0} – {1} {2}.pdf »
    strFichierZ = « \SERVERBaseBL » & Format(Now, « YYYYMMDDHHMM ») &  » BL {0} – {1} {2}.pdf »
    ‘ Ouvrir la liste des clients
    Set rst = CurrentDb.OpenRecordset(« Clients », dbOpenSnapshot)

    ‘ Parcourir toute la liste
    While Not rst.EOF
    Garcia = rst(« CodeClient »)
    Zorro = DCount(« [Sortie] », « Palettes », « [CodeClient] =  » & Garcia & «  »)
    If Zorro <> 0 Then

    ‘ Le nom du fichier varie en fonction du client
    strFichierPDF = StringFormat(strFichier, _
    Format(rst(« CodeClient »), « 000 »), _
    rst(« Abréviation »), _
    rst(« CodePostal »))
    strFichierPDFZ = StringFormat(strFichierZ, _
    Format(rst(« CodeClient »), « 000 »), _
    rst(« Abréviation »), _
    rst(« CodePostal »))
    ‘ Construire le filtre
    strFiltre = « [CodeClient] =  » & rst(« CodeClient »)

    ‘ Imprimer l’état en le filtrant sur le client concerné
    PrintAsPDF strFichierPDF, strEtat, strFiltre
    ‘C’EST ICI QU’IL FAUT METTRE A JOUR LA TABLE ARCHIVE AVEC LE NOM DE FICHIER DU BL EN LIEN HYPERTEXTE
    DoCmd.RunSQL « UPDATE Palettes_Archives INNER JOIN Chargement ON Chargement.Palette = Palettes_Archives.Palette SET Palettes_Archives.BL = ‘ » & strFichierPDFZ & « ‘ »

    Tout marche très bien, sauf que, lorsque je clique sur le lien hypertexte, rien ne se passe. Si je le copie et le recolle, tout va bien…Sauf que ça m’énerve!

    Avez-vous une idée ?

    PS : Merci et bravo

  8. Hervé Inisan dit :

    JackBxl > Je n’utilise pas Picasa, difficile de répondre. Mais quels sont les 2 liens affichés, selon les cas ?

  9. JackBxl dit :

    J’enrichis depuis des années une DB avec des liens hypertexte.
    Ce sont les chemins de photos mise sur le serveur
    Les liens sont créés en glissant simplement la vignette de la photo vue dans Picasa3.
    C’est excessivement rapide et facile.
    Le chemin est le chemin absolu jusqu’à la racine du serveur.
    mediastoreaatl-broh2-meopphotos_ctrlobsbur80128_P01.JPG

    Par contre si je copie l’adresse et colle dans mon formulaire (ou table) je n’ai que le chemin qui débute sous la lettre sous laquelle le dossier est monté.

    Je ne comprends pas l’origine de cette différence, et comme parfois le glissé/coller ne fonctionne pas je suis un peu inquiet de trop me fier à cette technique.

    Cela concerne des milliers de photos qui illustrent des bases de données Access 2003 mais qui migre aussi en Access 2010
    Merci

  10. JackBxl dit :

    J’espère arriver grâce a ces pages, mais suis nul en VBA
    J’ai 4500 liens dans une table qui pointent vers des photos. Le chemin a changé (merci l’admin ! )
    Si j’édite le lien visible, le véritable lien est inchangé. (le pop-up le confirme) Une pirouette en modifiant le format du champ vers texte et retour permettrait de se retrouver ????
    Je ferai le point plus tard

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *