OFFICE : Dessiner une carte de france avec les fonctions de dessins

Image non disponible

Apprenez à dessiner dans Office une carte de France à partir de données SVG.

Cet article s'applique à Excel, Word et Powerpoint.

37 commentaires Donner une note à l'article (5)

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction


Nous allons au cours de ce tutoriel dessiner une carte de France avec son découpage par département.
Chaque département pourra ensuite être colorié pour mettre des données en évidence.

Si vous n'êtes pas à l'aise avec VBA, vous pouvez tout de même copier-coller la carte des exemples pour l'utiliser dans vos documents.

II. Dessiner des formes libres dans Office


Vous avez sans doute déjà utilisé les outils de dessin pour créer des formes.

Pour afficher la barre d'outils de dessin : Affichage => Barres d'outils => Dessin.
Sélectionnez ensuite dans cette barre d'outils : Forme automatique => Lignes => Forme Libre.

À partir de Office 2007, choisissez dans l'onglet Insertion : Formes => Lignes => Forme Libre.
Image non disponible

Activez l'enregistreur de Macro (dans Excel ou Word) ; si besoin consultez ce tutoriel pour savoir comment faire : Initiation au VBA Office

Vous pouvez alors tracer une forme quelconque, composée de segments et de courbes.

Image non disponible

Voici le code VBA généré par l'enregistreur de Macro :

Code de dessin d'une forme libre
Sélectionnez

Sub Macro6()
'
' Macro6 Macro
' Macro recorded 19/10/2009 by xxxx
'

'
   With ActiveSheet.Shapes.BuildFreeform(msoEditingAuto, 308.25, 324.75)
        .AddNodes msoSegmentLine, msoEditingAuto, 351#, 270.75
        .AddNodes msoSegmentLine, msoEditingAuto, 402#, 322.5
        .AddNodes msoSegmentCurve, msoEditingCorner, 315.75, 397.5, 361.5, 385.5, _
        318#, 371.25
        .AddNodes msoSegmentCurve, msoEditingCorner, 315.75, 369#, 312.75, 365.25, _
        309.75, 364.5
        .AddNodes msoSegmentCurve, msoEditingCorner, 306#, 359.25, 308.25, 360.75, _
        304.5, 358.5
        .AddNodes msoSegmentCurve, msoEditingCorner, 303#, 353.25, 301.5, 324.75, _
        308.25, 324.75
        .ConvertToShape.Select
    End With
End Sub


Ce code s'explique ainsi :
1 - BuildFreeform commence une nouvelle forme libre en donnant les coordonnées du point initial.
2 - AddNodes ajoute des segments ou des courbes.
3 - ConvertToShape finalise la forme, BuildFreeform renvoyant un constructeur de forme et non pas une forme visible.

On remarque que :
- un segment est créé en donnant le point de destination, le point source étant le point précédent.
- une courbe est créée à partir de 3 points : le premier point est le point de destination, les deux autres points sont des points de contrôle utilisés pour générer la courbe.

Suite à ces premiers essais, on se pose la question suivante :
- Ne pourrait-on pas créer des formes qui suivent le contour des départements pour générer une carte de France ?

La réponse est bien entendu positive, nous allons voir comment procéder.

III. Trouver les coordonnées des départements français

Afin de créer les formes qui représenteront les départements, il faut trouver les coordonnées des contours de ces départements.

Les contours précis des départements sont disponibles sur le site de l'IGN (base de données GEOFLA).
Malheureusement, les fichiers ne sont pas libres pour une utilisation commerciale.

Pour nos besoins, des contours simplifiés suffisent amplement.
Nous allons trouver ces contours dans des fichiers SVG.
Des fichiers sont disponibles sur le site Wikimedia :
Nous utiliserons ce fichier : Départements et régions de France

Il est indiqué sur la page que ce fichier est libre.

IV. Le format SVG

En quoi une image au format SVG va-t-elle nous aider ?
Le format SVG est une représentation vectorielle d'une image : c'est-à-dire que l'image est décomposée en segment, courbe, ...
Ouvrez le fichier Départements et régions de France avec un éditeur de texte (Wordpad par exemple).
En début de fichier, la première ligne nous informe que nous lisons en fait un fichier XML :

