How can I include a timestamp in a .xpt filename? - sas

I have a SAS script that outputs a SAS .xpt file. I currently use the PROC COPY method of generating this because the required name includes dashes and is longer than eight characters (which I understand is the name limit when using xport).
My code is roughly as follows:
LIBNAME TempSrc "C:\Temp";
LIBNAME xportout xport 'C:\Temp\1234-AB-FileOut_Name_.xpt';
PROC IMPORT datafile="C:\Temp\FileIn.csv"
out=mydata
dbms=dlm replace;
DELIMITER= ",";
getnames=yes;
options ExtendObsCounter=no;
RUN;
DATA TempSrc.SasFile;
set work.mydata
RUN;
PROC COPY in=TempSrc out=xportout memtype=data;
select stdy7673;
RUN;
I have recently been required to include a timestamp in the output file name.
I have these macros to generate the date and time as required:
%let today=%sysfunc(date(), date9.);
%let now=%sysfunc(time(), time5.);
%let now=%sysfunc(compress(&now, :));
I have not been able to incorporate into the LIBNAME with any success, though.
Neither of the following has worked:
LIBNAME xportout xport 'C:\Temp\1234-AB-File_Name_&today.&now..xpt';
LIBNAME xportout xport 'C:\Temp\1234-AB-File_Name_' || &today. || &now. '.xpt';
How can I include the datetime in the .xpt filename?

Macro variables won't resolve in 'single quotes'. Use "double quotes" as follows:
LIBNAME xportout xport "C:\Temp\1234-AB-File_Name_&today.&now..xpt";

Related

SAS List of variables containing special characters

I am a novice for SAS programming and I am trying to create a list of old_variable names so I can work with them (subset, rename, spaces, etc.), however the variable names have funky characters (#, parenthesis, single quotes, numbers, you name it). Each variable is delimited-separated by ';' and the source file is in csv format. I need to do it for 44 different files and each file has about 199 variables.
So far, I have tried a macro where I create a list of the variables, however, the code fails when I try to use the macro &vars because of the special characters. I have checked SAS paper 005-2013, however I believe I am not really sure how to use the functions in my code.
Any insights or directions would be appreciated. Here is the code I tried so far:
1) Importing:
proc import datafile='file_oldname.csv'
dbms=csv
out= oldName
replace;
delimiter=',';
getnames=yes;
run;
2) Making my list of oldNames;
* A macro variable contanining the oldvariables names;
* Using Proc Contents and Proc SQL;
proc contents data=oldName out=listOldName;
run;
options VALIDMEMNAME=EXTEND;
proc sql noprint;
select distinct(name) into:vars separated by " " from listOldName;
quit;
%put &vars;
&vars contains the list of variables, however if I try to use it, it fails because of the special characters.
How can I wrap the &vars properly so that the variable names with special characters can be used? I want to further renamed them by new names.
Thanks a lot!
As your variable names contain special characters, they need to be referenced in "name literal!"n format.
Try:
options VALIDVARNAME=ANY;
proc sql noprint;
select distinct nliteral(name)
into:vars separated by ' '
from listOldName;
%put &=var;
More info on name literals in documentation.
Edit - as kindly pointed out by #Tom, the nliteral function handily covers the conversion you require! Documentation for that is here.
When Proc IMPORT runs it creates data sets with variable names that meet the VALIDVARNAME setting at import time. Thus, one alternative, would be to set the option prior to IMPORT to ensure 'clean' variable names, and reset it afterwards.
%let setting = %sysfunc(getoption(VALIDVARNAME));
options validvarname=v7;
Proc IMPORT ... ;
...;
run;
options validvarname = &SETTING;
Example
filename have temp;
data _null_;
file have;
put 'Name,"Age","Date of Birth",School:First,Surprise!,-Feedback';
put 'Abel,0,Yesterday,Eastern Acacdemy,Balloons!,None';
run;
options validvarname=any;
proc import file=have replace out=have_any dbms=csv;
getnames=yes;
run;
options validvarname=v7;
proc import file=have replace out=have_v7 dbms=csv;
getnames=yes;
run;
options validvarname=any;

Define Library in SAS where some of the Folder name will be change each time(When this SAS macro run from different users)

