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

Un formulaire (état) qui contient de multiples fois le même sous-formulaire (sous-état), chacun avec une source différente

- Dans cette application, on a choisi de construire un formulaire qui contient 21 fois le même sous-formulaire avec pour chacun une source différente. Ces derniers sont construits à la volée.

- Un procédé identique sera présenté pour un état.

- On verra aussi comment il est possible, dans un formulaire continu, d'avoir une zone de liste modifiable dont le contenu est spécifique à chaque enregistrement.

Les commentaires et les suggestions d'amélioration sont les bienvenus, alors, après votre lecture, n'hésitez pas 15 commentaires Donner une note à l´article (5) 

Article lu   fois.

L'auteur

Profil ProSite personnel

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Prérequis

Maîtriser la conception des formulaires et des états.

Être capable de « sentir le code VBA » : pas nécessairement savoir l'écrire, mais comprendre ce qui s'y passe (ce qui constitue une étape importante dans votre apprentissage de ce langage qui décuplera vos possibilités).

Image non disponible
Pour un problème de code dans un module, placez le curseur n'importe où dans l'instruction et pressez <F1>.
L'aide Access s'ouvre alors à la bonne page.

II. Le but de l'exercice

On dispose d'une table qui contient les différents plats :

Image non disponible

À l'ouverture du formulaire : compléter la date

Image non disponible

Il vient

Image non disponible

On voudrait alors construire les menus de la semaine pour les éléments de la carte des trois services journaliers :

Image non disponible

avec une liste déroulante limitée aux plats pertinents pour chaque cas, pour aboutir à ceci :

Image non disponible

En un clic, produire un état bilingue du menu d'un jour :

Image non disponible

En un clic, produire un état synoptique des sept jours, au choix en français et en anglais :

Image non disponible
Image non disponible

III. L'idée

Utiliser un formulaire « principal » qui contiendra 21 sous-formulaires (un pour chacune des trois cartes de chacun des sept jours de la semaine) et récupérer ces données pour produire les états.

IV. Les difficultés

1° Adapter la source de chaque sous-formulaire pour qu'il affiche les données de cette carte. Nous devrons écrire quelques lignes de code VBA.

2° Adapter le contenu des zones de liste pour les limiter aux choix pertinents pour un item de ce type (soupe, entrée, plat…).

Le problème vient du fait que lorsqu'on modifie de manière dynamique le contenu de la zone de liste pour en restreindre les choix dans l'enregistrement actif, cette restriction entre automatiquement en vigueur pour tous les autres enregistrements du formulaire.
Cela n'altère pas la valeur des choix antérieurs : l'item qui avait été choisi subsiste tel quel, mais si sa valeur ne figure pas dans la liste de celles ponctuellement permises, Access ne peut plus l'afficher.

Au paragraphe VIII, nous décrirons une astuce pour contourner le problème.

V. La table tMenus

Cette table pour stocker les données du plat choisi, pour chaque item des trois services de chaque jour (30 enregistrements par jour), par exemple pour le 8/10/2015 :

Image non disponible

On évite les doublons comme ceci :

Image non disponible
  On pourrait considérer comme une redondance le fait que tMenus contienne les intitulés (français/anglais) puisque ceux-ci sont dans tPlats.
On s'attendrait à une relation comme celle-ci pour obtenir le nom du plat :
Image non disponible
Image non disponible
  Cependant, nous n'avons pas pu opter pour une telle solution, car dans un premier temps, lorsque les enregistrements sont créés, on ne connaît pas encore le plat qui sera choisi par l'utilisateur… et tPlatsFK vaut alors 0, par défaut.

VI. Le formulaire fMenuSemaine

VI-A. Les pièces du puzzle

À l'ouverture, tous les contrôles sont invisibles sauf txtDateDepart.

Image non disponible

Sa mise à jour fera passer la propriété Visible des autres contrôles à Oui.

