A Poor/Rich SAS® User’s Proc Export Gro… ·  · 2016-03-11Hall of Fame (2011), SAS Circle of...

Preview:

Citation preview

Next Presentation:

Art holds a PhD from Michigan State University,has been a SAS user since 1974, is president

of the Toronto Area SAS Society and hasreceived such recognitions as the SAS

Customer Value Award (2009), SAS-LHall of Fame (2011), SAS Circle of

Excellence (2012) and, in 2013,was recognized as being the

first SAS user to have beenawarded more than 10,000

points on the SASDiscussion Forums

Presenter: Arthur Tabachneck

2

SAS® Global Forum 2014

March 23-26 Washington, DC

Arthur TabachneckThornhill, ON Canada

Tom AbernathyNew York, NY

Matt KastinPenn Valley, PA

4

How many of you are able to export SAS

datasets to Excel using PROC EXPORT?

Question

5

Would you like to automate the process to be

a point-and-click menu option?

If your answer was "YES"

and

Would you like to be able to:

• include or exclude the variable name row

• export a table starting at a specific cell

• add a table to an existing worksheet

• copy a file to your system's clipboard

6

Would you like to be able to export SAS datasets

to Excel, without needing SAS/Access for PC File

Formats, have the same options as mentioned

on the previous slide, AND be able to automate

the process to be a point-and-click menu option?

Regardless of whether you answered YES or NO

7

and, of course,

in ways that appear to accomplish

the tasks almost automagically

8

what the solution looks like

Right click on a dataset name

in the SAS Explorer window

9

Then select the desired Action(i.e., press hot key (E) or point and left-click)

10

The Workbook will automagically be created

11

Left-click anywhere in the SAS Explorer Window

how to get those capabilities

12

Left-click on Tools, move your mouse to Options→Explorer

how to get those capabilities

13

Left-click on Members

how to get those capabilities

14

Then double left-click on Table

how to get those capabilities

15

left-click on Add and an Add Action screen will appear

how to get those capabilities

16

Type the text you want to add to the menu

&Export to Excel

Action: &Export to ExcelIt will appear on the menu as: Export to Excel

Note: You can make one character a hotkey by

preceding it with an ampersand

how to get those capabilities

17

Left click in the Action Command box

&Export to Excel

how to get those capabilities

18

Action Commands only accept up to 255 characters

SAS Explorer comes with a built-in action called Copy Contents to Clipboard, but it creates an HTML file, contains some possibly undesired headers, shading and borders and runs 138.67 times slower than the methods we've proposed

The 255 character limitation can be circumvented by submitting a macro

When using gsubmit in an Action Command, everything between the two single quotes will be submitted

some key points about the Action Command

% has a special meaning in Action Commands thus, if you need to use a % (e.g., to call a macro), use two %s

When a SAS dataset is selected %8b and %32b can be used to refer to the libname and filename, respectively

19

the macro can produce 7 different actions, dependent upon how it is called. Action #1:

Action Commandgsubmit '%%exportxl(%8b,%32b,P,YES,NO)';

gsubmit '%%exportxl(%8b,%32b,P,YES,NO)';

&Export to Excel

our paper presents a SAS macro: %exportxl

runs proc export* on the dataset, creating an Excel workbook in the directory

* requires SAS/Access for PC File Formats

libnm filenm type usenames range

20

click on OK to exit the Add Action screen

gsubmit '%%exportxl(%8b,%32b,P,YES)';

&Export to Excel

after you have entered the action command

21

click on OK to exit the Table Options screen

then,

22

Once you have completed those stepswhenever you right click on a file in the SAS Explorer

window, and select the action:

23

The Workbook will automagically be created

24

Action Commandgsubmit '%%exportxl(%8b,%32b,S,YES,NO)';

gsubmit '%%exportxl(%8b,%32b,S,YES,NO)';

Export to Excel with Variable &Names

the other six action commands: Action #2

produces an Excel workbook that will include variable names in the first row

Note: Outcomes 2-7 only require base SAS

libnm filenm type usenames range

25

Action Commandgsubmit '%%exportxl(%8b,%32b,S,YES,YES)';

gsubmit '%%exportxl(%8b,%32b,S,YES,YES)';

Export to Excel &Range with Variable Names

produces an Excel workbook that will include variable names and let you indicate the

upper left cell where the table should begin

libnm filenm type usenames range

the other six action commands: Action #3

26

Action Commandgsubmit '%%exportxl(%8b,%32b,S,NO,NO)';

gsubmit '%%exportxl(%8b,%32b,S,NO.NO)';

Export to Excel w/&o Variable Names