En-tête du fichier SVG
Sélectionnez

<?xml version="1.0" encoding="UTF-8" standalone="no"?>


Regardons un peu plus bas dans le fichier, nous trouvons plusieurs couches de données (layer), dont une qui va particulièrement nous intéresser : la couche Départements :

Couche départements
Sélectionnez

  <g
     inkscape:groupmode="layer"
     id="layer10"
     inkscape:label="Département"
     style="display:inline">
    <path
       style="opacity:1;color:#000000;fill:#fff3e3;fill-opacity:1;fill-rule:evenodd;stroke:#5d5d5d;stroke-width:1;
	   		stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;
			marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;
			stroke-opacity:0.51459853;visibility:visible;display:inline;overflow:visible"
       d="M 536.28822,491.78463 L 536.28822,493.94088 L 538.25697,495.31588 L 541.56947,497.25338 L 541.78822,498.81588 
	   		L 539.81947,499.40963 L 536.69447,500.00338 L 536.69447,501.34713 L 537.85072,502.53463 
			L 538.06947,506.44088 L 542.35072,507.81588 L 543.91322,508.19088 L 545.28822,510.34713 
			L 544.31947,511.72213 L 542.75697,512.28463 L 541.56947,514.44088 L 540.41322,515.81588 
			L 540.97572,519.31588 L 543.91322,519.12838 L 544.69447,519.72213 L 547.44447,518.34713 
			L 548.22572,519.12838 L 546.85072,522.06588 L 548.22572,523.44088 L 545.88197,525.19088 
			L 544.31947,528.69088 L 548.60072,529.69088 L 554.66322,530.25338 L 552.13197,533.19088 
			C 552.13197,533.19088 550.94264,532.73207 550.41322,532.97213 
			C 550.39757,532.97984 550.36511,532.99432 550.35072,533.00338 
			C 550.34622,533.00671 550.32381,533.03114 550.31947,533.03463 
			C 550.31528,533.03829 550.29224,533.06206 550.28822,533.06588 
			C 550.28453,533.07004 550.26048,533.0928 550.25697,533.09713 
			C 550.25029,533.10614 550.23167,533.11865 550.22572,533.12838 
			C 550.22294,533.13342 550.22831,533.1544 550.22572,533.15963 
			C 550.22093,533.17046 550.19846,533.21054 550.19447,533.22213 
			C 550.19268,533.22812 550.19605,533.24719 550.19447,533.25338 
			C 550.19174,533.26615 550.16507,533.3023 550.16322,533.31588 
			C 550.16182,533.32987 550.16369,533.36355 550.16322,533.37838 
			C 550.16323,534.35494 548.81947,536.72213 548.81947,536.72213 
			L 550.75697,538.84713 L 554.28822,541.00338 L 560.91322,542.75338 L 562.85072,543.53463 
			L 564.63197,544.31588 L 563.44447,546.47213 L 566.56947,546.28463 L 567.16322,547.65963 
			L 570.28822,547.65963 L 571.06947,543.94088 L 569.10072,543.53463 L 571.85072,540.62838 
			L 570.88197,539.62838 L 571.06947,537.87838 L 574.60072,535.94088 L 574.78822,533.78463 
			L 572.44447,533.59713 L 570.88197,534.94088 L 570.88197,533.00338 L 574.00697,532.81588 
			L 574.97572,530.47213 L 575.75697,523.62838 L 575.16322,520.69088 L 575.10072,517.87838 
			L 571.69447,520.12838 L 567.63197,520.28463 L 567.28822,517.47213 L 567.81947,516.75338 
			L 566.56947,515.87838 L 566.22572,511.09713 L 565.69447,510.22213 L 563.56947,510.22213 
			L 562.50697,509.34713 L 562.50697,505.97213 L 561.10072,505.09713 L 560.03822,504.56588 
			L 557.91322,501.90963 L 558.06947,500.31588 L 555.44447,500.31588 L 554.53822,497.65963 
			L 550.81947,497.65963 L 548.88197,495.00338 L 549.41322,494.12838 L 548.19447,493.40963 
			L 545.35072,493.94088 L 544.28822,493.25338 L 540.41322,493.25338 L 540.03822,492.19088 
			L 537.85072,491.78463 L 536.28822,491.78463 z "
       id="departement2a"
       inkscape:label="#path2446" />
    <path
       style="opacity:1;color:#000000;fill:#fff3e3;fill-opacity:1;fill-rule:evenodd;stroke:#5d5d5d;stroke-width:1;
	   		stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;
			marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;
			stroke-opacity:0.51459853;visibility:visible;display:inline;overflow:visible"
       d="M 568.91322,452.72213 L 565.97572,454.69088 L 566.38197,456.62838 L 567.94447,458.59713 L 566.19447,459.94088 
	   		L 566.97572,461.50338 L 565.78822,462.87838 L 565.78822,464.62838 L 567.75697,466.40963 
			L 567.75697,469.12838 L 566.56947,471.65963 L 565.22572,472.25338 L 563.66322,470.09713 
			L 560.91322,470.31588 L 560.31947,469.90963 L 557.97572,469.90963 L 555.85072,471.87838 
			L 555.03822,475.19088 L 549.97572,476.15963 L 546.06947,479.47213 L 545.28822,481.62838 
			L 543.35072,481.44088 L 542.35072,480.25338 L 541.78822,483.59713 L 540.41322,484.15963 
			L 540.00697,487.28463 L 540.60072,488.65963 L 538.44447,490.22213 L 537.85072,491.78463 
			L 540.03822,492.19088 L 540.41322,493.25338 L 544.28822,493.25338 L 545.35072,493.94088 
			L 548.19447,493.40963 L 549.41322,494.12838 L 548.88197,495.00338 L 550.81947,497.65963 
			L 554.53822,497.65963 L 555.44447,500.31588 L 558.06947,500.31588 L 557.91322,501.90963 
			L 560.03822,504.56588 L 561.10072,505.09713 L 562.50697,505.97213 L 562.50697,509.34713 
			L 563.56947,510.22213 L 565.69447,510.22213 L 566.22572,511.09713 L 566.56947,515.87838 
			L 567.81947,516.75338 L 567.28822,517.47213 L 567.63197,520.28463 L 571.69447,520.12838 
			L 575.10072,517.87838 L 574.97572,512.09713 L 579.66322,505.47213 L 579.66322,494.53463 
			L 577.72572,490.81588 L 577.13197,479.09713 L 575.75697,476.94088 L 573.22572,475.00338 
			L 572.81947,467.75338 L 574.00697,464.44088 L 572.44447,459.15963 L 571.47572,454.87838 
			L 570.66322,453.69088 L 568.91322,452.72213 z "
       id="departement2b"
       inkscape:label="#path2454" />
