SAS collapse pivot table column in Excel with DDE - excel

I want to manipulate an existing Excel sheet with DDE using SAS:
I have the following code (be careful! I use z for r(ows) and s for c(columns) because of German language settings in Excel):
option noxwait noxsync;
x call "C:\Program Files (x86)\Microsoft Office\Office15\EXCEL.EXE";
%let delay=5;
data _null_;
rc=sleep(&delay);
run;
filename sas2xl dde 'excel|system';
data _null_;
rc=sleep(&delay);
run;
%let mapwkbk=H:\odstest.xlsx;
data _null_;
file sas2xl;
rc=sleep(&delay);
put '[open("' "&mapwkbk" '")]';
run;
filename random dde 'excel|Daten!z2s1:z100s3';
data _null_;
set sashelp.class;
file random;
put name sex age;
run;
data _null_;
file sas2xl;
/*rc=sleep(&delay);*/
put '[workbook.select("Pivot")]';
put '[select("Z2S1")]';
put "[pivot.refresh()]";
put '[workbook.select("Daten")]';
put '[select("z1S2:z1s5")]';
put '[filter]';
put '[select("z1S10")]';
put '[filter]';
put '[column.width(0,"s1",false,1)]';
put '[column.width(0,"s6:s9",false,1)]';
put '[workbook.delete("Dim")]';
/*put "[save()]";*/
/*put "[quit()]";*/
run;
Now I would like to collapse some columns of the pivot table. How to reach this?

Related

Clikable Hyperlink with SAS ODS EXCEL

I got a problem with Hyperlink generated by SAS ODS EXCEl.
I'm using SAS9.4TM3 and EXCEL 2013.
I coded this
data lst_tie;
NUM_TIE = '2900004227803';
output;
NUM_TIE = '2900004233852';
output;
run;
data lst_tie(drop=HL);
set lst_tie;
format HL2 $500.;
HL = "http://tier-kh.cm-cic.fr/tie6_tiers/default.aspx?trt=tiesyn&banque=02297&caisse=38848&tiers="||NUM_TIE;
HL2 = '=LIEN_HYPERTEXTE("'||HL||'";"'||NUM_TIE||'")';
run;
ods excel file = "$GRPFPU/test_tiesyn.xlsx"
options (absolute_column_width="3cm,20cm,20cm");
proc report data=lst_tie
;
column NUM_TIE
HL2;
define num_tie / "Numero" style(column)={ width=100%};
define HL2 / "Tiers" style(column)={tagattr='wraptext:no' width=100%};
quit;
ods excel close;
The URL seems well encoded :
=LIEN_HYPERTEXTE("http://tier-kh.cm-cic.fr/tie6_tiers/default.aspx?trt=tiesyn&banque=02297&caisse=38848&tiers=2900004227803";"2900004227803")
without carriage return (CR).
But, on opening the XLSX file there is a CR characters just after LIEN_HYPERTEXTE (HYPERLINK in English)
XLSX Preview 1
But if I delete the CR so the hyperlink is OK.
XLSX OK
I tried several option as WIDTH_COLUMS, Wrap Option , but no way.
Thanks
ODS EXCEL is trying to make your printout pretty by inserting physical line breaks into long lines. Apparently it doesn't notice that your value is a formula instead of plain text.
Starting with SAS 9.4M4 you can add flow="tables" to the ODS statement. See this SAS Blog post
ods excel file = "$GRPFPU/test_tiesyn.xlsx"
options (absolute_column_width="3cm,20cm,20cm"
flow="tables"
)
;
For older versions of SAS, like yours, try making the column wider so it doesn't try to wrap it. Try adding width=1000% instead of width=100% to the column with the links.
define HL2 / "Tiers" style(column)={tagattr='wraptext:no' width=1000%};
To have a clickable hyperlink I add a format
``
data lst_tie;
NUM_TIE = '2900004227803';
output;
NUM_TIE = '2900004233852';
output;
run;
data lst_tie;
set lst_tie;
format HL2 $500.;
HL = "http://tier-kh.cm-cic.fr/tie6_tiers/default.aspx?trt=tiesyn&banque=02297&caisse=38848&tiers="||NUM_TIE;
run;
data one;
set lst_tie;
retain fmtname '$urltie';
rename NUM_TIE=start;
label = HL;
run;
proc format cntlin=one;
run;
ods excel file = "$GRPFPU/test_tiesyn.xlsx"
options (absolute_column_width="3cm,20cm,20cm" flow="tables");
proc report data=lst_tie
;
column NUM_TIE
;
define num_tie / "Numero" style(column)={TAGATTR='format:0' width=1.5in url=$urltie. color=cx0000FF textdecoration=underline /*tagattr='wraptext:no' width=100%*/
};
quit;
ods excel close;
``