produces an Excel workbook that will not include variable names in the first row

libnm filenm type usenames range

the other six action commands: Action #4

27

Action Commandgsubmit '%%exportxl(%8b,%32b,S,NO,YES)';

gsubmit '%%exportxl(%8b,%32b,S,NO.YES)';

Export to Excel Range w/o Variable Names

produces an Excel workbook (excluding variable names) and will let you indicate the upper left cell where the table should begin

libnm filenm type usenames range

the other six action commands: Action #5

28

Action Commandgsubmit '%%exportxl(%8b,%32b,C,YES,NO)';

gsubmit '%%exportxl(%8b,%32b,C,YES,NO)';

E &xport to Clipboard with variable names

copies the dataset (with variable names) to your clipboard so that you can paste it

into another program

libnm filenm type usenames range

the other six action commands: Action #6

29

Action Commandgsubmit '%%exportxl(%8b,%32b,C,NO,NO)';

gsubmit '%%exportxl(%8b,%32b,C,NO,NO)';

&Export to Clipboard w/o Variable Names

copies the dataset (without variable names) to your clipboard so that you can paste it

into another program

libnm filenm type usenames range

the other six action commands: Action #7

30

if you use one of the Actions with range=YES*

enter the upper left cell where the range should begin and then press your <enter> key

*Note: not applicable to Action #1 as proc export doesn't support outputting to a range

the following screen will appear when you select the action

31

and, if you use Actions 2-5

i.e., the program will ask you whether it should, or shouldn't, replace the existing file

if the workbook already exists, ascreen like the following will appear

32

Save the file as exportxl.sas in a directory thatexists in your SASAUTOS* path

* see: http://analytics.ncsu.edu/sesug/2008/SBC-126.pdf

where to get the macro

Copy the SAS program from:http://www.sascommunity.org/mwiki/images/f/f4/1793-2014.sas

33

%macro exportxl(libnm,filenm,type,usenames,range);%let filepath=%sysfunc(pathname(&libnm.));%if &type. eq P %then %do;

proc exportdata=&libnm..&filenm.outfile= "&filepath.\&filenm..xlsx" dbms=xlsxreplace;

run;%end;

how the macro works

libnm filenm type usenames

%8b %32bP for Proc ExportS for vbs script

C for Clipboard

include row withvariable names

YESNO

%let filepath=%sysfunc(pathname(&libnm.));

whether table shouldbe written to a range

YESNO

range

34

%macro exportxl(libnm,filenm,type,usenames);%let filepath=%sysfunc(pathname(&libnm.));%if &type. eq P %then %do;

proc exportdata=&libnm..&filenm.outfile= "&filepath.\&filenm..xlsx" dbms=xlsxreplace;

run;%end;

%if &type. eq P %then %do;proc exportdata=&libnm..&filenm.outfile= "&filepath.\&filenm..xlsx" dbms=xlsxreplace;

run;%end;

how the macro works

35

%else %do;proc fcmp outlib=work.func.util;function c2cb(lib $,mem $, usenm $);rc=filename('clippy',' ','clipbrd');if rc ne 0 then return(1);fid=fopen('clippy','o',0,'v');if fid eq 0 then do;rc = filename( 'clippy' );return(2);

end;dsid=open(catx('.',lib,mem));if dsid eq 0 then do;rc=fclose(fid);rc=filename('clippy');return(3);

end;

how the macro works

36

%else %do;proc fcmp outlib=work.func.util;function c2cb(lib $,mem $, usenm $);rc=filename('clippy',' ','clipbrd');if rc ne 0 then return(1);fid=fopen('clippy','o',0,'v');if fid eq 0 then do;rc = filename( 'clippy' );return(2);

end;dsid=open(catx('.',lib,mem));if dsid eq 0 then do;rc=fclose(fid);rc=filename('clippy');return(3);

end;

how the macro works

Open the clipbrd so that we can

write to it

37

%else %do;proc fcmp outlib=work.func.util;function c2cb(lib $,mem $, usenm $);rc=filename('clippy',' ','clipbrd');if rc ne 0 then return(1);fid=fopen('clippy','o',0,'v');if fid eq 0 then do;rc = filename( 'clippy' );return(2);

end;dsid=open(catx('.',lib,mem));if dsid eq 0 then do;rc=fclose(fid);rc=filename('clippy');return(3);

end;

how the macro works

Open the SAS dataset so that we can read it

38

nvar=attrn(dsid,'nvar');array v[1] /nosymbols;call dynamic_array(v,nvar);do i = 1 to nvar;