[....]


On découvre les coordonnées des contours des départements dans l'élément path, attribut d.
Consultez les spécifications du format SVG pour comprendre le contenu de cet attribut :
- M est un déplacement qui définit donc le premier point.
- L est un tracé de segment du point courant vers un autre point qui devient le point courant.
- C est un tracé de courbe à partir de 3 points.
- z ferme le tracé.

Il est alors possible de faire une analogie avec le code VBA généré précédemment à la construction d'une forme libre :
- M => BuildFreeform.
- L => AddNodes msoSegmentLine.
- C => AddNodes msoSegmentCurve.
- z => ConvertToShape.

V. Lecture des données et création des formes


Nous allons voir 2 méthodes pour importer les données de contour.
La première méthode utilise Excel, la deuxième méthode utilise la librairie Microsoft XML.

V-A. Import du SVG dans une feuille Excel

Ouvrez le fichier svg directement avec Excel.

Les données sont affichées "à plat" dans une feuille.
Repérez les données de la couche Départements.

Image non disponible

Copiez-collez ensuite les données dans une feuille de votre classeur, que nous nommons Departements.
Ne gardez que les données utiles :
- les contours de la colonne d.
- les identifiants de la colonne id15.
- les noms des départements de la colonne ns4:label16.

Image non disponible

Nous pouvons maintenant parcourir cette feuille et créer les formes correspondant à chaque département :