How to open .sas7bdat in SAS and export to excel?

I am quite new to SAS. I have got a file with file extension .sas7bdat which contains daily stocks prices and percentage changes. It has almost 2 million line items. I know that I can simply double click the file and open it with SAS 9.4. But, I am looking for codes which I can type in Editor and open this file. Please help me.
After I open this file, I need to export it to excel. Since it has 2 million data, I can not export everything in a single excel tab. So, What I want to do it randomly pick (say 10,000 or 20,000) data and export only this randomly picked data to excel.
My .sas7bdat file is on desktop.
Please help.
You can use surveyselect and specify the number of records you want in your subset the use proc export.
In my Example below I create a table of 10 rows and only wanted 5 row in the subset. just change the value in my macro variable from 5 to 100000
Code:
data have;
input value;
datalines;
1
2
3
4
5
6
7
8
9
10
;
run;
%let subset=5;
proc surveyselect data=have
method=srs n=&subset. out=want;
run;
Output:
value=1
value=2
value=5
value=6
value=10
Exporting:
proc export data=sashelp.class
outfile='c:\myfiles\want.csv'
dbms=csv
replace;
run;
You can also filter on the data you are exporting, dummy example below:
proc export data=want (where=(value > 100 or location='X'))
outfile='c:\myfiles\want.csv'
dbms=csv
replace;
run;
You can use ODS. This will be simpler, but generate a file which will give warning in opening first time
libname rd_data "<Your Path to dataset>"
data temp;
set rd_data.<dataset name>;
rnd = ranuni(123456);
run;
proc sort data = temp out = temp(drop=rnd);
by rnd;
run;
**** Remember this is .xls file, not .xlsx
ods html file = <xls file path - full path>;
proc print data = temp(obs=1000);
run;
ods html close;
Alternatively, you can use DDE (Dynamic Data Exchange)
First, create a library to point to the location on the file system where the data set resides. This is a pointer (in C terms) to the directory.
libname myData "<path to folder>";
From there you can use a random number and a data step to get N random values. Alternatively, PROC SURVEYSELECT can be used, but you might not have it licensed.
data temp;
set myData.<Data Set Name>;
__rnd = ranuni(1);
run;
proc sort data=temp ;
by __rnd;
run;
data toOutput;
set temp(obs=10000 drop=__rnd);
run;
The last Data Step reads in just the first 10,000 records which you randomized above.
Then you can use PROC EXPORT to export the values.
proc export data=toOutput outfile="c:\temp\output.xlsx" dbms=xlsx replace;
sheet="MyData";
run;
The great thing here is that you can create other sheets in the file with additional exports.
proc export data=toOutput outfile="c:\temp\output.xlsx" dbms=xlsx replace;
sheet="MyData2";
run;
This would allow you to create multiple samples or even export all the data across multiple sheets.

Change from DDE to proc export because office 2016 does not support it

