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 d’Office 2007, choisissez dans l'onglet Insertion : Formes => Lignes => Forme Libre.
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.
Voici le code VBA généré par l'enregistreur de Macro :
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 :
- BuildFreeform commence une nouvelle forme libre en donnant les coordonnées du point initial.
- AddNodes ajoute des segments ou des courbes.
- 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 :
<?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 :
<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.
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.
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.
'---------------------------------------------------------------------------------------------------------
' 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.
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.
'---------------------------------------------------------------------------------------------------------
' 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.
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é.
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 :
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'affaire a augmenté.
- en rouge les départements dont le chiffre d'affaire 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 :
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 :
'--------------------------------------------------------------------------------
' 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
xécutez cette procédure (F5) ou cliquez sur le bouton sur la feuille CA pour colorier la carte :
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
'--------------------------------------------------------------------------------
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 :
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 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
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