Reputation: 1001
I am automating the exporting of a data set from SAS to Excel using ODS ExcelXP
:
PURCHASE_ annual_ Minimum_
Obs APR fee Cash_Advance
1 23.45% NONE $10
2 23.45% NONE $10
3 23.45% NONE $10
4 18.45% NONE $10
5 18.45% NONE $10
6 18.45% NONE $10
7 23.45% NONE $10
8 23.45% NONE $10
9 23.45% NONE $10
10 23.45% $0
11 23.45% $0
12 23.45% $0
In SAS, the columns are formatted as text and I want all of the columns to be imported as text into Excel. I've used the following code to create the file using PROC REPORT
:
ods tagsets.ExcelXP path="H:/path" file="file.xls" style=myStyle
options(frozen_headers='yes' WrapText='no'
embedded_titles='yes' suppress_bylines='yes'
sheet_interval='none' sheet_label=' '
sheet_name='Solicited'
width_points='1' width_fudge='1'
absolute_column_width='100' autofit_height='yes'
zoom='100');
title1;
proc report data=testing2 nowd;
column purchase_APR annual_fee minimum_cash_advance;
define purchase_APR / display style(column)={tagattr='format:@'} 'PURCHASE_APR';
define annual_fee / display style(column)={tagattr='format:@'} 'ANNUAL_FEE';
define minimum_cash_advance / display style(column)={tagattr='format:@'} 'MINIMUM_CASH_ADVANCE';
run;
ods tagsets.ExcelXP close;
However, when opening up the Excel file, the Text fields have been somehow changed from 23.45%
, $0
, and $10
(text) to 0.2345
, 0
, and 10
(text) respectively.
How can I get the output in Excel to be just like the data set in SAS?
I have tried using the specific formats to get them to look the same (i.e.tagattr='format:0.00%'
, etc.) but the output in Excel is numeric and not text format.
Upvotes: 1
Views: 10770
Reputation: 63424
The proper way would be to modify how the template processes numbers. You can do that pretty easily in this case. You could even just comment out a line and one block of code, but here's the really proper answer.
Open the template in a text editor. We're going to add a couple of parameters, and implement them.
First, add the options to the $valid_options array. There are a bunch of lines like these, add these two more (Around line 635 or so):
set $valid_options["TEXTPERCENT"] "This value forces percentages to be displayed as text";
set $valid_options["TEXTCURRENCY"] "This value forces currency amounts to be displayed as text";
That text can be whatever you want, this is one interpretation. Now, around line 700 there are some lines setting the defaults, add these two:
set $option_defaults["TEXTCURRENCY"] 'no';
set $option_defaults["TEXTPERCENT"] 'no';
Now down much later (around row 1670) you have the section that defines $punctuation. We change how that works in order to remove "%" and "$" from the list if you set those options:
set $punctuation $thousands_separator " ";
set $punctuation $punctuation "%" /if ^$textpct;
set $punctuation $punctuation $currency_sym /if ^$textcurr;
(Basically, set $variable /if ; we set up punctuation to start with $thousands_separator and then add in the other bits if they are "no" only.)
Now around line 2100 in the "Yes/no on/off options... " section we evaluate the option's value. (The prior uses these values, but that's okay; it's actually called later.)
set $option_key 'TEXTPERCENT';
trigger do_yes_no;
eval $textpct $answer;
set $option_key 'TEXTCURRENCY';
trigger do_yes_no;
eval $textcurr $answer;
Finally, we implement things. Down around line 7400 is event value_type;
which is where the % $ get removed and the numbers get adjusted to be 'real numbers' even if they shouldn't be. This is annoying. So we tell it not to.
do /if ^$textpct;
do /if $convert_percentages;
eval $tmp inputn($value, $test_format)/100;
else;
eval $tmp inputn($value, $test_format);
done;
/*putlog "Percent value:" $tmp;*/
set $value $tmp;
done;
We wrap the percent conversion code with do /if ^$textpct;
and done
, which tells it to skip doing the inputn (which will kill our percents). If we were cheating and not doing this the proper way, we could comment out this line:
set $value compress($value, $punctuation);
But since we fixed the $punctuation variable to contain (or not contain!) the right stuff already, this isn't an issue.
Now this will work! We just modify the tagset call:
*First include your tagset, which I put in c:\temp\ but you can put wherever and call whatever you like;
%include "c:\temp\excel_tpl_nocompress.txt";
ods tagsets.ExcelXP path="c:\temp\" file="testfile.xml"
options(frozen_headers='yes' WrapText='no'
embedded_titles='yes' suppress_bylines='yes'
sheet_interval='none' sheet_label=' '
sheet_name='Solicited' convert_percentages="no"
width_points='1' width_fudge='1'
absolute_column_width='100' autofit_height='yes'
textcurrency='yes' textpercent='yes'
zoom='100');
title1;
*Then add in the textpercent and textcurrency lines, and it should work as is.;
And now you're off to the races.
- <Row ss:AutoFitHeight="1">
- <Cell ss:StyleID="data__l1" ss:Index="1"> <Data ss:Type="String">23.45%</Data> </Cell>
- <Cell ss:StyleID="data__c1" ss:Index="2"> <Data ss:Type="String" /> </Cell>
- <Cell ss:StyleID="data__l1" ss:Index="3"> <Data ss:Type="String">$0</Data> </Cell>
</Row>
Upvotes: 2
Reputation: 1001
I found the answer I needed. I found the ExcelXP Options on the following page: ExcelXP Options I know it is a 'hack', but I changed the default options in the tagsets.ExcelXP
to be currency_symbol = "|"
and decimal_separator = "|"
... fooling SAS into thinking that it should look for the pipe for currencies instead of a dollar sign and the pipe instead of a period for percentages. That way when it came across $0
or 23.45%
it treated these as pure text.
Upvotes: 1