Ouvrez l'éditeur VBA (Alt + F11) puis insérez un nouveau module (Insertion => Module).
Si l'instruction n'y est pas déjà, ajoutez Option Explicit en début de module.

Ensuite nous écrivons une fonction CreateShapes qui va créer les formes des départements :
Cette fonction ne sera utilisée qu'une seule fois.
Elle pourra être supprimée une fois la carte de France générée.

 
Sélectionnez

'---------------------------------------------------------------------------------------------------------
' Importation du fichier SVG des départements et création des formes libres
'---------------------------------------------------------------------------------------------------------
Function CreateShapes()
Dim oSheet As Excel.Worksheet ' Feuille de travail
Dim lLine As Long ' Compteur de lignes
Dim lCoord As String ' Coordonnées du département
Dim lCoordArray As Variant ' Coordonnées du département en tableau
Dim lCptCoord As Long ' Compteur pour parcourir les coordonnées
Dim lNbShape As Long ' Nombre de formes créées
Dim lShapeRange() ' Tableaux des noms de formes créées pour fonction Group
Dim loFreeformBuilder As Excel.FreeformBuilder 'Constructeur de forme libre

' Feuille de données
Set oSheet = Sheets("Departements")
' Parcourt la feuille des données
For lLine = 1 To 96
    ' Coordonnées
    lCoord = oSheet.Cells(lLine, 1)
    ' Mise en forme des coordonnées
    lCoord = Replace(lCoord, ",", " ")
    ' Crée un tableau à partir de la chaîne de caractères
    lCoordArray = Split(lCoord, " ")
    ' Initialise le compteur
    lCptCoord = LBound(lCoordArray)
    Do
        Select Case lCoordArray(lCptCoord)
        Case "M" ' Point de départ
            ' Crée un constructeur de "forme libre" pour le département courant sur la feuille oSheet
            Set loFreeformBuilder = oSheet.Shapes.BuildFreeform(msoEditingCorner, _
			Val(lCoordArray(lCptCoord + 1)) * 10, Val(lCoordArray(lCptCoord + 2)) * 10)
            lCptCoord = lCptCoord + 3
        Case "L" ' Segment
            loFreeformBuilder.AddNodes msoSegmentLine, msoEditingAuto, _
			Val(lCoordArray(lCptCoord + 1)) * 10, Val(lCoordArray(lCptCoord + 2)) * 10
            lCptCoord = lCptCoord + 3
        Case "C" ' Courbe
            loFreeformBuilder.AddNodes msoSegmentCurve, msoEditingCorner, _
			Val(lCoordArray(lCptCoord + 1)) * 10, Val(lCoordArray(lCptCoord + 2)) * 10, _
			Val(lCoordArray(lCptCoord + 3)) * 10, Val(lCoordArray(lCptCoord + 4)) * 10, _
			Val(lCoordArray(lCptCoord + 5)) * 10, Val(lCoordArray(lCptCoord + 6)) * 10
            lCptCoord = lCptCoord + 7
        Case "z" ' Fin de la forme
            ' Convertit le Constructeur en Forme
            With loFreeformBuilder.ConvertToShape
            	' Identifiant du département
                .Name = oSheet.Cells(lLine, 2)
                ' Incrémente le nombre de formes créées
                lNbShape = lNbShape + 1
                ' Redimensionne le tableau de formes créées
                ReDim Preserve lShapeRange(1 To lNbShape)
                ' Ajoute le nom de la forme au tableau pour groupement
                lShapeRange(lNbShape) = .Name
            End With
            ' Libère l'objet constructeur
            Set loFreeformBuilder = Nothing
            ' Sort de la boucle de traitement des coordonnées
            Exit Do
        End Select
    Loop
Next
' Groupe les départements dans une forme
With oSheet.Shapes.Range(lShapeRange).Group
    .Name = "CarteFrance"
    .ScaleHeight 0.05, msoFalse
    .ScaleWidth 0.05, msoFalse
    .LockAspectRatio = msoTrue
End With
End Function


Dans cette fonction, on commence par définir l'objet oSheet qui est notre feuille de travail.

