The presentation will include a code review and presentation of reports that appear in both English and Italian.



Similar documents
Choosing the Best Method to Create an Excel Report Romain Miralles, Clinovo, Sunnyvale, CA

Using Macros to Automate SAS Processing Kari Richardson, SAS Institute, Cary, NC Eric Rossland, SAS Institute, Dallas, TX

Salary. Cumulative Frequency

SAS/Data Integration Studio Creating and Using A Generated Transformation Jeff Dyson, Financial Risk Group, Cary, NC

Dynamic Decision-Making Web Services Using SAS Stored Processes and SAS Business Rules Manager

Creating Word Tables using PROC REPORT and ODS RTF

Managing Tables in Microsoft SQL Server using SAS

Create an Excel report using SAS : A comparison of the different techniques

Macros from Beginning to Mend A Simple and Practical Approach to the SAS Macro Facility

Web Reporting by Combining the Best of HTML and SAS

Methodologies for Converting Microsoft Excel Spreadsheets to SAS datasets

Tips and Tricks for Creating Multi-Sheet Microsoft Excel Workbooks the Easy Way with SAS. Vincent DelGobbo, SAS Institute Inc.

Data-driven Validation Rules: Custom Data Validation Without Custom Programming Don Hopkins, Ursa Logic Corporation, Durham, NC

Search and Replace in SAS Data Sets thru GUI

The SAS Data step/macro Interface

ABSTRACT INTRODUCTION SAS AND EXCEL CAPABILITIES SAS AND EXCEL STRUCTURES

More Tales from the Help Desk: Solutions for Simple SAS Mistakes Bruce Gilsen, Federal Reserve Board

ABSTRACT THE ISSUE AT HAND THE RECIPE FOR BUILDING THE SYSTEM THE TEAM REQUIREMENTS. Paper DM

Writing cleaner and more powerful SAS code using macros. Patrick Breheny

Importing Excel File using Microsoft Access in SAS Ajay Gupta, PPD Inc, Morrisville, NC

The Basics of Dynamic SAS/IntrNet Applications Roderick A. Rose, Jordan Institute for Families, School of Social Work, UNC-Chapel Hill

Chapter 8 Decision Support: Determine Feasibility of a Business Loan for the App

From The Little SAS Book, Fifth Edition. Full book available for purchase here.

Post Processing Macro in Clinical Data Reporting Niraj J. Pandya

Importing Excel Files Into SAS Using DDE Curtis A. Smith, Defense Contract Audit Agency, La Mirada, CA

Defining a Validation Process for End-user (Data Manager / Statisticians) SAS Programs

PharmaSUG 2014 Paper CC23. Need to Review or Deliver Outputs on a Rolling Basis? Just Apply the Filter! Tom Santopoli, Accenture, Berwyn, PA

Internet/Intranet, the Web & SAS. II006 Building a Web Based EIS for Data Analysis Ed Confer, KGC Programming Solutions, Potomac Falls, VA

WOW! YOU DID THAT WITH SAS STORED PROCESSES? Dave Mitchell, Solution Design Team, Littleton, Colorado

Advanced Tutorials. Numeric Data In SAS : Guidelines for Storage and Display Paul Gorrell, Social & Scientific Systems, Inc., Silver Spring, MD

Essential Project Management Reports in Clinical Development Nalin Tikoo, BioMarin Pharmaceutical Inc., Novato, CA

Session Attribution in SAS Web Analytics

Perfecting Report Output to RTF Steven Feder, Federal Reserve Board, Washington, D.C.

CHAPTER 1 Overview of SAS/ACCESS Interface to Relational Databases

Oracle OLAP. Describing Data Validation Plug-in for Analytic Workspace Manager. Product Support

Release 2.1 of SAS Add-In for Microsoft Office Bringing Microsoft PowerPoint into the Mix ABSTRACT INTRODUCTION Data Access

Introduction to SAS Business Intelligence/Enterprise Guide Alex Dmitrienko, Ph.D., Eli Lilly and Company, Indianapolis, IN

Using SAS Output Delivery System (ODS) Markup to Generate Custom PivotTable and PivotChart Reports Chevell Parker, SAS Institute

SAS Add in to MS Office A Tutorial Angela Hall, Zencos Consulting, Cary, NC

Overview. NT Event Log. CHAPTER 8 Enhancements for SAS Users under Windows NT