office excel 2016 for some reason does not support DDE command and therefore the following programs is crashing. Do you know how can I make it work? I have tried with proc export, I will add the code I tried as comment. Or if you have any other idea of how it can work, please share. Thank you in advance!
ods listing close;
ODS HTML path="path'
(TITLE="CD");
title;footnote;
%macro prnt;
%if &nobs ne 0 %then %do;
title1 "CDTC";
footnote "PROGRAM: (, UPDATED: &tist";
proc print data = dag.dc label noobs; run;
%end;
ods HTML close;
ods listing;
%mend;
%prnt;
/*
proc export data = inter
outfile =
"\\sraw.xlsx"
dbms = xlsx
replace;
run;
*/
options noxwait noxsync;
%SYSEXEC "C:\Program Files (x86)\Microsoft Office\Office14\excel.exe";
%sysexec "C:\Program Files (x86)\Microsoft Office\root\Office16\excel.exe";
data _null_;
x=sleep(10);
run;
filename Commands dde 'excel|system';
/*Open file and unprotect*/
DATA _null_;
FILE commands;
PUT '[ERROR(FALSE)]';
*Put '[open("\\PATH.xlsx")]';
put '[open("PATH")]';
/*put '[workbook.activate("sheet1")]';*/
Put '[PROTECT.DOCUMENT(FALSE, FALSE, , FALSE, FALSE)]';
RUN;
%LET ARK=sheet1;
%LET RU=4;
filename C1 dde "EXCEL|&ARK!R&RU.C1:R1000C1" NOTAB;
filename C2 dde "EXCEL|&ARK!R&RU.C2:R1000C2" NOTAB;
filename C3 dde "EXCEL|&ARK!R&RU.C3:R1000C3" NOTAB;
filename C4 dde "EXCEL|&ARK!R&RU.C4:R1000C4" NOTAB;
filename C5 dde "EXCEL|&ARK!R&RU.C5:R1000C5" NOTAB;
filename C6 dde "EXCEL|&ARK!R&RU.C6:R1000C6" NOTAB;
filename C7 dde "EXCEL|&ARK!R&RU.C7:R1000C7" NOTAB;
filename C8 dde "EXCEL|&ARK!R&RU.C8:R1000C8" NOTAB;
filename C9 dde "EXCEL|&ARK!R&RU.C9:R1000C9" NOTAB;
filename C10 dde "EXCEL|&ARK!R&RU.C10:R1000C10" NOTAB;
filename C11 dde "EXCEL|&ARK!R&RU.C11:R1000C11" NOTAB;
filename C12 dde "EXCEL|&ARK!R&RU.C12:R1000C12" NOTAB;
filename C13 dde "EXCEL|&ARK!R&RU.C13:R1000C13" NOTAB;
filename C14 dde "EXCEL|&ARK!R&RU.C14:R1000C14" NOTAB;
filename C15 dde "EXCEL|&ARK!R&RU.C15:R1000C15" NOTAB;
filename C16 dde "EXCEL|&ARK!R&RU.C16:R1000C16" NOTAB;
filename C17 dde "EXCEL|&ARK!R&RU.C17:R1000C17" NOTAB;
filename C18 dde "EXCEL|&ARK!R&RU.C18:R1000C18" NOTAB;
filename C19 dde "EXCEL|&ARK!R&RU.C19:R1000C19" NOTAB;
DATA _NULL_;
SET INTER;
FILE C1;
PUT COLLATAGREEMENTID;
FILE C2;
PUT CCYID;
FILE C3;
PUT TYPE;
FILE C4;
PUT AGREEMENTNO;
FILE C5;
PUT WSSCUSTID;
FILE C6;
put receffective $12.;
*PUT RECEFFECTIVE commax32.2;
FILE C7;
PUT RECINDEX;
FILE C8;
PUT RECEFFRATE;
*PUT RECEFFRATE commax32.5;
FILE C9;
PUT RECACCRUAL;
*PUT RECACCRUAL commax32.2;
FILE C10;
PUT DELIVEFFECTIVE;
*PUT DELIVEFFECTIVE commax32.2;
FILE C11;
PUT DELIVINDEX;
FILE C12;
PUT DELIVEFFRATE;
*PUT DELIVEFFRATE commax32.5;
FILE C13;
PUT DELIVACCRUAL;
*PUT DELIVACCRUAL commax32.2;
FILE C14;
PUT TOTEFFECTIVE;
*PUT TOTEFFECTIVE commax32.2;
FILE C15;
PUT TOTACCRUAL;
*PUT TOTACCRUAL commax32.2;
FILE C16;
PUT PRODDATE;
FILE C17;
PUT ENDDATE ;
FILE C18;
PUT FIXED_BAL_EUR;
*PUT FIXED_BAL_EUR commax32.2;
FILE C19;
PUT ON_BAL_EUR;
*PUT ON_BAL_EUR commax32.2;
RUN;
/*TVI 23-09-2016
data _null_;
a='[SAVE.AS('||'"'||'\\PATH';
s="&sta2";
b='.xlsX'||'"'||')]';
c=a||s||b;
call symput('b',"'"||c||"'");
run;
*/
data _null_;
a='[SAVE.AS('||'"'||"PATH";
s="&sta2";
b='.xlsX'||'"'||')]';
c=a||s||b;
call symput('b',"'"||c||"'");
run;
%put &b;
%let savefile= &b;
dATA _NULL_;
FILE COMMANDS lrecl=1024;
PUT '[ERROR(FALSE)]';
PUT &SAVEFILE;
run;
/*lukker excel ned igen*/
DATA _NULL_;
FILE COMMANDS;
PUT '[QUIT()]';
RUN;
QUIT;
I had EXACTLY this same problem.
The problem is the registry settings for excel 2016 DDE.
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Office\16.0\Excel\Options]
"DontUpdateLinks"=dword:00000000
"DDEAllowed"=dword:00000000
"DDECleaned"=dword:00000000
save this in a file.reg and merge with registry, close and restart exccel
Proc EXPORT can replace an entire sheet in an existing workbook. Your template workbook appears to want data starting in row 4. Not knowing what are in the first three rows I would say you probably need to update the template to work with a data-only sheet.
Example, create a multi-sheet workbook, then replace one of the worksheets.
Create template (once) for demo purposes;
filename TEMPLATE 'c:\temp\demo-template.xlsx' recfm=n;
data _null_;
rc = FDELETE ('TEMPLATE');
run;
proc export data=sashelp.class(obs=0) dbms=excel replace file=TEMPLATE;
sheet = 'DATA_FOR_TEMPLATE';
run;
proc export data=sashelp.cars(obs=10) dbms=excel replace file=TEMPLATE;
sheet = 'CARS_DATA';
run;
Now update one sheet in the template, pre-copied to your save/as
filename REALIZE1 'c:\temp\demo-15feb2018.xlsx' recfm=n;
* copy template to desired 'save/as';
data _null_;
rc = FCOPY ('TEMPLATE', 'REALIZE1');
run;
* replace all of a sheet;
proc export data=sashelp.class dbms=excel replace file=REALIZE1;
sheet = 'DATA_FOR_TEMPLATE';
run;
filename TEMPLATE;
filename REALIZE;
For the case of a template with protections that need to be turned off and on, you can do that in a powershell script or excel vb.