Puis on parcourt les lignes qui contiennent les données de 1 à 96.
Comme c'est une fonction à usage unique, on se permet d'indiquer en dur les numéros de ligne.

Les données de contour prises dans la colonne 2 sont stockées dans la variable lCoord.
On remplace ensuite les virgules par des espaces.
On obtient ainsi une chaîne d'instructions (M, L, C, z) et de coordonnées séparées par des espaces.

Cette chaîne de caractères est alors découpée avec l'instruction Split pour être injectée dans un tableau lCoordArray.
Il est plus facile de parcourir un tableau qu'une chaîne de caractères.

Lors du parcours de ce tableau, on effectue une action différente en fonction de l'instruction rencontrée :
- M : c'est le début de la forme : on initialise le constructeur de forme avec la fonction BuildFreeform.
- L : c'est l'instruction de tracé de segment que nous traduisons par la fonction .AddNodes msoSegmentLine.
- C : c'est l'instruction de tracé de courbe que nous traduisons par la fonction .AddNodes msoSegmentCurve.
- z : c'est l'instruction de fin de forme que nous traduisons par la fonction ConvertToShape pour traduire le constructeur en forme.

Les coordonnées sont multipliées par 10 afin de contourner un petit problème lors de la construction du premier segment.
En effet si le deuxième point de la forme libre est trop proche du premier, la fonction ConvertToShape renvoit une erreur 1004.
En multipliant les valeurs par 10, on évite cette erreur : ensuite nous réduirons la taille de la carte pour l'afficher à sa taille initiale.
Remarque : j'ai observé cette erreur avec Excel 2002.

On donne comme nom de chaque forme créée l'identifiant de la région : FR-01, FR-02, ...
Puis on ajoute ce nom de forme au tableau lShapeRange.
Ce tableau nous est ensuite utile pour regrouper toutes les formes des départements en un groupe nommé CarteFrance.

Notez qu'on divise la taille du groupe par 20 (avec ScaleHeight et ScaleWidth) pour obtenir une carte de taille raisonnable.
La propriété LockAspectRatio permet de verrouiller le rapport hauteur/largeur du groupe afin de pouvoir redimensionner proprement la carte manuellement.

Exécutez la fonction CreateShapes (F5) : la carte de France est générée sur la feuille Departements.

Image non disponible

V-B. Import du SVG avec la librairie Microsoft XML

Il est également possible de générer la carte directement à partir du fichier svg.
Nous allons le faire avec Word.

Créez un nouveau fichier Word.
Placez le fichier Départements et régions de France dans le même répertoire que ce fichier Word.

Ouvrez l'éditeur VBA (Alt + F11) puis insérez un nouveau module (Insertion => Module).
Si l'instruction n'y est pas déjà, ajoutez Option Explicit en début de module.

Dans le menu, sélectionnez : Outils => Références et cochez la librairie Microsoft XML, v3.0 (ou une autre version si nécessaire).
Cette librairie nous permet de charger et parcourir un fichier XML.

Ensuite nous écrivons une fonction CreateShapes qui va créer les formes des départements :
Cette fonction ne sera utilisée qu'une seule fois pour générer les formes.
Elle pourra être supprimée une fois la carte de France générée.

 
Sélectionnez

'---------------------------------------------------------------------------------------------------------
' Importation du fichier SVG des départements et création des formes libres
'---------------------------------------------------------------------------------------------------------
Function ImportSVG()
Dim loXml As New MSXML2.DOMDocument ' Objet XML
Dim loElt As MSXML2.IXMLDOMElement ' Element XML
Dim loAttr As MSXML2.IXMLDOMAttribute ' Attribut de l'élément XML
Dim loDep As MSXML2.IXMLDOMElement ' Element XML Département
Dim loAttrDep As MSXML2.IXMLDOMAttribute ' Attribut de l'élément Département
Dim lId As String ' Id du département
Dim lName As String ' Nom du département
Dim lCoord As String ' Coordonnées du département
Dim lCoordArray As Variant ' Coordonnées du département en tableau
Dim lCptCoord As Long ' Compteur pour parcourir les coordonnées
Dim lNbShape As Long ' Nombre de formes créées
Dim lShapeRange() ' Tableaux des noms de formes créées pour fonction Group
Dim loFreeformBuilder As Word.FreeformBuilder 'Constructeur de forme libre
Dim oDoc As Word.Document ' Document sur laquelle la carte est créée