Topic: SAS Library
Difficulty: path(File name and Location) is changing after each run but only some of the details are changing but not the full path (as given in below example). we have also highlighted those field in Bold
I want to write only one code where I can cover all kind of change which happening in file name and location, is it possible?
%let path='C:\Data\variationstring\empcat**A**\person**34**_**1212**\persondata_empcatA_**34**';
libname test "&path";
proc import datafile="&path\Accounts_**34**.xls"
out=mydata
sheet="thefile";
getnames=no;
run;
When another user run that program then above path will be changed:
%let path='C:\Data\variationstring\empcat**A**\person**49**_**1684**\persondata_empcatA_**49**';
libname test "&path";
proc import datafile="&path\Accouns_**49**.xls"
out=mydata
sheet="thefile";
getnames=no;
run;
Can anyone help me for this, please?
Thanks
Try to put it in a macro like this:
%macro import (macro_var1,macro_var2,macro_var3);
%let path="C:\Data\variationstring\empcat**A**\person**&macro_var1.**_**&macro_var2.**\persondata_empcatA_**&macro_var3.**";
libname test "&path";
proc import datafile="&path\Accouns_**49**.xls"
out=mydata
sheet="thefile";
getnames=no;
run;
%mend;
%import (34, 1212, 34);
%imoprt (49, 1684, 49);
etc.
when defining path, don't forget to put it in double quotes (") insted of single (')
In addition to Grigory's excellent suggestion, it looks to me like you're doing something that would be well served utilizing a data-driven programming approach.
If you have, say, an excel spreadsheet with all of your personnel records - let's say the first number is store and the second is employeeID - and you want to run one report per employeeID, then you write the macro like Grigory suggested; but you call the report from the first dataset.
So here:
proc import file="C:\Data\employeeID.xlsx"
out=employees dbms=xlsx
replace;
run;
%macro get_employee(store=, employeeID=, empCat=);
%let path="C:\Data\variationstring\empcat&empcat.\person&store._&employeeID.\persondata_empcat&empcat._&store.";
libname test "&path";
proc import datafile="&path\Accouns_&store..xls"
out=mydata
sheet="thefile";
getnames=no;
run;
%mend get_employee;
proc sql; *this generates macro calls, look at output to see what the macro variable contains;
select cats('%get_employee(employeeid=',employeeID,',store=',store,',empcat=',empcat,')')
into :get_emp_list separated by ' '
from employees;
quit;
&get_emp_list.; *This actually runs all those macro calls;
You can read my paper, Writing Code With Your Data for more details, or find other similar papers online.

Exporting data from SAS to Excel with a custom file name

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

SAS libref not recognized in macro loop

I've run into an odd SAS quirk that I can't figure out - hopefully you can help.
I have a simple macro loop that imports CSV files and for some reason if I use a libref statement in the "out=" part of the import procedure, SAS doesn't recognize the libref as a valid name. But if I use the same libref in a data step, it works just fine.
The specific error it gives is: "ERROR: "TESTDB." is not a valid name."
I'd like to figure this out because I work with pretty big files and want to avoid reading through them more times than is necessary.
Here's the code that works, with some comments in it. I got around the issue by reading in the files, then writing them to permanent SAS datasets in a second step, but ideally I'd like to import the files directly into the "TESTDB" library. Any idea how to get SAS to recognize a libref in the "out=" statement of the import procedure?
libname testdb "C:\SAS test";
%let filepath = C:\SAS test\;
%macro loop(values);
%let count=%sysfunc(countw(&values));
%do i = 1 %to &count;
%let value = %qscan(&values,&i,%str(,));
proc import datafile = "&filepath.&value..csv"
out = &value dbms=csv replace; getnames=yes;
/*"out=testdb.&value" in the line above does not work*/
run;
data testdb.&value; set &value; run;
/*here the libref testdb works fine*/
%end;
%mend;
%loop(%str(test_a,test_b,test_c));
Thanks in advance for your help!
john
Perhaps try:
out=testdb.%unquote(&value)
Sometimes the macro language does not unquote values automatically. With result that the extra quoting characters introduced by a quoting function (%qscan %str %bquote %superq etc) cause problems.
Strange error. I am not able to pin it. My guess is that it has something to do with how the value macro variables are being created. When I moved the value variable creation to a data step and used Call Symputx, it works.
%macro loop(files);
/* Create macro variables for files.*/
data _null_;
count = countw("&files.",",");
call symputx("count",count,"L");
do i = 1 to count;
call symputx(cats("file",i),scan("&files.",i,","),"L");
end;
run;
/* Read and save each CSV as a sas table. */
%do i=1 %to &count.;
proc import datafile = "&filepath.&&file&i...csv"
out = testdb.&&file&i. dbms=csv replace; getnames=yes;
run;
%end;
%mend;
%loop(%str(test_a,test_b));

Inserting a table name into a string with SAS

I'm writing a macro in sas, that exports a file. I want the name of the file, to
be the same as the name of the table in sas. So if i run:
%to_excel(my_table);
I want the file to be saved to "Q:/my_table.xlsx". Heres what I have so far:
%macro to_excel(tb);
proc export data=&tb
outfile=?????????????????
dbms = xlsx
replace;
run;
%mend;
You are almost there. Try this.
%macro to_excel(tb);
proc export data=&tb
outfile="Q:/&tb..xlsx"
dbms = xlsx
replace;
run;
%mend;
%to_excel(my_table);