Beyond the Basics: Advanced REPORT Procedure Tips and Tricks Updated for SAS 9.2 Allison McMahill Booth, SAS Institute Inc.

Automate Data Integration Processes for Pharmaceutical Data Warehouse

Ad-hoc Reporting Report Designer

Effective Use of SQL in SAS Programming

Report Customization Using PROC REPORT Procedure Shruthi Amruthnath, EPITEC, INC., Southfield, MI

ABSTRACT INTRODUCTION

MICROSOFT ACCESS STEP BY STEP GUIDE

An Introduction to SAS/SHARE, By Example

The Power of CALL SYMPUT DATA Step Interface by Examples Yunchao (Susan) Tian, Social & Scientific Systems, Inc., Silver Spring, MD

Data Export User Guide

Intro to Mail Merge. Contents: David Diskin for the University of the Pacific Center for Professional and Continuing Education. Word Mail Merge Wizard

How To Write A Clinical Trial In Sas

A Method for Cleaning Clinical Trial Analysis Data Sets

ODS for PRINT, REPORT and TABULATE

AN INTRODUCTION TO MACRO VARIABLES AND MACRO PROGRAMS Mike S. Zdeb, New York State Department of Health

Simple Invoicing Desktop Database with MS Access c 2015 by David W. Gerbing School of Business Administration Portland State University

Flat Pack Data: Converting and ZIPping SAS Data for Delivery

Nine Steps to Get Started using SAS Macros

Excel Working with Data Lists

Excel Reports User Guide

Reading Delimited Text Files into SAS 9 TS-673

You have got SASMAIL!

Can SAS Enterprise Guide do all of that, with no programming required? Yes, it can.

Table Lookups: From IF-THEN to Key-Indexing

Handling Missing Values in the SQL Procedure

Foundations & Fundamentals. A PROC SQL Primer. Matt Taylor, Carolina Analytical Consulting, LLC, Charlotte, NC

How to Use SDTM Definition and ADaM Specifications Documents. to Facilitate SAS Programming

Paper CI Marketing Campaign (Message sent) Contact Recorded in SAS System Tables. Response Recorded in SAS System Tables

Embedded Special Characters Kiran Karidi, Mahipal Vanam, and Sridhar Dodlapati

5. Crea+ng SAS Datasets from external files. GIORGIO RUSSOLILLO - Cours de prépara+on à la cer+fica+on SAS «Base Programming»

Using SAS Enterprise Business Intelligence to Automate a Manual Process: A Case Study Erik S. Larsen, Independent Consultant, Charleston, SC

Paper Hot Links: Creating Embedded URLs using ODS Jonathan Squire, C 2 RA (Cambridge Clinical Research Associates), Andover, MA

THE HELLO WORLD PROJECT

SAS Comments How Straightforward Are They? Jacksen Lou, Merck & Co.,, Blue Bell, PA 19422

Using SAS With a SQL Server Database. M. Rita Thissen, Yan Chen Tang, Elizabeth Heath RTI International, RTP, NC

ENHANCING SAS OUTPUT WITH OUTPUT DELIVERY SYSTEM (ODS)

Part 1 Foundations of object orientation

Working together with Word, Excel and PowerPoint

B) Mean Function: This function returns the arithmetic mean (average) and ignores the missing value. E.G: Var=MEAN (var1, var2, var3 varn);

PS004 SAS , using Data Sets and Macros: A HUGE timesaver! Donna E. Levy, Dana-Farber Cancer Institute

PROC LOGISTIC: Traps for the unwary Peter L. Flom, Independent statistical consultant, New York, NY

SAS Macro Programming for Beginners

Tricks Using SAS Add-In for Microsoft Office

PharmaSUG Paper AD11

Make it SASsy: Using SAS to Generate Personalized, Stylized, and Automated Lisa Walter, Cardinal Health, Dublin, OH

Sample- for evaluation purposes only! Advanced Excel. TeachUcomp, Inc. A Presentation of TeachUcomp Incorporated. Copyright TeachUcomp, Inc.

SUGI 29 Coders' Corner

Transcription:

