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.
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 |
Public Enum HyperlinkPrefix none = 0 all = 1 http = 2 mailto = 3 End Enum ' --- ' EXTRACTION DE L'ADRESSE D'UN LIEN HYPERTEXTE ' --- ' Function GetHyperlink( _ ByVal strLink As String, _ Optional ByVal hlpClearPrefix As HyperlinkPrefix _ = HyperlinkPrefix.none) As String ' Quelques variables Dim strTemp As String Dim intI As Integer Dim intJ As Integer ' Position du premier # strTemp = "" intI = InStr(1, strLink, "#", vbTextCompare) If intI > 0 Then ' Position du second # intJ = InStr(intI + 1, strLink, "#", vbTextCompare) If intJ > 0 Then ' Partie Adresse strTemp = Trim(Mid(strLink, intI + 1, intJ - intI - 1)) ' Suppression du mailto: si nécessaire If ((hlpClearPrefix = HyperlinkPrefix.all) _ Or (hlpClearPrefix = HyperlinkPrefix.mailto)) _ And (LCase(Left(strTemp, 7)) = "mailto:") Then strTemp = Mid(strTemp, 8) End If ' Suppression du http:// si nécessaire If ((hlpClearPrefix = HyperlinkPrefix.all) _ Or (hlpClearPrefix = HyperlinkPrefix.http)) _ And (LCase(Left(strTemp, 7)) = "http://") Then strTemp = Mid(strTemp, 8) End If End If End If GetHyperlink = strTemp End Function |
Explications
La fonction GetHyperlink()
reçoit 2 paramètres :
- Une chaîne qui donne le lien hypertexte d’origine (avec ses signes #), et de laquelle nous allons extraire l’adresse véritable ;
- 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 valeurHyperlinkPrefix.mailto
) - Supprimer le
http://
à gauche de l’adresse (utilisez la valeurHyperlinkPrefix.http
) - Supprimer les
mailto:
et leshttp://
(utilisez la valeurHyperlinkPrefix.all
) - Ne rien supprimer (utilisez la valeur
HyperlinkPrefix.none
, ou n’alimentez pas le second paramètre).
Pour tester…
- Ouvrez la fenêtre Exécution (
CTRL
+G
). - Tapez dans cette fenêtre :
? GetHyperlink("inisan@provider.com#mailto:inisan@provider.com#")
puisEntrée
.
Vous obtenez comme résultat :mailto:herve.inisan@provider.com
- Tapez :
? GetHyperlink("herve.inisan@provider.com#mailto:herve.inisan@provider.com#", mailto)
puisEntré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 :
- Créez une nouvelle requête basée sur la table à exporter.
- Placez les champs à exporter sur la grille de requête, sauf l’e-mail d’origine (sa syntaxe avec signes # le rend inutile).
- 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 :
Vous pouvez maintenant exporter cette requête vers Excel (entre autres) : le lien hypertexte obtenu est enfin exploitable !
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.
Si l’erreur se produit sur la fonction GetHyperlink(), il faut « nettoyer » les valeurs vides au préalable, comme ceci :
Email réel: GetHyperlink(Nz([Email]; 3)
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…
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 !
Un immense merci pour cette fonction qui comble une lacune d’Access qui me gênait depuis fort longtemps.
Content que ça puisse dépanner ! 🙂
otam > 🙂 Content que ça fonctionne.
La focale est parfaitement ajustée à la longueur du nez. Cela fonctionne à merveille. Merci
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.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
JackBxl > Je n’utilise pas Picasa, difficile de répondre. Mais quels sont les 2 liens affichés, selon les cas ?
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_ctrlobsbur 80128_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
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