La section Entête du formulaire contient sept contrôles avec une date qui correspondra à chaque jour de la semaine qui débute à la date de départ saisie par l'utilisateur.

Dans la section Détail, on trouve :

- 3 fois le sous-formulaire sfLignes destiné à afficher les 10 items d'une carte ;

- 21 fois le sous-formulaire sfMenuJour qui affichera le plat choisi pour chacun des 10 items des 21 cartes de la semaine (3 services fois 7 jours).

VI-B. Le code déclenché par la mise à jour de txtDateDepart

 
Sélectionnez
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.
Private Sub txtDateDepart_AfterUpdate()
  Dim ctl As Control
  Dim sSqlDebut As String
  Dim sSql As String
  Dim i As Integer
  'Rendre les contrôles visibles
  For Each ctl In Me.Controls
    ctl.Visible = True
  Next ctl
  'Aménager les dates
  DoCmd.SetWarnings False
  For Each ctl In Me.Controls
    If ctl.Name Like "txtJour#" Then
        'Garnir les contrôles
        ctl = Me.txtDateDepart + Right(ctl.Name, 1)
        'Créer (éventuellement) les enregistrements vierges avec ces dates dans la table tMenus
        DoCmd.RunSQL "INSERT INTO tMenus ( MenuDate, MenuService, MenuLigne ) " _
              & "SELECT #" & Format(ctl, "mm/dd/yyyy") & "# AS Expr1, 1 AS Expr2, tMatrice.MenuLigne FROM tMatrice;"
        DoCmd.RunSQL "INSERT INTO tMenus ( MenuDate, MenuService, MenuLigne ) " _
              & "SELECT #" & Format(ctl, "mm/dd/yyyy") & "# AS Expr1, 2 AS Expr2, tMatrice.MenuLigne FROM tMatrice;"
        DoCmd.RunSQL "INSERT INTO tMenus ( MenuDate, MenuService, MenuLigne ) " _
              & "SELECT #" & Format(ctl, "mm/dd/yyyy") & "# AS Expr1, 3 AS Expr2, tMatrice.MenuLigne FROM tMatrice;"
    End If
  Next ctl
  DoCmd.SetWarnings True
  'Construire la source de chaque sous-formulaire et le contenu des listes
  For Each ctl In Me.Controls
    If ctl.Name Like "CTNR*" Then
        'source
        ctl.Form.RecordSource = "SELECT tMenus.* FROM tMenus " _
                       & "WHERE MenuDate=[Formulaires]![fMenuSemaine]![txtJour" & Mid(ctl.Name, 5, 1) & "] " _
                            & "AND MenuService=" & Right(ctl.Name, 1) & " ORDER BY tMenus.MenuLigne;"
        'Liste
        ctl.Form!cboPlat.RowSource = "SELECT tPlatsPK, PlatNomF,PlatNomE FROM tPlats " _
            & "WHERE Ligne=Replace([Forms]![fMenuSemaine]!" & ctl.Name & ".[form]![txtMenuLigne],6,7);"

    End If
  Next ctl
End Sub

Explication du code

7-9 : on lance une boucle sur tous les contrôles du formulaire pour les rendre visibles.

10-25 : modification des propriétés des contrôles en fonction des dates de la semaine.

15 : les contrôles nommés txtDatei où « i » varie de 0 à 6

Image non disponible

Pour calculer la date qui convient, il suffit d'ajouter à la date txtDateDepart un nombre de jours égal au chiffre qui termine le nom du contrôle.

16-22 : ici, pour chacune des sept dates, on va compléter (éventuellement) la table tMenus pour qu'elle contienne 3 (les trois services) x 10 (les dix items de la carte) soit 30 enregistrements pour chaque journée.

Les requêtes construites à la volée sont du type de celle-ci par exemple pour le lunch (code service = 1) du 4/10/2015

Image non disponible

De deux choses l'une :