SAS Reporting in English, ed anche in italiano: A Methodology for Creating Reports in Two Languages Deborah Testa, Seven of Nine Systems, Inc. Studio City, CA ABSTRACT Project Leonardo was a disease management study conducted in two countries, a joint undertaking between researchers in California, project managers and clinicians at Pfizer Italia in Rome, and medical professionals in the Regional Health Authority in the southern Italian region of Puglia. A primary goal of the project was to demonstrate the value of a partnership between public and private entities, so keeping all team members informed was paramount. The project required weekly operational reports and interim and final outcomes analyses. The researchers in California spoke little or no Italian, and some of the regional clinicians (as well as their patients) spoke little or no English. But everyone needed to see the weekly progression of the project, so we needed to produce reports for team members who speak only English and also for those who speak only Italian. To be effective project management tools, our data presentations needed to respect local conventions regarding the display of numbers and dates and well as using the appropriate vocabulary. To fully support the goal of partnership, we decided to require our reports contain nothing that either an American or an Italian team member would find foreign or unfamiliar. We implemented that requirement using a combination of professional translation services, existing database elements, SAS macro variables, formats, and some lesser-known system options. The implementation is flexible enough to support reports in any number of languages. The presentation will include a code review and presentation of reports that appear in both English and Italian. INTRODUCTION Our solution to the challenge of creating bilingual reports combined: 1. The use of an external Excel file to store metadata. 2. Standard SAS macro substitution. 3. SAS formats and functions. 4. SAS system options. The reports were developed using the ODS RTF destination and (in the case of the sample included in this paper) the TABULATE procedure. The reports existed in English versions before we received the requirement to translate them into Italian. The solution turned out to be quite robust: we were able to produce almost 100 weekly reports perfectly formatted for our two sets of users in the U.S. and in Italy. It would be an easy matter to extend it to produce reports in three or more languages. 1

EXTERNAL EXCEL FILE We examined the report mock-up and identified report elements that would require manipulation. These included header strings, footer strings, column headers, formats, and data values. Wherever possible, we extracted these elements into an external metadata file. In the end, the SAS code was strikingly simple, and therefore easy to maintain. Although this data could have been stored in the SAS code itself, using an external Excel file made collaboration easier. We always tried to remain cognizant of the one of the primary project goals: to demonstrate the value of partnership and collaboration. All of the metadata data were stored in a single Excel file, and report-specific information was stored in a worksheet having the same name as the report itself. Because the names of the projects were drawn from famous Italian artists such as Michelangelo, Leonardo, Raffaello, etc., the Excel file was given a name based on that: MichelangeloReports.xlsx. Within that Excel file, a worksheet was created for each report, with a name identical to the report name. In this paper, I am using the Patient Milestones Report as an example, so we have a worksheet inside Michelangeo Reports.xlsx named PatientMilestonesReport. In that worksheet, we created three columns: Element, English and Italiano. Then we entered one line for each report element, and gave it a name. The first element on our mock-up is title3. So the first data line in the Excel file looks like this: Element English Italiano Title3 Patient Milestones I punti maggiori We engaged the services of a professional translator to complete the Italiano column by providing a translation of the text in the English column. Although the phrases were generally simple and it might have been possible to use Google Translate, we decided to avoid any awkwardness that might come from using a blunt instrument like that, in favor of translations based on the nuances of a professional. The Excel file was completed with as many rows as were required for each report. The worksheet for our Patient Milestones Report eventually looked like the file provided as Appendix 1. Each report is programmed to look for its counterpart worksheet in the Excel file, using the IMPORT procedure. Since the project name is provided to all reports in a macro variable named &ShortName, the report is programmed to look for metadata in &ShortName.Reports.xlsx. Once the three Excel columns have been read into a SAS data set, basic DATA steps can place the values into macro variables. data_null_; set ReportParameters_&Language; call symput(element,trim(&language)); If we run this DATA step inside a macro where the value of &Language has been set to English, we will end up with 17 macro variables: &title3, &Note, &Column1Header, etc. having English strings as values: Patient Milestones, etc. If we run the DATA step after the value of &Language has been set to Italiano, we will have the same 17 macro variables with the same names, but their values will have Italian strings as values: I punti maggiori, etc. The report code has abstracted all of these strings and replaced them with the appropriate macro variables. The report code has this single statement, which suffices for both languages: Title3 &title3 ; This makes the report code nicely concise: there aren t a lot of IF/THEN statements with hard-coded strings strewn throughout the code. Almost everything that is variable is in the Excel file. The value will resolve in either English or Italian depending on the value of &Language.. Since the PROC TABULATE code is embedded in a macro that has a single named parameter %macro DoReport(Language=); We invoke the macro twice: %DoReport(Language=English) %DoReport(Language=Italiano) 2