' Objet document
Set oDoc = ThisDocument
' Chargement du fichier SVG contenant les départements
loXml.Load ThisDocument.Path & "\Départements_et_régions_de_France.svg"
' Parcourt les éléments du XML
For Each loElt In loXml.DocumentElement.ChildNodes
    ' Les départements sont dans un noeud de nom = g
    If loElt.nodeName = "g" Then
        ' Parcourt les attributs de l'élément
        For Each loAttr In loElt.Attributes
            ' Teste si l'attribut "inkscape:label" est égale à "Département"
            ' => cet élément contient les coordonnées des départements
            If loAttr.Name = "inkscape:label" And loAttr.Value = "Département" Then
                ' Parcourt les départements
                For Each loDep In loElt.ChildNodes
                    ' Parcourt les attributs de chaque élément = chaque département
                    For Each loAttrDep In loDep.Attributes
                        ' Conserve les attributs utiles dans des variables
                        Select Case loAttrDep.Name
                            Case "id" ' Identifiant
                                lId = loAttrDep.Value
                            Case "inkscape:label" ' Nom
                                lName = loAttrDep.Value
                            Case "d" ' Chemin = Coordonnées
                                lCoord = loAttrDep.Value
                        End Select
                    Next
                    ' Mise en forme des coordonnées
                    lCoord = Replace(lCoord, ",", " ")
                    ' Crée un tableau à partir de la chaîne de caractères
                    lCoordArray = Split(lCoord, " ")
                    ' Initialise le compteur
                    lCptCoord = LBound(lCoordArray)
                    Do
                        Select Case lCoordArray(lCptCoord)
                        Case "M" ' Point de départ
                            ' Crée un constructeur de "forme libre" pour le département courant sur le document oDoc
                            Set loFreeformBuilder = oDoc.Shapes.BuildFreeform(msoEditingCorner, _
							Val(lCoordArray(lCptCoord + 1)), Val(lCoordArray(lCptCoord + 2)))
                            lCptCoord = lCptCoord + 3
                        Case "L" ' Segment
                            loFreeformBuilder.AddNodes msoSegmentLine, msoEditingAuto, _
							Val(lCoordArray(lCptCoord + 1)), Val(lCoordArray(lCptCoord + 2))
                        lCptCoord = lCptCoord + 3
                        Case "C" ' Courbe
                            loFreeformBuilder.AddNodes msoSegmentCurve, msoEditingCorner, _
							Val(lCoordArray(lCptCoord + 1)), Val(lCoordArray(lCptCoord + 2)), _
							Val(lCoordArray(lCptCoord + 3)), Val(lCoordArray(lCptCoord + 4)), _
							Val(lCoordArray(lCptCoord + 5)), Val(lCoordArray(lCptCoord + 6))
                            lCptCoord = lCptCoord + 7
                        Case "z" ' Fin de la forme
                            ' Convertit le Constructeur en Forme
                            With loFreeformBuilder.ConvertToShape
                                ' Identifiant du département
                                .Name = lId
                                ' Incrémente le nombre de formes créées
                                lNbShape = lNbShape + 1
                                ' Redimensionne le tableau de formes créées
                                ReDim Preserve lShapeRange(1 To lNbShape)
                                ' Ajoute le nom de la forme au tableau pour groupement
                                lShapeRange(lNbShape) = .Name
                            End With
                            ' Libère l'objet constructeur
                            Set loFreeformBuilder = Nothing
                            ' Sort de la boucle de traitement des coordonnées
                            Exit Do
                        End Select
                    Loop
                Next
            End If
        Next
    End If
Next
' Groupe les départements dans une forme
With oDoc.Shapes.Range(lShapeRange).Group
    .Name = "CarteFrance"
    .ScaleHeight 0.5, msoFalse
    .ScaleWidth 0.5, msoFalse
    .LockAspectRatio = msoTrue
