ODS measured tagset til RTF er smart og kan tilpasses 4. Oktober 2012 Marc Andersen, StatGroup ApS, Denmark
Indhold Oversigt Hvorfor Hvad Validering Programkode til tagset: send mail til Tips Konklusion 2
Oversigt Tagset ODS RTF_title Udvidelse af SAS measured tagsets.rtf Indrykning af tekst i celle indrykker alle linier Indhold af titel statement kommer i Word indholdsfortegnelse Side hoved og side fod kan tilpasses med SAS ODS Dokument egenskaber kan sættes med SAS ODS 3
Hvorfor lave et nyt tagset til RTF Lav rapport Hent data Rapporter data Analyser data Microsoft Word (RTF), Microsoft Powerpoint 4
Tagset RTF_title: Titler og fodnoter options papersize=a4 orientation=landscape; ods tagsets.rtf_title file="demo_template.rtf" style=listings nogtitle nogfootnote options(contents= 'YES' TOPHEADER='144 BOTTOMHEADER='1440' TOC="off" TOPHEADER_RTFTEXT='\pard{Company {\field{\fldinst{docproperty MYCOMPANY \\* MERGEFORMAT}}}, document {\field{\fldinst{docproperty MYTITLE \\* MERGEFORMAT}}}} \par' BOTTOMHEADER_TEXT='[BOTTOMHEADER]' TOC_DESCRIPTION_TEXT='[Enter Table of Contents Header]' USERPROPERTIES="start" MYCOMPANY="[CompanyName]" MYTITLE="[Example]" ) ; title "Listing 1: Dataset sashelp.class"; title2 "This is the title2 - but it does not go into the TOC"; footnote "Footnote to Listing 1"; proc report data=sashelp.class nofs headline headskip missing split=" "; column Name Sex Age Height Weight; compute after / style={just=left}; line @1 Line made by compute after"; endcomp; run; title "Listing 1: Dataset sashelp.class"; title2 "This is the title2 - but it does not go into the TOC"; footnote "Footnote to Listing 1"; ods tagsets.rtf_title close; 5
Hvorfor bruge ODS Forenkle Øget krav til form og layout kræver mere og indviklet programmering Analyserne kan programmeres forholdsvis kort med SAS Adskille programmering af analyserne fra form oglayout Muligt SAS Output Delivery System (ODS) ODS Styles, ODS tagsets, ODS DOCUMENT ODS HTML: SAS 7 (1998), SAS 8 (1999) ODS MARKUP and TAGSET in PROC TEMPLATE, ODS RTF production: SAS 8.2 (2001) Measured RTF tagset production (SAS 9.2, 2008; SAS 9.3 2011) (http://support.sas.com/rnd/base/ods/o dsrtf/measured.html) 6
Indrykning: Tagsets.rtf versus Tagsets.rtf_title Tagsets.rtf \in Tagsets.rtf_title \lin 7
Indrykning: eksempel på ændring Koden for eksisterende sas tagsets.rtf ses ved: proc template; source Tagsets.rtf / file="tagsets-rtf.txt" nofollow ; Ca 2000 linier kode. Eksisterende tagsets.rtf har put "\fi" INDENT /if INDENT; som giver indrykning i starten af linien. RTF kontrol ord \lin giver indtrykning af afsnittet. Ændret til i tagsets.rtf_title: put "\lin" INDENT /if INDENT; 8
Indrykning: brug og resultat... select; when (seq_pt=0) do; /* Header */ col1_text= soc_text; style_text="font_weight=bold"; when (seq_pt>0) do; /* Detail */ col1_text= pt_text; style_text="indent=2cm";. proc report ; column style_text col1_text ; define style_text / display noprint; define col1_text / "SOC/PT" display width=50 flow style={cellwidth=4cm}; compute col1_text; call define(_col_,"style/merge", catx(" ","style=","{",style_text,"}")); endcomp; Tagsets.rtf_title \lin 9
Hvad er: Rich Text Format RTF Første version 1987 Seneste version 1.9.1 http://www.microsoft.com/en us/download/details.aspx?id=10725 http://en.wikipedia.org/wiki/rich_text_format Fremadrettet The RTF file format is no longer enhanced to include new features and functionality. Features and functionality that are new to Word 2010 and future versions of Word are lost when they are saved in RTF. In addition, Word 2010 supports a new converter interface based on Open XML Formats. http://technet.microsoft.com/en us/library/cc179199(office.14).aspx 10
Tagsets meget kort Tagsets defineres i PROC template. Tagsets er specielt egnet til at lave XML (HTML) hvor der er samhørende start og slut elementer. Tagsets kan også bruges til at skrive tekst filer. Tagsets modtager events fra procedure, som laver output. SAS har tagsets.simplecsv som er tagset der skriver indholdet til en tekst fil. Uddrag: define event data; start: put $delimiter /if ^cmp( COLSTART, "1"); put """"; put VALUE; finish: put """"; 11
Om SAS Measured RTF Tagsets behandler events: table, row, cell etc Measured RTF har yderligere event for side skrift RTF side skift bestemmes af SAS Output fra en procedure som fylder flere sider, opdeles i enkelt sider med title og footnote på hver side SAS RTF tagset viser title og footnotes som tabel Se også Description of formating possible and programming strategy for using ODS http://support.sas.com/resources/pa pers/proceedings12/006 2012.pdf Teaching Your RTF Tagset to Do Clever Tricks http://support.sas.com/rnd/base/od s/odsrtf/067 31 updated.pdf 12
SAS tagsets.rtf: ingen TOC fra title options papersize=a4 orientation=landscape; ods tagsets.rtf file="demo_template-rtf.rtf" nogtitle nogfootnote options(tables_off="systitleandfootercontainer") ; title "Listing 1: Dataset sashelp.class"; title2 "This is the title2 - "; footnote "Footnote to Listing 1"; proc report data=sashelp.class nofs headline headskip missing split=" "; column Name Sex Age Height Weight; compute after / style={just=left}; line @1 Line made by compute after"; endcomp; run; ods tagsets.rtf close; 13
Tagset RTF_title: Title itoc ods path(prepend) sassetup.tmpl(read); options papersize=a4 orientation=landscape; ods tagsets.rtf_title file="demo_template.rtf" style=listings nogtitle nogfootnote options(contents= 'YES' TOPHEADER='144 BOTTOMHEADER='1440' TOC="off" TOPHEADER_RTFTEXT=' MYCOMPANY MYTITLE ' BOTTOMHEADER_TEXT='[BOTTOMHEADER]' TOC_DESCRIPTION_TEXT='[..TOC Header ]' USERPROPERTIES="start" MYCOMPANY="[CompanyName]" MYTITLE="[Example]" ) ; title "Listing 1: Dataset sashelp.class"; title2 "This is the title2 "; footnote "Footnote to Listing 1"; proc report data=sashelp.class nofs headline headskip missing split=" "; column Name Sex Age Height Weight; compute after / style={just=left}; line @1 Line made by compute after"; endcomp; run; ods tagsets.rtf_title close; 14
Tagset RTF_title: Titler og fodnoter options papersize=a4 orientation=landscape; ods tagsets.rtf_title file="demo_template.rtf" style=listings nogtitle nogfootnote options(contents= 'YES' TOPHEADER='144 BOTTOMHEADER='1440' TOC="off" TOPHEADER_RTFTEXT='\pard{Company {\field{\fldinst{docproperty MYCOMPANY \\* MERGEFORMAT}}}, document {\field{\fldinst{docproperty MYTITLE \\* MERGEFORMAT}}}} \par' BOTTOMHEADER_TEXT='[BOTTOMHEADER]' TOC_DESCRIPTION_TEXT='[Enter Table of Contents Header]' USERPROPERTIES="start" MYCOMPANY="[CompanyName]" MYTITLE="[Example]" ) ; title "Listing 1: Dataset sashelp.class"; title2 "This is the title2 - but it does not go into the TOC"; footnote "Footnote to Listing 1"; proc report data=sashelp.class nofs headline headskip missing split=" "; column Name Sex Age Height Weight; compute after / style={just=left}; line @1 Line made by compute after"; endcomp; run; title "Listing 1: Dataset sashelp.class"; title2 "This is the title2 - but it does not go into the TOC"; footnote "Footnote to Listing 1"; ods tagsets.rtf_title close; 15
Overvejelser: Title og footnote Footnote: skal være del af tabellen det gør det nemmere at lave cut andpaste til powerpoint Vis kun title1 i Table of Contents (TOC) Measured tagsets deler en lang tabel op i mange tabeller svarende til hver side med titles i starten af tabellen. For ikke at få indførsel i TOC for hver side, så markeres kun title på første side som TOC. Vis Title1 line i navigation pane Tekst markeret med Heading styles vises i navigation pane. Men: styles defineret som Headings vises ikke i navigation pane, når de er del af en tabel (http://office.microsoft.com/en us/word help/troubleshootthe document map HP005189669.aspx). Titles er ikke del af tabellen. Teksten indsættes istedet for at være del af tabel. I RTF skal Heading 1 være del af stylesheet: tilføj RTF {\s1 Heading 1;} is starten af RTF file Paragraph med title 1 markeres som heading: \pard\s1{listing 1\par} Efterfølgende title 2.. skal ikke mærkes som heading. Virker ikke for Word 2007 Gem title1 text i ODS stream og de efterfølgende title2.. i en ande stream. Skriv først RTF control word \s1, så stream med title1 text, derefter stream med resten af title2.. telst 16
Brug: Side hoved og side fod options papersize=a4 orientation=landscape; ods tagsets.rtf_title file="demo_template.rtf" style=listings nogtitle nogfootnote options(contents= 'YES' TOPHEADER='144 BOTTOMHEADER='1440' TOC="off" TOPHEADER_RTFTEXT='\pard{Company {\field{\fldinst{docproperty MYCOMPANY \\* MERGEFORMAT}}}, document {\field{\fldinst{docproperty MYTITLE \\* MERGEFORMAT}}}} \par' BOTTOMHEADER_TEXT='[BOTTOMHEADER]' TOC_DESCRIPTION_TEXT='[Enter Table of Contents Header]' USERPROPERTIES="start" MYCOMPANY="[CompanyName]" MYTITLE="[Example]" ) ; title "Listing 1: Dataset sashelp.class"; title2 "This is the title2 - but it does not go into the TOC"; footnote "Footnote to Listing 1"; proc report data=sashelp.class nofs headline headskip missing split=" "; column Name Sex Age Height Weight; compute after / style={just=left}; line MERGEFORMAT}}}} @1 Line made by compute after"; \par' endcomp; USERPROPERTIES="start" run; ods tagsets.rtf_title close; TOPHEADER_RTFTEXT='\pard{Company {\field{\fldinst{docproperty MYCOMPANY \\* MERGEFORMAT}}}, document {\field{\fldinst{docproperty MYTITLE \\* MYCOMPANY="[CompanyName]" MYTITLE="[Example]" 17
Overvejelser: Side hoved og side fod Option name TOPHEADER BOTTOMHEADER TOPHEADER_RTFTEXT TOPHEADER_TEXT BOTTOMHEADER_RTFTEXT BOTTOMHEADER_TEXT Description Vertical Position for header in twips from top of page (twips: 1/1440 inch) Vertical Position for footer in twips from bottom of page RTF code to put in the header. Default value the contents of TOPHEADER_TEXT rtfencoded. Plain text without rtf codes RTF code to put in the footer. Default value the contents of TOPFOOTER_TEXT rtfencoded. Plain text without rtf codes 18
Dokument egenskaber Dokument egenskaber bruges blandt andet med dokument håndteringssystemer. tagsets.rtf_title har et interface som benytter at vilkårlige options kan overføres med ODS: USERPROPERTIES="start" MYCOMPANY="[CompanyName]" MYTITLE="[Example] Alternativt: skriv det I tagset koden; interface med macro variable (MVAR). Tagset koden til at skrive egenskaber til RTF er: put "{\propname " _name_ "}"; put "\proptype30"; put "{\staticval " _value_ "}"; Bruger definerede egenskaber kan indsættes i RTF dokumentets hoved ved kaldet TOPHEADER_RTFTEXT= \pard{company {\field{\fldinst{docproperty MYCOMPANY \\* MERGEFORMAT}}}, Document {\field{\fldinst{docproperty MYTITLE \\* MERGEFORMAT}}}} \par 19
Validering, metode A: Sammenlign indhold fra SAS og Word SAS tagset gemmer indhold af tabel proc template; define tagset Tagsets.dump_txt / store=sassetup.tmpl; define event table; start: put "Table " NL; define event colspecs; set $ThisColCount COLCOUNT; define event row; put strip($thiscolcount) NL; define event header; start: put strip(value) NL; define event data; start: put strip(value) NL; parent = tagsets.simplecsv; run; /* Brug: ods tagsets.dump_txt file="dump_sas.txt" ; */ Word macro gemmer indhold af tabel Function CellTextOnly(text) CellTextOnly = Mid(text, 1, Len(text) - 2) End Function Sub dump_word() Set fs = CreateObject("Scripting.FileSystemObject") fn = fs.buildpath(activedocument.path, _ fs.getbasename(activedocument.name)+"-dump_word.txt") Open fn For Output As #1 For t = 2 To ActiveDocument.Tables.Count 'Skip TOC Set atable = ActiveDocument.Tables(t) Print #1, "Table" For r = 1 To atable.rows.count CellCount = atable.rows(r).cells.count Print #1, Trim(CellCount) For c = 1 To CellCount Set CellRange = atable.cell(r, c).range Print #1, CellTextOnly(CellRange.text) Next c Next r Next t Close #1 End Sub Indholdet af tekst filerne er ens på nær formatering og tomme celler. 20
Validering, metode A: Sammenlign indhold fra SAS og Word SAS tagset udskriver header og data proc template; define tagset Tagsets.dump_txt / definestore=sassetup.tmpl; event row; define event table; start: put "Table " NL; define event header; define event colspecs; start: set $ThisColCount COLCOUNT; define event row; put strip($thiscolcount) NL; define event data; definestart: event header; start: put strip(value) NL; define event data; start: put strip(value) NL; parent = tagsets.simplecsv; run; put strip($thiscolcount) NL; put strip(value) NL; put strip(value) NL; Word macro for dumping cell contents Function CellTextOnly(text) CellTextOnly = Mid(text, 1, Len(text) - 2) End Function For r = 1 To atable.rows.count Sub dump_word() Set fs CellCount = CreateObject("Scripting.FileSystemObject") = _ fn = fs.buildpath(activedocument.path, atable.rows(r).cells.count fs.getbasename(activedocument.name)+"-dump_word.txt") Print #1, Trim(CellCount) Open fn For Output As #1 For For t = c 2 = To 1 ActiveDocument.Tables.Count To CellCount 'Skip TOC Set atable Set CellRange = ActiveDocument.Tables(t) = _ Print #1, "Table" atable.cell(r, c).range For r = 1 To atable.rows.count Print CellCount #1, = atable.rows(r).cells.count CellTextOnly(CellRange.text) Print #1, Trim(CellCount) For c = 1 To CellCount Next c Set CellRange = atable.cell(r, c).range Next r Print #1, CellTextOnly(CellRange.text) Next c Next r Next t Close #1 End Sub 21
Validering method B: Sammenlign resultat fra tagsets.rtf og tagsets.rtf_title output iword 22
Tips og tricks Brug putlog itagset koden Se i RTF filen søg efter kendte tekster Brug tracers irtf filen dummy RTF kontrol ord for debugging, fx \AAA, \HereItIs ukendte kontrol ord ignores Brug værdier som er nummer at genfinde i RTF filen, fx 1.5123cm som længde angivelse For at forstå ODS events se på HTML output eller SAS tagsets med event maps Gem tagsets i separat bibliotek (SAS version og platform specifikt) : ods path(prepend) sassetup.tmpl(read); proc template; define tagset Tagsets.txt_dump / store=sassetup.tmpl; Automatiser test programmer Vær opmærksom på ændringer mellem SAS versions (http://support.sas.com/kb/45/138.html) Sammenhænget mellem SAS options, formatering og tagset er indviklet og kompleks vær forberedt på overraskelser; test ofte 2012 okt 04 23
Konklusion Værd at undersøge andre formater HTML, DocBook ODS RTF til Word virker godt nok Mangler som kan omgås Venter på bedre integration med Word Realistisk muligt at bruge og tilpasse et tagset Ikke noget som skal gøres hver dag Tagsets.rtf_title virker som tiltænkt 24