Exporting data from SAS to Excel with a custom file name - sas

I need to export a data set from SAS to Excel 2013 as a .csv file. However, I need the file name to be dynamic. In this instance, I need it to appear as:
in_C000000_013117_65201.csv
where the string, "in_C000000_" will remain constant, the string "013117_" will be the current day's date, and the string "65201" will be the row count of the data set itself.
Any help that you can provide would be much appreciated!
Thanks!

Here's a modified macro I wrote in the past that does almost exactly what you're asking for. If you want to replace sysdate with a date in your desired format, that's easy to do as well:
%let path = [[desired destination]];
%macro exporter(dataset);
proc sql noprint;
select count(*) into: obs
from &dataset.;
quit;
data temp;
format date mmddyy6.;
date = today();
run;
proc sql noprint;
select date format mmddyy6. into: date_formatted
from temp;
quit;
proc export data = &dataset.
file = "&path.in_C000000_&date_formatted._%sysfunc(compress(&obs.)).csv"
dbms = csv replace;
run;
%mend exporter;
%exporter(your_dataset_here);
Produces datasets in the format: in_C000000_020117_50000.csv

Related

Missing the last few column names when exporting to CSV file

I am trying to export a dataset in my Library/Work. It shows normal in SAS. However when I export the data as CSV or txt file (either from right click -> export, or use SAS code), the last few column names were missing (showing empty in CSV), while the values were kept. The column names missing are all in the format of "Log_xxx" but some the same-format columns were exported correctly. There're around 4000+ columns in my dataset.
The code I've tried is like:
proc export data=logdata
outfile="path.csv"
dbms=csv
replace;
run;
I've exported many datasets before, but it's the first time I have this kind of problem. I've tried to restart SAS and it's still not working.
I simply wanted to export the whole dataset completely with all column names and values.
Do you have any ideas?
I don't think it is PROC EXPORT that is the issue. You have to tell SAS that you want to write lines that are longer then 32,767 bytes (the default setting for the LRECL option).
This code works:
data test;
array longname [3500] ;
run;
filename csv temp lrecl=1000000 ;
proc export data=test dbms=csv file=csv ;
run;
So change your code to set the LRECL long enough for all of the variable names.
filename csv "path.csv" lrecl=1000000 ;
proc export data=logdata
outfile=csv
dbms=csv
replace
;
run;
Based on this post, your header is likely exceeding 32k characters, which causes the issues.
Solution is to manually create the file without proc export, or proc export to XLSX doesn't appear to have the issue.
*Create demo data;
data class;
set sashelp.class;
label age='Age, Years' weight = 'Weight(lbs)' height='Height, inches';
run;
proc sql noprint;
create table temp as
select name as _name_, label as _label_
from dictionary.columns
where libname="WORK" and upcase(memname)="CLASS";
select nliteral(name) into :varList separated by ' '
from dictionary.columns
where libname="WORK" and upcase(memname)="CLASS";
quit;
data _null_;
file "&sasforum.\datasets\TwoLinesHeader.csv" dsd lrecl = 40000;
set class;
if _n_ = 1 then do;
do until(eof);
set temp end=eof;
put _name_ #;
end;
put;
end;
put (&varList) (:);
run;

Saving the query results to csv

I'm wondering if it's possible to save the query results to csv? Without creating views.
I have a large table but need only 2 columns from there to process with python then. Maybe someone can help with it?
Here are three ways
ODS
SQL query can be output to an ODS CSV destination. This approach encompasses the widest possibilities of querying.
ods csv file='c:\temp\query-results.csv';
proc sql;
select name, age
from sashelp.class
where name like 'J%'
;
quit;
ods csv close;
EXPORT Procedure
Where clause can be applied using kept columns of 'a large table' (data=)
proc export
data = sashelp.class(
keep=name age
where = (
name like 'J%'
)
)
replace
file = 'c:\temp\class-subset.csv'
dbms = csv
;
run;
DATA _null_
Where statement can be applied using any columns of 'a large table' (SET). The PUT statement manages which columns are output.
data _null_;
set sashelp.class;
where name like 'J%';
file 'c:\temp\subset-per-datastep.csv' dlm=',' dsd;
if _n_ = 1 then put 'name,age';
put name age;
run;
I think you can use ods to create file with results, for example:
ods csv file="C:\test.csv" options(delimiter=';');
proc sql;
select * from sashelp.class;
quit;
ods csv close;