- les enregistrements existent déjà et l'ajout sera rejeté (voir définition de tMenus) ;
- des enregistrements seront ajoutés pour les dix items de la carte de ce service de cette date, prêts à accueillir le plat qui sera choisi par l'utilisateur. (À ce stade, tPlatsFk vaut 0.)

27-38 : adaptation des 21 sous-formulaires.

30-32 : on crée la source de chacun. En l'occurrence, la portion de tMenus qui le concerne.
Par exemple pour le lunch du jour0 (CTNR01, où « 0 » indique le jour et « 1 » le lunch), cette requête créée à la volée :

Image non disponible

34-35 : dans la foulée, on aménage le contenu des zones de liste. Voici un exemple des 21 requêtes construites à la volée, il se rapporte à la liste des items pour le lunch du jour0 :

Image non disponible

N.B. Les lignes 6 et 7 de la carte concernent les légumes. Dans tPlats ceux-ci ont la valeur 7 en colonne Ligne.

VII. Le sous-formulaire sfLignes

Il est destiné à afficher les items d'une carte dans le formulaire principal :

Image non disponible

Sa construction :

Image non disponible

Sa source :

Image non disponible

VIII. La problématique des zones de liste à contenu variable dans un formulaire continu

Le problème vient du fait que lorsqu'on modifie de manière dynamique le contenu de la zone de liste pour en restreindre les choix dans l'enregistrement actif, cette restriction entre automatiquement en vigueur pour tous les autres enregistrements du formulaire.
Cela n'altère pas la valeur des choix qui ont été faits dans les autres enregistrements : l'item qui avait été choisi subsiste tel quel, mais si sa valeur ne figure pas dans la liste de celles ponctuellement permises, Access ne peut plus l'afficher. 

VIII-A. Un exemple pour bien se comprendre

Supposons que dans cette table :

Image non disponible

on veut garnir la colonne idPlatChoisi en picorant dans une liste dont le choix serait limité aux plats qui correspondent à la ligne indiquée.

On pense d'abord à un formulaire comme celui-ci :

Image non disponible

Avec ce code sur l'événement « Sur activation » pour actualiser le contenu de la liste à chaque enregistrement :

 
Sélectionnez
Option Compare Database
Option Explicit

Private Sub Form_Current()
  Me.cboPlat.Requery
End Sub

Ce qui donnerait ceci :

Image non disponible

MAIS pour la ligne suivante :

Image non disponible

la liste est bien limitée aux bons choix, mais le choix qui avait été opéré pour « Entrée » n'est plus affiché !

De même :

Image non disponible

Bref, seul l'enregistrement actif laisse apparaître le choix opéré.

D'ailleurs, si on revient sur l'enregistrement 2 :

Image non disponible

le choix s'affiche à nouveau… et les autres disparaissent !

VIII-B. Que se passe-t-il ?

Pour bien comprendre, nous allons ajouter un contrôle au formulaire pour afficher la valeur contenue dans idPlatChoisi.

Voici :

Image non disponible

Quand on est positionné sur la ligne 2, la requête qui fixe le contenu de la zone de liste limite le choix à 169 et 170 :

Image non disponible

… et ni 168 ni 204 ne trouvent leur intitulé !

VIII-C. Une astuce pour sortir de l'impasse

Nous allons ajouter un nouveau contrôle au formulaire :

Image non disponible

avec comme propriété Source contrôle une fonction de domaine qui recherche dans tPlats l'intitulé correspondant à la valeur mémorisée dans cboPlat (soit idPlatChoisi de cet enregistrement).

Et voilà le travail :

Image non disponible

VIII-D. Une dernière retouche pour faire « joli »

On réduit la largeur de la zone de liste pour ne laisser apparaître que son carré Image non disponibleque l'on place à droite de la zone de texte qui contient l'intitulé :

Image non disponible

Et on obtient finalement une « illusion » de zone de liste modifiable :

Image non disponible

Pas beau ça ?

IX. Le sous-formulaire sfMenuJour

Il est destiné à sélectionner le plat de chaque item des 21 cartes :