End With

End Function


On parcourt les éléments du XML avec la collection ChildNodes.
La collection Attributes de chaque élément permet de parcourir les données de chaque élément (Identifiant, Coordonnées, ...).

Le code de génération des formes est identique au code précédent avec Excel, mis à part que l'erreur rencontrée avec Excel lors de points trop rapprochés n'apparaît pas dans Word (2002).
On retire donc le multiplicateur (* 10) qui n'est pas utile ici.

Exécutez la fonction CreateShapes (F5) : la carte de France est générée sur le document courant.

Image non disponible

Notez que le code pour générer une carte dans Powerpoint est identique, mis à part l'objet oDoc qui doit être remplacé par un objet de type Slide.
Remarque : j'ai été confronté au même problème avec Powerpoint (2002) qu'avec Excel et j'ai dû multiplier les coordonnées par 10 pour ne plus avoir d'erreur.

Une fois la carte générée, la fonction CreateShapes n'est plus utile et peut être supprimée.
La référence à la librairie Microsoft XML peut également être retirée.

V-C. Fichiers exemples

Les fichiers suivants contiennent une application Office (Word, Excel ou Powerpoint) et le fichier svg des départements de France.
Chaque application contient une carte de France déjà générée et le code VBA utilisé.

Exemple Excel
Exemple Powerpoint
Exemple Word

VI. Colorier la carte


Maintenant que notre carte est créée, nous souhaitons la colorier.
Nous allons dans un premier temps le faire dans Excel.
Créez un nouveau classeur Excel.
Renommez la première feuille CA et inscrivez-y par exemple des chiffres d'affaires :

Image non disponible

Nous souhaitons maintenant colorier la carte en fonction de la progression du chiffre d'affaire entre 2008 et 2009 :
- en vert les départements dont le chiffre d'affaires a augmenté.
- en rouge les départements dont le chiffre d'affaires a diminué.

Copier la carte de France du classeur du chapitre précédent.
Collez-la dans la feuille CA du nouveau classeur, à droite des chiffres.

Ajoutez à côté de la carte une forme de votre choix, qui ressemble à un bouton.
Cliquez avec le bouton droit sur cette forme et choisissez Ajoutez un texte : saisissez un texte, par exemple Rafraîchir la carte.

Ce bouton va déclencher du code VBA : cliquez avec le bouton droit sur la forme et choisissez Affecter une Macro.
Nommez éventuellement la macro (ColorMap par exemple) et cliquez sur Nouveau.
Vous êtes redirigés dans l'éditeur VBA, dans la procédure vide nouvellement créée :

Procédure de coloration de la carte
Sélectionnez

Sub ColorMap()

End Sub


Il suffit alors de parcourir les données de la feuille CA et de rechercher la forme représentant le département pour la colorier.

Voici la procédure complète :

Procédure de coloration de la carte
Sélectionnez

'--------------------------------------------------------------------------------
' Colore la carte en fonction de la progression du CA
'--------------------------------------------------------------------------------
Sub ColorMap()
Dim oSheet As Excel.Worksheet ' Feuille
Dim lLine As Long ' Numéro de ligne
Dim loShape As Shape ' Forme
Dim lColor As Long ' Couleur
' Feuille contenant la carte
Set oSheet = ThisWorkbook.Sheets("CA")
' Désactive le remplissage de la carte
oSheet.Shapes("CarteFrance").Fill.Visible = msoFalse
' Pour chaque ligne de CA
For lLine = oSheet.UsedRange.Row + 1 To oSheet.UsedRange.Row + oSheet.UsedRange.Rows.Count
    ' Couleur de remplissage
    ' Rouge si CA diminue
    ' Vert si CA augmente
    If oSheet.Cells(lLine, 4) < oSheet.Cells(lLine, 3) Then
        lColor = vbRed
    Else
        lColor = vbGreen
    End If
    ' Parcours les départements de la carte
    For Each loShape In oSheet.Shapes("CarteFrance").GroupItems
        ' Si la forme loShape a pour nom la valeur de la première colonne (l'identifiant FR-XX)
        If loShape.Name = oSheet.Cells(lLine, 1) Then
            ' Réactive le remplissage de la forme
            loShape.Fill.Visible = True
            ' Type de remplissage = couleur unie
            loShape.Fill.Solid
            ' Pas de transparence
            loShape.Fill.Transparency = 0#
            ' Couleur de remplissage
            loShape.Fill.ForeColor.RGB = lColor
            ' La forme a été trouvée => on sort de la boucle
            Exit For
        End If
    Next