Since the value of &Language is also used the in the ODS statement that establishes the name of the output file, the two invocations of the macro create the following two files: PatientMilestonesReport_English.doc Patient MilestonesReport_Italiano.doc A separate SAS program zips up all of the English reports into one.zip file, and all of the Italian reports in another. CONDITIONAL SAS FORMATS There were a couple of places where we have created derived values in the analysis data set. An example of this is the column CaseStatus, which had been assigned the values Open, Closed and Unknown. Although it would have been possible to integrate these into the Excel file, there were a few times when it was deemed simpler to create two SAS formats: proc format; value $Open_English; value $Open_Italiano Open = Aperto Closed = Chiuso Unknown = Sconoscuito ; proc tabulate format CaseStatus $Open_&Language..; The key is to use the name string in the beginning of the two format names ( Open_ ), and the two expected values of &Language to complete the two names. Then use the name of the macro variable in the report code. The null format for English means that the derived values will not change in an English report. We were also challenged by the fact that in the U.S., dots and commas are used in different ways in numeric representation. In the U.S., we would use 1,003.5; in Italy, we would use 1.003,5. In the U.S. we would use 10.5%; in Italy we would use 10,5%. The SAS format commaxw.d is the Italian (or European) equivalent to the commaw.d format. So a tiny DATA step instructs our report macro which one to use: data_null_; if symget( Language )= English then call symput( NFormat, comma6.1 ); else if symget( Language )= Italiano then call symput( NFormat, commax6.1 ); Then we used the macro variable in the PROC TABULATE TABLES statement: tables DaysEnrolled= &Column5Header *sum= *f=&nformat. We used a similar pair of formats to control the way dates appear to users: data_null_; if symget( Language )= English then call symput( DFormat, date9. ); else if symget( Language )= Italiano then call symput( DFormat, eurdfde9. ); Then we used the macro variable in the PROC TABULATE TABLES statement: tables CMCompletedDate= &Column6Header *sum= *f=&dformat. Using this pair of date formats, Italian users would see 13Ott2010 whereas U.S. users see 13OCT2010. 3

SAS SYSTEM OPTIONS: LOCALIZATION After a little bit of research, we learned that the SAS system option called LOCALE would accomplish exactly what we needed in our report footers. The SAS documentation explains the concept of locale this way: A locale reflects the language, local conventions such as data formatting, and culture for a geographical region. Local conventions might include specific formatting rules for dates, times, and numbers and a currency symbol for the country or region. Collating sequence, paper size, postal addresses, and telephone numbers can also be included in locale. 1 If you re using SAS in the U.S., the value of this option is set to English_UnitedStates. Changing it in the Italian invocation of our report macros to Italian_Italy changes the way some formats such as NLDATE behave. If I want the footnote of my report to read Tuesday, September 7, 2010 and giovedì 07 settembre 2010 and I need to derive that information from a SAS date value, then combining the SAS system option locale with the SAS format NLDATE and the companion SAS function NLDATE is the only approach that will give me exactly what I want, even down to the nuance that in English the names of the days of the week are capitalized and in Italian they are not. And nldate is both a SAS format and a SAS function. Using both of those together, it is possible to make the last details fall into place. One very important warning: if you change the value of the system option LOCALE, remember to change it back at the end of your program: options locale=english_unitedstates; CONCLUSION If you need to produce bilingual (or even multilingual) reports, effective use of the SAS macro facility and SAS reports will get you almost everything you need. Take the time to research how SAS uses the concept of localization, and no detail is out of your reach. It s a powerful tool, and can be used to produce reports in language based on alphabets and symbols vastly different from the ones used in English. It would be easy, for example, to modify this approach to produce reports in English and Chinese, or English and Arabic. There are many other concepts besides the ones touched on in this paper to help you produce polished, professional output. REFERENCES 1 SAS 9.2 National Language Support (NLS), Reference Guide. Copyright 2009, SAS Institute Inc., Cary, NC, USA. All Rights Reserved. Reproduced with permission of SAS Institute Inc., Cary, NC. Start here for an introduction to how SAS implements localization: http://support.sas.com/documentation/cdl/en/nlsref/61893/html/default/viewer.htm#/documentation/cdl/en/nlsref/618 93/HTML/default/nls-overview.htm ACKNOWLEDGMENTS I would like to thank my colleagues both in the U.S. and in Italy for letting me work on such a fun project. CONTACT INFORMATION Your comments and questions are valued and encouraged. Contact the author at: Deborah Testa Seven of Nine Systems, Inc. dtesta@sevenofninesystems.com www.sevenofninesystems.com Electronic copies of the following are available upon request: Copies of the Excel metadata file described in this paper. 4