Export one SAS table into multiple Excel worksheets based on field value

I'm trying to export one SAS table into multiple Excel worksheets based on the value of a field (parent_account). I want each worksheet to be named the same as the parent_account. I'm using the following code that I found at http://www.tek-tips.com/viewthread.cfm?qid=1335588, but I'm getting these error messages:
A character operand was found in the %EVAL function or %IF condition where a numeric operand is required.
Argument 2 to macro function %SCAN is not a number.
%macro export_to_excel();
%local varlist idx var;
proc sql noprint;
select distinct parent_account into: varlist separated by '||'
from todays_activity;
quit;
%let idx = 1;
%do %while ( %scan(&varlist, &idx, %str(||)) ne %str() );
%let var=%scan(&varlist, &idx, %str(||));
proc export data=sashelp.class (where=(parent_account="&var"))
outfile='My file location\Report.xls'
dbms=excel;
sheet="&var";
quit;
%let idx = %eval(&idx + 1);
%end;
%mend export_to_excel;
%export_to_excel;
You could try using ODS EXCEL. Here is an example use SASHELP.CLASS dataset.
First make sure the data is sorted by your grouping variables.
proc sort data=sashelp.class out=class ;
by sex ;
run;
Set up ODS to point to your target file. Tell it to make a new sheet for each BY group.
ods excel file="&path/class.xlsx" ;
ods excel options
(sheet_interval="bygroup"
suppress_bylines="yes"
sheet_name='GENDER'
);
You also might want to turn off other output destinations.
Then print the file using PAGEBY option. And close the ODS EXCEL destination
proc print data=class noobs;
by sex ;
pageby sex ;
var _all_;
run;
ods excel close;
To test it you could try reading it back in as data. But watch out that it will create member names with embedded spaces.
options validmemname=extend;
libname xx xlsx "&path/class.xlsx";
proc copy inlib=xx outlib=work; run;
libname xx clear ;
From SAS log
NOTE: The data set WORK.GENDER has 9 observations and 5 variables.
NOTE: The data set WORK.'GENDER 2'n has 10 observations and 5 variables.
This might be helpful
%macro export_to_excel;
proc sql noprint;
select distinct parent_account into: varlist separated by '#' from todays_activity;
select count(distinct parent_account) into:n from todays_activity;
quit;
%do i=1 %to &n;
%let var= %scan(&varlist,&i,"#");
proc export data=sashelp.class (where=(parent_account="&var"))
outfile='Your file location\Report.xls'
dbms=excel;
sheet="&var";
run;
%end;
%mend export_to_excel;

How to make cell range dynamic in DDE in SAS

I am trying to format a weekly report using DDE in sas which opens a excel file kept on my desktop location. I want to format the font some of these cells. I have a total column which needs to be formatted every time the new data comes in. But every time this data would come out the range of the "Total" cell would be different. Please refer to the code i am writing
options noxsync noxwait;
filename sas2xl dde 'excel|system';
data _null_;
length fid rc start stop time 8;
fid=fopen('sas2xl','s');
if (fid le 0) then do;
rc=system('start excel');
start=datetime();
stop=start+10;
do while (fid le 0);
fid=fopen('sas2xl','s');
time=datetime();
if (time ge stop) then fid=1;
end;
end;
rc=fclose(fid);
run;
data _null_;
file sas2xl;
put '[open(myfilepath\file.xlsx")]';
run;
**I had created a macro using call symput and i am using it here for dynamically changing the row number**
%macro xyz;
data _null_;
file sas2xl;
%do i= 1 %to 3;
put '[error(false)]';
put '[workbook.activate("Sheet1")]';
put '[select("r&&rownum&i..c1")]';
put '[format.font("Arial",true,false,false,false,1,false,false)]';
put '[column.width(0,"c1:c6",false,3)]';
%end;
run;
ERROR
The code is not working and give me a error like this
DDE session not ready. FATAL:
Unrecoverable I/O error detected in the execution of the DATA step program. Aborted during the EXECUTION phase.
Can you please tell me how can i go ahead in this

Resources