Image non disponible

Sur chaque ligne, une zone de liste modifiable qui permet de choisir un plat compatible avec l'item de la carte (uniquement les soupes sur la 1re ligne, uniquement des entrées sur la 2e, etc.)

Image non disponible

Pour ce qui est de la zone de liste modifiable, ce sous-formulaire est conçu suivant la technique décrite au chapitre précédent.

X. L'état eMenuJour

L'idée, c'est d'afficher le formulaire fMenu et d'obtenir, en double-cliquant sur une date, un état qui donne la carte bilingue de cette date :

Image non disponible

L'objectif est de récupérer les données déjà disponibles dans le formulaire.

X-A. Un squelette : eMenuJourVierge

Image non disponible
Image non disponible

Remarquez comment sont nommés les conteneurs de sous-état

Image non disponible

L'objet source du conteneur n'est pas complété.

X-B.

Pour confectionner l'état, on va prendre une copie de ce squelette, nous l'appellerons eMenuJour et nous complèterons à la volée la date dans txtDate et l'objet source dans chacun des douze conteneurs.

La structure adoptée pour nommer les contrôles nous permettra de factoriser le code.

X-C. Le code du double-clic sur une date de fMenuSemaine

 
Sélectionnez
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.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
Option Compare Database
Option Explicit

Private Sub txtJour0_DblClick(Cancel As Integer)
  Me.txtDateDepart.SetFocus
  Call MenuJour(0)
End Sub

Private Sub txtJour1_DblClick(Cancel As Integer)
  Me.txtDateDepart.SetFocus
  Call MenuJour(1)
End Sub

Private Sub txtJour2_DblClick(Cancel As Integer)
  Me.txtDateDepart.SetFocus
  Call MenuJour(2)
End Sub

Private Sub txtJour3_DblClick(Cancel As Integer)
  Me.txtDateDepart.SetFocus
  Call MenuJour(3)
End Sub
Private Sub txtJour4_DblClick(Cancel As Integer)
  Me.txtDateDepart.SetFocus
  Call MenuJour(4)
End Sub

Private Sub txtJour5_DblClick(Cancel As Integer)
  Me.txtDateDepart.SetFocus
  Call MenuJour(5)
End Sub

Private Sub txtJour6_DblClick(Cancel As Integer)
  Me.txtDateDepart.SetFocus
  Call MenuJour(6)
End Sub