SAS - Change date format returned from database

I'm pulling data from many Teradata tables that have dates stored in MM/DD/YYYY format (ex: 8/21/2003, 10/7/2013). SAS returns them as DDMMMYYYY, or DATE9 format (ex: 21AUG2003, 07OCT2013). Is there a way to force SAS to return date variables as MM/DD/YYYY, or MMDDYY10 format? I know I can manually specify this for specific columns, but I have a macro set up to execute the same query for 65 different tables:
%macro query(x);
proc sql;
connect using dbase;
create table &x. as select * from connection to dbase
(select *
from table.&x.);
disconnect from dbase;
quit;
%mend(query);
%query(bankaccount);
%query(budgetcat);
%query(timeattendance);
Some of these tables will have date variables and some won't. So I'd like the value to be returned as MMDDYY10 format by default. Thanks for your help!
Per the comments to my question, I was able to figure this out using the FMTINFO function. I pretty much used this same code:
proc contents data=mylib._all_ noprint out=contents;
run;
data _null_;
set contents;
where fmtinfo(format,'cat')='date';
by libname memname ;
if first.libname then call execute(catx(' ','proc datasets nolist lib=',libname,';')) ;
if first.memname then call execute(catx(' ','modify',memname,';format',name)) ;
else call execute(' '||trim(name)) ;
if last.memname then call execute(' DDMMYYS10.; run;') ;
if last.libname then call execute('quit;') ;
run;
Found here:
https://communities.sas.com/t5/SAS-Procedures/Change-DATE-formats-to-DDMMYYS10-for-ALL-unknown-number-date/td-p/366637

Adding date in variable name in SAS

I have a column with name total transaction. I want to add a date 4 days back from now in its name .
For example if today is 20161220 so I want my variable to be renamed as total_transaction_20161216.
Please suggest me a way out of my problem.
Just create a macro variable that stores the required date format and then use that in a rename statement within proc datasets.
%let datevar = %sysfunc(intnx(day,%sysfunc(today()),-4),yymmddn8.);
%put &=datevar.;
data have;
total_transaction=1;
run;
proc datasets lib=work nolist nodetails;
modify have;
rename total_transaction = total_transaction_&datevar.;
quit;

SAS: Exporting Data Subsets to Separate Workbook Tabs in Excel

Question: How can I export subsets of a data set to individual tabs of an Excel workbook (preferably .xlsx) without running PROC EXPORT several times?
My Solution
The data set contains 15 indicators. Unfortunately, the indicators do not have names which can be indexed. This means I cannot put the export procedure into a macro which loops over a counter 15 times and appends the name with the index. The indicators are (not really) things like "car", "truck", "bicycle", "dinosaur", etc.
The solution I came up with was like this:
proc export data = data_set
(where = (indicator = "car"))
outfile = "c:\workbook.xlsx"
dbms = xlsx replace;
sheet = car;
run;
...
proc export data = data_set
(where = (indicator = "dinosaur"))
outfile = "c:\workbook.xlsx"
dbms = xlsx replace;
sheet = dinosaur;
run;
However, this is obviously inefficient and begs for some sort of automation.
You can use the libname facility, which is what proc export uses in the background usually.
libname myexcel xlsx "c:\outwhatever\myfile.xlsx"; *can use XLSX if 9.4+ or EXCEL if earlier;
That gives you a regular libname just as if it were a SAS libname, and you can write to it like so:
data myexcel.sheetname;
set whatever;
run;
Or use PROC COPY or similar.
There are other options (using OLEDB or similar, for example), but libname is simplest. See the documentation for more details.
If you have SAS 9.4 ODS Excel is quite simple and nice, set the sheet_interval option to bygroup and add a prefix for the sheet name.
proc sort data=sashelp.class out=class;
by age;
run;
ods excel file='/folders/myfolders/sample.xlsx' options (sheet_interval='bygroup' sheet_label='Age');
proc print data=class noobs label;
by age;
run;
ods excel close;