v[i]=ifn( vartype(dsid,i)='C',1,2);if usenm eq 'YES' then do;if i gt 1 then rc=fput(fid,'09'x);rc=fput(fid,varname(dsid,i));

end;end;if usenm eq 'YES' then rc=fwrite(fid);do i=1 to attrn(dsid,'nlobs');

rc=fetchobs(dsid,i);do j=1 to nvar;

if j gt 1 then rc=fput(fid,'09'x);if (v[j] eq 1) then rc=fput(fid, getvarc(dsid,j));else do;fmt=varfmt(dsid,j) ;if missing(fmt) then fmt='best12.';rc=fput(fid,putc(putn(getvarn(dsid,j),fmt),'$char12.'));

end;end;rc=fwrite(fid);

end;

how the macro works

Get number of variables and declare array

39

nvar=attrn(dsid,'nvar');array v[1] /nosymbols;call dynamic_array(v,nvar);do i = 1 to nvar;

v[i]=ifn( vartype(dsid,i)='C',1,2);if usenm eq 'YES' then do;if i gt 1 then rc=fput(fid,'09'x);rc=fput(fid,varname(dsid,i));

end;end;if usenm eq 'YES' then rc=fwrite(fid);do i=1 to attrn(dsid,'nlobs');

rc=fetchobs(dsid,i);do j=1 to nvar;

if j gt 1 then rc=fput(fid,'09'x);if (v[j] eq 1) then rc=fput(fid, getvarc(dsid,j));else do;fmt=varfmt(dsid,j) ;if missing(fmt) then fmt='best12.';rc=fput(fid,putc(putn(getvarn(dsid,j),fmt),'$char12.'));

end;end;rc=fwrite(fid);

end;

how the macro works

Assign values to array based

on variable type

Assign variable names

40

nvar=attrn(dsid,'nvar');array v[1] /nosymbols;call dynamic_array(v,nvar);do i = 1 to nvar;

v[i]=ifn( vartype(dsid,i)='C',1,2);if usenm eq 'YES' then do;if i gt 1 then rc=fput(fid,'09'x);rc=fput(fid,varname(dsid,i));

end;end;if usenm eq 'YES' then rc=fwrite(fid);do i=1 to attrn(dsid,'nlobs');

rc=fetchobs(dsid,i);do j=1 to nvar;

if j gt 1 then rc=fput(fid,'09'x);if (v[j] eq 1) then rc=fput(fid, getvarc(dsid,j));else do;fmt=varfmt(dsid,j) ;if missing(fmt) then fmt='best12.';rc=fput(fid,putc(putn(getvarn(dsid,j),fmt),'$char12.'));

end;end;rc=fwrite(fid);

end;

how the macro works

Write variable names

41

nvar=attrn(dsid,'nvar');array v[1] /nosymbols;call dynamic_array(v,nvar);do i = 1 to nvar;

v[i]=ifn( vartype(dsid,i)='C',1,2);if usenm eq 'YES' then do;if i gt 1 then rc=fput(fid,'09'x);rc=fput(fid,varname(dsid,i));

end;end;if usenm eq 'YES' then rc=fwrite(fid);do i=1 to attrn(dsid,'nlobs');

rc=fetchobs(dsid,i);do j=1 to nvar;

if j gt 1 then rc=fput(fid,'09'x);if (v[j] eq 1) then rc=fput(fid, getvarc(dsid,j));else do;fmt=varfmt(dsid,j) ;if missing(fmt) then fmt='best12.';rc=fput(fid,putc(putn(getvarn(dsid,j),fmt),'$char12.'));

end;end;rc=fwrite(fid);

end;

how the macro works

Get data and formats and write tab-delimited records

42

rc=fclose(fid);

rc=close(dsid);

rc=filename('clippy');

return(0);

endsub;

quit;

%local cmplib;

%let cmplib=%sysfunc(getoption(cmplib));

options cmplib=(work.func);

%put %sysfunc(c2cb(&libnm,&filenm,&usenames)) ;

options cmplib=(&cmplib);

how the macro works

Cleanup

43

how the macro works

rc=fclose(fid);

rc=close(dsid);

rc=filename('clippy');

return(0);

endsub;

quit;

%local cmplib;

%let cmplib=%sysfunc(getoption(cmplib));

options cmplib=(work.func);

%put %sysfunc(c2cb(&libnm,&filenm,&usenames)) ;

options cmplib=(&cmplib);

Get optionsRun FunctionReset Options

44

%if &range. eq YES %then %do;data _null_;window range rows=8 columns=80irow=1 icolumn=2 color=black#2 @3 'Enter the upper left cell where range should begin (e.g. D5): 'color=gray range $8. required=yesattr=underline color=yellow;DISPLAY range blank;call symput('range',range);stop;