Public Sub MenuJour(NumJour As Integer)

  Dim ctl As Control
  Dim i As Integer
  
  'Geler temporairement l'affichage à l'écran et les messages
  Application.Echo False
  DoCmd.SetWarnings False
  
  'Initialiser eMenuJour
  DoCmd.CopyObject , "eMenuJour", acReport, "eMenuJourVierge"
  
  'Ouvrir eMenuJour en mode construction
  DoCmd.OpenReport "eMenuJour", acViewDesign
  
  'Dupliquer seLignes en seLignes_i_F et E
  '---------------------------------------
  DoCmd.OpenReport "seLignes", acViewDesign
       'En français
  Reports!seLignes!txtLigne.ControlSource = "LigneF"
  DoCmd.Save acReport, "seLignes"
  For i = 1 To 3
    'Créer les sous-états
    DoCmd.CopyObject , "seLignes" & i & "F", acReport, "seLignes"
    'Aménager les ObjectSource des sous-états seLignes_i
    Reports!eMenujour("seLignes" & i & "F").SourceObject = "État.seLignes" & i & "F"
  Next i
       'En anglais
  Reports!seLignes!txtLigne.ControlSource = "LigneE"
  DoCmd.Save acReport, "seLignes"
  For i = 1 To 3
    'Créer les sous-états
    DoCmd.CopyObject , "seLignes" & i & "E", acReport, "seLignes"
    'Aménager les ObjectSource des sous-états seLignes_i
    Reports!eMenujour("seLignes" & i & "E").SourceObject = "État.seLignes" & i & "E"
  Next i
  DoCmd.Close acReport, "seLignes"
  
  'Dupliquer seMenu
  '----------------
  DoCmd.OpenReport "seMenu", acViewDesign
       'En français
  Reports!seMenu!txtNom.ControlSource = "NomF"
  Reports!seMenu!txtNom.FontSize = 8
  DoCmd.Save acReport, "seMenu"
  For i = 1 To 3
    'Créer les sous-états
    DoCmd.CopyObject , "seMenu" & i & "F", acReport, "seMenu"
    'Aménager les ObjectSource des sous-états seMenu_i
    Reports!eMenujour("seMenu" & i & "F").SourceObject = "État.seMenu" & i & "F"
  Next i
       'En anglais
  Reports!seMenu!txtNom.ControlSource = "NomE"
  DoCmd.Save acReport, "seMenu"
  For i = 1 To 3
    'Créer les sous-états
    DoCmd.CopyObject , "seMenu" & i & "E", acReport, "seMenu"
    'Aménager les ObjectSource des sous-états seMenu_i
    Reports!eMenujour("seMenu" & i & "E").SourceObject = "État.seMenu" & i & "E"
  Next i
  DoCmd.Close acReport, "seMenu"
  
  'Aménager les dates
  Reports!eMenujour!txtDate.ControlSource = _
                      "=#" & Format(Me("txtJour" & NumJour), "mm/dd/yyyy") & "#"
  
  'Sauvegarder et rouvrir en construction
  DoCmd.Save acReport, "eMenujour"
  DoCmd.Close acReport, "eMenujour"
  DoCmd.OpenReport "eMenujour", acViewDesign
  
  'Aménager les sources
  For Each ctl In Reports!eMenujour.Controls
    If ctl.Name Like "seMenu*" Then
        Reports!eMenujour!(ctl.Name).Report.RecordSource = _
                     Me("CTNR" & NumJour & Mid(ctl.Name, 7, 1)).Form.RecordSource
    End If
  Next ctl
  
  'Rétablir l'affichage et les messages
  Application.Echo True
  DoCmd.SetWarnings True
  
  'Afficher l'état
  DoCmd.OpenReport "eMenuJour ", acViewPreview
End Sub

Complément aux commentaires du code

4 - 33 : le double-clic sur chacune des sept dates appelle la sous-routine MenuJour en donnant son numéro d'ordre comme paramètre (0 pour le 1er jour, 6 pour le dernier).

35 - fin : la sous-routine Menujour.

À l'ouverture, la base contient uniquement ces états qui vont servir de modèle :

Image non disponible

Dans le code qui suit, nous allons construire à la volée toute une série d'états… que nous supprimerons à la fermeture.

50 - 54 : on crée eMenuJour à l'image de eMenuJourVierge.

56 - 78 : on garnit les conteneurs de type

Image non disponible

d'abord en français (60 - 66), puis en anglais (70 - 78).

82 - 104 : on suit la même logique pour garnir les conteneurs de type

Image non disponible

111 - 113 : dans certaines circonstances (et c'est le cas ici) Access a du mal à s'y retrouver lorsqu'on fait référence à des contrôles d'un objet que l'on est en train de construire à la volée (en l'occurrence eMenujour). Pour cette raison, on sauvegarde, on ferme et on rouvre en construction eMenujour avant de compléter sa construction.

117 - 122 : on s'occupe ici de l'objet source de chacun des six conteneurs

Image non disponible

En fait, on récupère pour chacun, l'objet source du conteneur correspondant sur le formulaire fMenuSemaine.

Après l'exécution de ce code, la fenêtre des objets « États » a évolué :

Image non disponible

