ODS Orienté Objet - des rapports personnalisés avec une
Transcription
ODS Orienté Objet - des rapports personnalisés avec une
ODS ORIENTE OBJET – DES RAPPORTS PERSONNALISES AVEC UNE ETAPE DATA L’Output Delivery System (ODS) vous permet déjà de customiser les résultats des procédures SAS, en modifiant le type de sortie, les formats, etc… Nous allons voir ici que grâce à une étape DATA _NULL_, nous allons pouvoir contrôler de façon simple et précise le contenu et l’aspect de notre rapport. Caractéristiques : Catégories : Base OS : Windows, Unix, z/OS Version : SAS® 9.2, 9.3 Vérifié en Novembre 2012 Table des matières ODS Orienté Objet – Des rapports personnalisés avec une Etape DATA ...................................... 1 Introduction ..................................................................................................................... 1 ODS Report Writing Interface .......................................................................................... 1 Un langage Orienté Objet ............................................................................................... 1 Texte .............................................................................................................................. 2 Tableaux ......................................................................................................................... 3 Les méthodes ................................................................................................................ 3 Un exemple................................................................................................................... 4 Un autre exemple .......................................................................................................... 6 Agencement de la page ..................................................................................................... 7 Concept et terminologie .................................................................................................. 7 Agencement en grille...................................................................................................... 8 Agencement absolu ........................................................................................................ 9 Divers ............................................................................................................................ 12 Conclusion ...................................................................................................................... 12 Références...................................................................................................................... 12 Introduction ODS Report Writing Interface L’ODS Report Writing Interface, apparue avec la version 9.1.3 de SAS, est une déclinaison du DATA _NULL_ report writing, qui fait partie intégrante du Système SAS depuis de nombreuses versions. Cette « Interface de Rédaction de Rapport » basée sur le « Système de Génération de Résultat » (dans la langue de Molière) combine la puissante logique de programmation de l’étape DATA, avec les fonctionnalités de l’ODS. Dans les exemples ci-dessous, nous utiliserons la destination ODS par défaut, soit HTML, sans la modifier. Vous pouvez bien entendu modifier cette destination (PDF, RTF…) ainsi que ses paramètres, à l’aide des options de l’instruction ODS. Avertissement : Il s’agit d’une fonctionnalité expérimentale en version 9.1.3, et en préproduction pour les versions 9.2 et 9.3. Vous verrez donc systématiquement la ligne ci-dessous dans la log SAS : WARNING: DATA step interface is preproduction in this release. Un langage Orienté Objet Cette interface se base sur une classe d’objet appelée odsout. Après avoir instancié un objet de cette classe (notre rapport), nous pourrons utiliser un certain nombre de méthodes de cette classe pour ajouter les éléments qui constitueront celui-ci – texte, tableaux, images… Cet objet ne doit être instancié qu’une seule fois dans notre étape DATA, aussi nous initialiserons en général notre rapport lors de la lecture du premier enregistrement : if _n_ = 1 then do; declare odsout obj(); end; Texte Voici un exemple très simple, qui se contente de créer un rapport avec un peu de texte. data _null_; set sashelp.cars end=eof; if _n_ =1 then do; declare odsout obj(); obj.note(data: "Des voitures", overrides: "preimage='C:\Images\cars.png' font_style=italic font_size=12pt font_weight=bold color=cxbbb2e0", Mars 2012 -2- just: "L"); end; obj.format_text(data: make, overrides: "background=cx494068 color=cxbbb2e0 font_size=12pt font_style=italic width=2.5in", just: "C"); obj.format_text(data: model, overrides: "background=cxbbb2e0 font_style=italic font_size=8pt width=2.5in", just: "C"); if eof ne 1 then obj.format_text(data: " ", overrides: "height=1mm"); ; run; N.B. : Avant d’exécuter les exemples de cet article, pensez à supprimer les tabulations… Ici, les méthodes .note() et .format_text() sont utilisées pour insérer des lignes de texte. Chaque appel à ces méthodes génère une ligne en sortie, ainsi plusieurs lignes peuvent être produites pour chaque enregistrement de la table source. Chaque méthode peut recevoir plusieurs paramètres. Dans cet exemple : data: Le contenu, qui peut être une variable overrides: Permet de modifier les attributs de style par défaut just: Contrôle l’alignement horizontal Tableaux Les méthodes Le principe de base à retenir est le suivant : Un tableau ne peut contenir que des lignes Une ligne ne peut contenir que des cellules Les cellules contiennent les éléments à afficher Les méthodes permettant de définir ces éléments sont les suivantes : .TABLE_START() .TABLE_END() .ROW_START() .ROW_END() .CELL_START() .CELL_END() .FORMAT_CELL() Mars 2012 Indique le Indique la Indique le Indique la Indique le Indique la Une façon début d'un tableau fin d’un tableau début d'une ligne fin d’une ligne début d'une cellule fin d’une cellule plus simple de définir une cellule -3- Un exemple data _null_; declare odsout obj(); obj.table_start(name: "Table1", label: "Notre première table", overrides: "width=4in"); obj.row_start(); obj.format_cell(data: "Un entête de tableau", column_span: 2, overrides: "backgroundcolor=cx494068 color=white"); obj.row_end(); obj.row_start(); obj.format_cell(data: "Trois petits", overrides: "just=left font_weight=bold"); obj.format_cell(data: "Cochons", overrides: "just=left"); obj.row_end(); obj.row_start(); obj.format_cell(data: "Pendus", overrides: "just=left font_weight=bold"); obj.format_cell(data: "Au plafond", overrides: "just=left"); obj.row_end(); obj.row_start(); obj.format_cell(data: "Combien", overrides: "just=left font_weight=bold"); obj.format_cell(data: "En voulez-vous ?", overrides: "just=left color=green"); obj.row_end(); Mars 2012 -4- obj.row_start(); obj.format_cell(data: "Un pied de tableau", column_span: 2, overrides: "font_size=10pt just=left"); obj.row_end(); obj.table_end(); run; Dans cet exemple, nous n’avons pas de table source, donc pas de variable à exploiter pour remplir le tableau. Nous ne passons donc qu’une seule fois dans la boucle DATA, comme si nous ne traitions qu’un seul enregistrement. Notez bien que les lignes du tableau ne sont pas des enregistrements au sens SAS du terme. Pour illustrer cela, voyons un autre exemple … Mars 2012 -5- Un autre exemple data _null_; set sashelp.class end=eof; length OR IM $ 50; if sex='M' then do; OR="backgroundcolor=blue color=white"; IM="preimage='C:\Images\male.png'"; end; else do; OR="backgroundcolor=pink color=black"; IM="preimage='C:\Images\female.png'"; Mars 2012 -6- end; if _n_ =1 then do; declare odsout obj(); obj.note(data: "La table SASHELP.CLASS", overrides: "font_style=italic font_size=12pt font_weight=bold color=cxbbb2e0", just: "C"); end; obj.table_start(name: Name, label: Name, overrides: "width=8cm"); obj.row_start(); obj.format_cell(data: Name, column_span: 2, overrides: OR); obj.format_cell(data: "", overrides: IM); obj.row_end(); obj.row_start(); obj.format_cell(data: "Age", overrides: "just=center font_weight=bold"); obj.format_cell(data: "Taille", overrides: "just=center font_weight=bold"); obj.format_cell(data: "Poids", overrides: "just=center font_weight=bold"); obj.row_end(); obj.row_start(); obj.format_cell(data: Age, overrides: "just=center"); obj.format_cell(data: Height, overrides: "just=center"); obj.format_cell(data: Weight, overrides: "just=center"); obj.row_end(); obj.table_end(); run; Dans cet exemple, nous avons généré un tableau complet pour chaque enregistrement de la table source. Nous avons également créé 2 nouvelles variables temporaires, OR et IM, qui nous ont permis d’appliquer des attributs de style différents en fonction des données en entrée. Agencement de la page Concept et terminologie Les éléments constitutifs d’une page peuvent être décrits de la façon suivante : Mars 2012 -7- Le Layout Container est une zone qui ne peut contenir que des Region Container. Le type de Layout (agencement) définira la façon dont les différentes régions se positionneront au sein de celui-ci. Cette zone peut être de taille fixe, ou s’adapter dynamiquement à la taille des régions qui la composent. Le Region Container est la zone où est placé le contenu à afficher (texte, tableau, graphique, autre Layout…). On peut également fixer sa taille, ou la laisser s’adapter au contenu. Les Titles et Footnotes ne font pas partie du Layout Container. Il existe 2 types d’agencement : LAYOUT_GRIDDED LAYOUT_ABSOLUTE Agencement relatif des éléments, basé sur une grille Positionnement des éléments en coordonnées absolues Agencement en grille L’agencement en grille est similaire à l’utilisation d’un tableau. On définit au départ le nombre de lignes et de colonnes du Layout, et cela définit le nombre de Regions disponibles dans ce Layout (nb lignes x nb colonnes), pour chaque boucle de l’étape DATA. Mars 2012 -8- data _null_; set comics end=eof; if _n_=1 then do; declare odsout obj(); obj.layout_gridded(columns: 2, overrides: "just=center"); end; obj.region(width: "5cm"); obj.image(file: photo, overrides: "just=left width=100pct height=100pct"); obj.format_text(data: strip(nom), overrides: "just=left width=100pct"); obj.region(width: "15cm"); obj.format_text(data: strip(desc)); if eof ne 1 then obj.format_text(data: ""); else obj.layout_end(); run; Dans cet exemple, nous avons défini notre Layout avec 2 colonnes (et 1 lignes, qui est la valeur par défaut). Cette définition n’a lieu d’être qu’une seule fois lors de l’exécution. Ensuite, nous créons 2 Regions, qui chacune vont recevoir le contenu – une image et du texte pour la première, du texte pour la seconde. Agencement absolu L’agencement en positon absolu permet une mise en place très précise des éléments dans la page. Cela est particulièrement utile pour les sorties de type PRINTER (comme le format PDF). Mars 2012 -9- title; ods listing close; ods html close; options nodate nonumber; ods escapechar="~"; options papersize=(15cm 10cm); options topmargin=0cm bottommargin=0cm leftmargin=0cm rightmargin=0cm; ods pdf file="Carte.pdf" notoc newfile=Bygroup; data _null_; set sashelp.class; by name; if _N_=1 then do; declare odsout obj(); end; obj.open_dir(name: name, label: "", by: 1); obj.layout_absolute(overrides: "borderwidth=1"); obj.region(width: "15cm", height: "2cm", overrides: "background=cx494068"); obj.format_text(data: "Groupe Scolaire L. Aragon", overrides: "color=cxbbb2e0 font_size=32pt", just: 'c'); Mars 2012 - 10 - obj.region(width: "3.5cm", height: "5cm", x: "1cm", y: "3cm", overrides: "background=white BORDERWIDTH=1mm"); obj.format_text(data: "Photo", overrides: "color=black font_style=italic font_size=12pt", just: 'c'); obj.region(width: "8cm", height: "5cm", x: "6cm", y: "3cm", overrides: "background=lightgrey"); obj.table_start(overrides: "rules=none frame=void cellpadding=0 cellspacing=0"); obj.row_start(); obj.format_cell(data: "ELEVE", column_span: 2, overrides: "width=5cm height=1.5cm color=purple font_size=18pt font_weight=bold just=center"); obj.row_end(); obj.row_start(); obj.format_cell(data: "Nom", overrides: "width=2cm font_size=12pt just=left"); obj.format_cell(data: name, overrides: "width=3cm font_size=14pt just=left"); obj.row_end(); obj.row_start(); obj.format_cell(data: "Age", overrides: "font_size=12pt just=left"); obj.format_cell(data: age, overrides: "font_size=14pt just=left"); obj.row_end(); obj.row_start(); obj.format_cell(data: "Poids", overrides: "font_size=12pt just=left"); obj.format_cell(data: weight, overrides: "font_size=14pt just=left"); obj.row_end(); obj.row_start(); obj.format_cell(data: "Taille", overrides: "font_size=12pt just=left"); obj.format_cell(data: height, overrides: "font_size=14pt Mars 2012 - 11 - just=left"); obj.row_end(); obj.table_end(); obj.region(width: "13cm", height: "0.8cm", x: "1cm", y: "8.5cm", overrides: "background=lightgreen vjust=middle"); obj.format_text(data: "Carte strictement personnelle", overrides: "color=darkgreen font_style=italic font_size=12pt", just: 'c'); obj.layout_end(); /*absolute*/ obj.close_dir(); run; ods pdf close; title; footnote; Pour chaque Region dans notre Layout, nous avons précisé sa taille (width et height) et la position du coin supérieur gauche (x et y). La méthode .open_dir() indique que l’on va créer un nouveau fichier pour chaque occurrence de la variable name. Divers Il y a quelques autres méthodes qui peuvent être utilisées : .page() .line() .image() .href() Initie une nouvelle page Trace une ligne horizontale Insère une image Insère un lien hypertexte Conclusion Pour certains rapports complexes, il était parfois nécessaire de retravailler ceux-ci dans un outil externe, afin d’obtenir exactement le rendu désiré. Avec l’ODS Report Writing Interface, vous pourrez améliorer de façon significative l’aspect de vos rapports, au sein de SAS, et ainsi automatiser plus facilement leur production. Références La documentation sur support.sas.com : http://support.sas.com/rnd/base/datastep/dsobject/index.html http://support.sas.com/rnd/base/datastep/dsobject/Power_to_show_paper.pdf http://support.sas.com/rnd/base/datastep/dsobject/Power_to_show_documentation.pdf Quelques articles techniques, études de cas et exemples : http://www2.sas.com/proceedings/sugi28/022-28.pdf http://support.sas.com/resources/papers/proceedings10/072-2010.pdf http://support.sas.com/resources/papers/proceedings12/071-2012.pdf Ludovic BREYSSE Consultant Support Clients SAS France Mars 2012 - 12 -