run;%end;%else %do;

%let range=A1;%end;

how the macro works

Display windowto let users

identify range

45

%if &range. eq YES %then %do;data _null_;window range rows=8 columns=80irow=1 icolumn=2 color=black#2 @3 'Enter the upper left cell where range should begin (e.g. D5): 'color=gray range $8. required=yesattr=underline color=yellow;DISPLAY range blank;call symput('range',range);stop;

run;%end;%else %do;

%let range=A1;%end;

how the macro works

Otherwise,set default

range

46

%if &type. eq S %then %do;data _null_;length script filevar $256;script = catx('\',pathname('WORK'),'PasteIt.vbs');filevar = script;script="'"||'cscript "'||trim(script)||'"'||"'";call symput('script',script);file dummy1 filevar=filevar recfm=v lrecl=512;put 'Dim objExcel';put 'Dim Newbook';put 'Set objExcel = CreateObject("Excel.Application")';put 'Set Newbook = objExcel.Workbooks.Add()';put 'objExcel.Visible = True';Script='Newbook.Sheets("Sheet1").Range("'||"&Range."||'").Activate';put script;put 'Newbook.Sheets("Sheet1").Paste';put 'Newbook.Sheets("Sheet1").Select';put 'Newbook.Sheets("Sheet1").Name = "'@;put "&filenm."@;put '"';

how the macro worksIf type eq S then

create a VBS scriptcalled PasteIt.vbs

47

how the macro works%if &type. eq S %then %do;data _null_;length script filevar $256;script = catx('\',pathname('WORK'),'PasteIt.vbs');filevar = script;script="'"||'cscript "'||trim(script)||'"'||"'";call symput('script',script);file dummy1 filevar=filevar recfm=v lrecl=512;put 'Dim objExcel';put 'Dim Newbook';put 'Set objExcel = CreateObject("Excel.Application")';put 'Set Newbook = objExcel.Workbooks.Add()';put 'objExcel.Visible = True';Script='Newbook.Sheets("Sheet1").Range("'||"&Range."||'").Activate';put script;put 'Newbook.Sheets("Sheet1").Paste';put 'Newbook.Sheets("Sheet1").Select';put 'Newbook.Sheets("Sheet1").Name = "'@;put "&filenm."@;put '"';

Add a worksheet,make it the active sheet

paste the clipboard,and assign sheet name

48

put 'Newbook.SaveAs("'@;put "&filepath.\&filenm..xlsx"@;put '")';put "Newbook.Close";

put 'objExcel = Nothing';put 'Newbook = Nothing';script="'"||'cscript "'||trim(script)||'"'||"'";call symput('script',script);

run;

data _null_;call system(&script.);

run;%end;

%end;%mend exportxl;

how the macro works

Save and closethe workbook

49

put 'Newbook.SaveAs("'@;put "&filepath.\&filenm..xlsx"@;put '")';put "Newbook.Close";

put 'objExcel = Nothing';put 'Newbook = Nothing';script="'"||'cscript "'||trim(script)||'"'||"'";call symput('script',script);

run;

data _null_;call system(&script.);

run;%end;

%end;%mend exportxl;

how the macro works

Cleanup andwrite command

line to macrovariable &script

50

put 'Newbook.SaveAs("'@;put "&filepath.\&filenm..xlsx"@;put '")';put "Newbook.Close";

put 'objExcel = Nothing';put 'Newbook = Nothing';script="'"||'cscript "'||trim(script)||'"'||"'";call symput('script',script);

run;

data _null_;call system(&script.);

run;%end;

%end;%mend exportxl;

how the macro works

Run theVBS script

51

What the ExportXL macro is and where you can download it

How the macro works

How you can set up Action Commands to call the macro to accomplish things that you can't do with proc export

summary of what I just presented:

How you can create Action Commands in the SAS Explorer window

52

Export to Excel

Copy Variable Names to Clipboard

Run Proc Contents

Get descriptive statistics

Show all correlations

Run Proc Means

Print bar charts

Run Proc Freq

and, if you want, you can use the same method to add all of your repeated tasks to the SAS Explorer menu

Your comments and questionsare valued and encouraged

Contact the Authors

Arthur Tabachneck, Ph.D.myQNA, Inc.Thornhill, ONart297@rogers.com

Tom AbernathyPfizer, Inc.New York, NYtom.abernathy@pfizer.com

Matt KastinI-Behavior, Inc.Penn Valley, PAmatthew.kastin@gmail.com