Next
End Sub


Exécutez cette procédure (F5) ou cliquez sur le bouton sur la feuille CA pour colorier la carte :

Image non disponible

Pour colorier directement la carte lors d'une modification de chiffre d'affaire, il est possible d'utiliser l'événement Change de la feuille :
Dans le module de code de la feuille CA.

Coloration de la carte sur changement dans la feuille CA
Sélectionnez

'--------------------------------------------------------------------------------
' Coloration de la carte sur changement dans la feuille CA
'--------------------------------------------------------------------------------
Private Sub Worksheet_Change(ByVal Target As Range)
ColorMap
End Sub


Si on modifie un chiffre d'affaire, la carte est alors automatiquement mise à jour.


Télécharger le classeur Excel de ce chapitre :
Carte coloriée avec Excel

VII. Détecter le clic sur un département

Peut-être souhaitez vous maintenant pouvoir agir sur clic sur un département ?

Créez un nouveau classeur Excel et copiez-collez la carte de France de ce classeur.
Cliquez avec le bouton droit sur la carte et choisissez Affecter une Macro.
Nommez éventuellement la macro selon votre besoin et cliquez sur Nouveau.
Vous êtes redirigés dans l'éditeur VBA, dans la procédure vide nouvellement créée :

Procédure appelée lors du clic sur la carte
Sélectionnez

Sub CarteFrance_Click()

End Sub


Dans cette procédure, pour connaître le département qui a provoqué le clic, il suffit de lire la propriété Application.Caller.

Procédure appelée lors du clic sur la carte
Sélectionnez

'-----------------------------------------------------------
'Procédure appelée lors du click sur la carte
'-----------------------------------------------------------
Sub CarteFrance_Click()
MsgBox "Vous avez cliqué sur le département : " & Application.Caller
End Sub


Cliquez sur les départements pour tester la procédure.

Vous pouvez maintenant agir en fonction de la valeur renvoyée par Application.Caller.

Pour illustrer cette technique, voici un petit jeu sous Excel dont le but est de cliquer sur le département demandé :

Jeu des départements Excel(HTTP)

VIII. Comment faire avec Microsoft Access ?


Les dessins de formes libres ne sont pas disponibles dans Access.
Il est cependant possible de dessiner une carte :
- sur un état : Apprendre à Ecrire et Dessiner dans les états Access.
- ou sur un formulaire en utilisant gdi32 ou gdi+.

Vous pouvez aussi étudier ces bases de données : Affichage d'information sur carte géographique, avec gdi+.

IX. Conclusion


Nous voici donc armés d'une carte de France réutilisable à loisir.
Il suffit de la copier-coller dans un document Word, Excel, ou Powerpoint.

Cela ne vous a sans doute pas échappé, il est possible d'aller plus loin en utilisant d'autres couches de données des fichiers svg :
- Affichage zoomé de la région parisienne.
- Dessin de cercles pour les préfectures.
- Affichage des numéros des départements.
- ...

Si vous améliorez la carte de France, n'hésitez pas à poster un message dans le forum sur la discussion donnée dans le synopsis.

X. Téléchargement

=> Les fichiers suivants contiennent une application Office (Word, Excel ou Powerpoint) et le fichier svg des départements de France.
Chaque application contient une carte de France déjà générée et le code VBA utilisé.
Exemple Excel
Exemple Powerpoint
Exemple Word
=> Télécharger le classeur Excel de la carte coloriée en fonction de la progression du chiffre d'affaire :
Carte coloriée avec Excel
=> Télécharger le jeu des départements sous Excel :
Jeu des départements Excel

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

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2009 Thierry GASPERMENT. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts. Droits de diffusion permanents accordés à Developpez LLC.