C'est la fermeture du formulaire fMenuSemaine qui provoquera le « nettoyage » de la base

 
Sélectionnez
Private Sub Form_Close()
  Dim db As DAO.Database, doc As DAO.Document
  'Fermer eMenuJour s'il est encore ouvert
 DoCmd.Close acReport, "eMenuJour"
  Set db = CurrentDb
  For Each doc In db.Containers("Reports").Documents
    If doc.Name Like "seMenu#*" Or doc.Name Like "seLignes#*" Or doc.Name = "eMenuJour" Then
        DoCmd.DeleteObject acReport, doc.Name
    End If
  Next doc
  Set db = Nothing
  DoCmd.Restore
End Sub

XI. L'état eMenuSemaine

Image non disponible

On complète les contrôles variables à la volée, la technique est la même que pour eMenuJour.

XI-A. Le code du clic sur le bouton Menu de la semaine

 
Sélectionnez
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.
52.
53.
54.
55.
56.
Private Sub btSemaine_Click()
  Dim i As Integer
  Dim j As Integer
  Dim Reponse As String
  'Demander dans quelle langue
  Reponse = UCase(InputBox("Quelle langue ?" & Chr(10) & Chr(13) _
                         & "Pour français, tapez « F »" & Chr(10) & Chr(13) _
                         & "for English, type « E »"))
  If Reponse <> "F" And Reponse <> "E" Then
    MsgBox "Choix de langue invalide " & Chr(10) & Chr(13) _
         & "Procédure interrompue."
    Exit Sub
  End If
  Application.Echo False
  'Aménager les contrôles variables de eMenuSemaine
  'Créer les sous-états selon la langue
         'Formater seLignes en fonction de la langue
  DoCmd.SetWarnings False
  DoCmd.OpenReport "seLignes", acDesign
  Reports!seLignes!txtLigne.ControlSource = "Ligne" & Reponse
  DoCmd.Save acReport, "seLignes"
  DoCmd.Close acReport, "seLignes"
  DoCmd.SetWarnings True
         'Formater seMenu en fonction de la langue
  DoCmd.SetWarnings False
  DoCmd.OpenReport "seMenu", acDesign
  Reports!seMenu!txtNom.ControlSource = "Nom" & Reponse
  Reports!seMenu!txtNom.FontSize = 6
  DoCmd.Save acReport, "seMenu"
  DoCmd.Close acReport, "seMenu"
  DoEvents
         'Démultiplier
  For i = 1 To 3
    For j = 0 To 6
      DoCmd.CopyObject , "seMenu" & i & j, acReport, "seMenu"
    Next j
  Next i
  DoCmd.SetWarnings True
  'Aménager les contrôles de dates
  DoCmd.OpenReport "eMenuSemaine", acViewDesign
  Reports!eMenuSemaine!txtDu.ControlSource = "=#" & Format(Me.txtDateDepart, "mm/dd/yyyy") & "#"
  Reports!eMenuSemaine!txtAu.ControlSource = "=#" & Format(Me.txtDateDepart + 6, "mm/dd/yyyy") & "#"
  For i = 0 To 6
    Reports!eMenuSemaine("txtDate" & i).ControlSource = "=#" & Format(Me.txtDateDepart + i, "mm/dd/yyyy") & "#"
  Next i
  'Aménager les sources
  For i = 0 To 6
    Reports!eMenuSemaine("ctnrLunch" & i).Report.RecordSource = Me("CTNR" & i & 1).Form.RecordSource
    Reports!eMenuSemaine("ctnrDinner" & i).Report.RecordSource = Me("CTNR" & i & 2).Form.RecordSource
    Reports!eMenuSemaine("ctnrMidnight" & i).Report.RecordSource = Me("CTNR" & i & 3).Form.RecordSource
  Next i
  DoCmd.Save acReport, "eMenuSemaine"
  'Afficher
  Application.Echo True
  DoCmd.OpenReport "eMenuSemaine", acViewPreview
End Sub

XII. Téléchargement

La db (format Access2000) qui a servi à mettre ce processus au point peut être téléchargée ici

XIII. Remerciements

Merci à Malick Seck (milkoseck) et f-leb pour la correction orthographique.

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 © 2015 Claude Leloup. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.