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, [email protected]
Tom AbernathyPfizer, Inc.New York, [email protected]
Matt KastinI-Behavior, Inc.Penn Valley, [email protected]
Top Related