Copies of the reports. SAS report code. SAS and all other SAS Institute Inc. product or service names are registered trademarks or trademarks of SAS Institute Inc. in the USA and other countries. indicates USA registration. Other brand and product names are trademarks of their respective companies. 5

APPENDIX 1: The CONTENTS of the Excel metadata file 6

SAS REPORT CODE proc format; value $Open_English; value $Open_Italiano 'Open'='Aperto' 'Closed'='Chiuso' 'Unknown'='Sconoscuito'; run; quit; %macro DoReport(Language=); %if &Language=English %then %do; options locale = English_UnitedStates; %end; %else %if &Language=Italiano %then %do; options locale = Italian_Italy; %end; data _null_; call symput('reportdate',trim(left(put(today(),nldate.)))); call symput('edate',trim(left(put(input("&extractdate",date9.),nldate.)))); call symput('reportday',(nldate(today(),'%a'))); if symget('language')='english' then do; call symput('reporttime',trim(left(put(time(),nltimap9.)))); call symput('at','at'); call symput('nformat','comma6.1'); call symput('dformat','date9.'); end; else if symget('language')='italiano' then do; call symput('reporttime',trim(left(put(time(),nltime.)))); if hour(time())=1 then call symput('at',"all'"); else call symput('at','alle'); call symput('nformat','commax6.1'); call symput('dformat','eurdfde9.'); end; run; proc import out=reportparameters_&language datafile="e:\clientdata\pfizeritalia\&shortname\&shortname.reports.xlsx" dbms=excel replace; range="&compressedreportname.$"; getnames=yes; mixed=yes; scantext=yes; usedate=yes; scantime=yes; run; data _null_; set ReportParameters_&Language; call symput(element,trim(&language)); run; 7

options orientation = portrait ; ods rtf body = "&RTFDestination.&CompressedReportName._&Language..doc" style = TestaDefault ; proc tabulate data = PatientMilestones; class CareManager MemberID CaseStatus &style; classlev CareManager MemberID CaseStatus &style; var EnrollmentDate DaysEnrolled CMCompletedDate MMGCompletedDate PdSCompletedDate FUCompletedDate &style; tables CareManager="&Column1Header"*MemberID="&Column2Header"*CaseStatus="&Column3Header", EnrollmentDate="&Column4Header"*sum=' '*f=&dformat.*&varstyle DaysEnrolled="&Column5Header"*sum=' '*f=&nformat.*&varstyle CMCompletedDate="&Column6Header"*sum=' '*f=&dformat.*&varstyle MMGCompletedDate="&Column7Header"*sum=' '*f=&dformat.*&varstyle PdSCompletedDate="&Column8Header"*sum=' '*f=&dformat.*&varstyle FUCompletedDate="&Column9Header"*sum=' '*f=&dformat.*&varstyle / misstext = ' ' box = {label="&note" s=[font_face="calibri" FONT_SIZE=2 JUST=L VJUST=B FONT_STYLE=italic] } ; title3 "&title3"; footnote1 j=r "^S={font_style=italic}&footnote1 &ReportDay &ReportDate &at &ReportTime.. ^S={}"; footnote2 j=r "^S={font_style=italic}&footnote2 &EDate. ^S={}"; footnote3 j=r "^S={font_style=italic}&footnote3 &SASSubProgramName ^S={}"; footnote4 j=r "^S={font_style=italic}&CompressedReportName..doc ^S={}"; footnote5 j=r "{\i &footnote5 }\~{\field{\*\fldinst {\i PAGE }}}\~{\i &footnote5of}\~{\field{\*\fldinst{\i NUMPAGES }}}"; keyword sum &style ; format CaseStatus $Open_&Language..; run; ods rtf close; options locale = English_UnitedStates; %mend DoReport; %DoReport(Language=English) %DoReport(Language=Italiano) 8