SAS Macro not detecting a file - macros

CMS released a SAS macro that checks for the existence of a file:
** check existance of dataset**;
%macro CHECKDS(FILE,LONGFILE);
%if %sysfunc(exist(&FILE)) %then;
%else %do;
data _null_;
file print ls=255;
&MSG30 put "ERROR : [Msg30] Program halted, file &LONGFILE does not exist";
abort; run;
%end;
%mend CHECKDS;
Now when I call it with this:
LIBNAME IN1 "/folders/myfolders/";
%CHECKDS(&STPERSON.TXT,PERSON)
run;
I get this error: ERROR : [Msg30] Program halted, file PERSON does not exist.
I know that the files exists and is in that location. Any ideas?

The first argument to the exist function should be in the format libname.memname. The second argument to the exist function specifies the member type; since you didn't specify the member type, the default, DATA, is assumed. This implies a file with a SAS data file with a sas7bdat extension.
See here for a list of member types.
Since your file is a .txt file, I don't think it can be considered a library member. Anyone is welcome to correct me if I'm wrong.

DWal got it right above. Here's a more complete answer for what I had to do. I had to convert the .txt file to a sas data set (particularly .sas7bdat).
proc import datafile="/folders/myfolders/PERSON"
dbms=dlm
out=person
replace;
delimiter=' ';
getnames=yes;
run;
Then that had to be written to my library and I was able to use it.
data IN1.person ;
set person;
run;

Related

SAS include dynamic path

I have tryed build little macro which in loop it should runother SAS programs.
Table Control_files has two field, where are other part of path to proper sas program.
%LET PATH_TO = '%include "T:\XXX\YYY\ZZZ\';
%LET PATH_end = '.sas"';
data _null_;
set CONTROL_FILES;
call execute ('%runlimitsquery('||&PATH_TO||SCHEMA_NAME||'\'||PROCES_NAME||&PATH_end||');');
run;
I tryed used runlimitsquery because I found somewhere that tip..
When I run my code, log returns:
NOTE: CALL EXECUTE generated line.
NOTE: Line generated by the CALL EXECUTE routine.
1 + %runlimitsquery(%include "T:\XXX\YYY\ZZZ\XXX_TECHNICAL_AAAAA\001_AAAAA.sas");
_
180
WARNING: Apparent invocation of macro RUNLIMITSQUERY not resolved.
ERROR 180-322: Statement is not valid or it is used out of proper order
Anyone can help me?
Ok, I have answer for my problem...
Below code works:
%LET PATH_TO = '%include "T:\XXX\YYY\ZZZ\';
%LET PATH_end = '.sas"';
data _null_;
set CONTROL_FILES;
call execute ('('||&PATH_TO.||SCHEMA_NAME||'\'||PROCES_NAME||&PATH_end.||';');
run;

SAS macros to import and apply macro from text file on csv dataset

I have a text file "Macro definition" which has two SAS macros definition. I would like to import them and apply on HTWT.csv data set. This dataset has 20 observations and 6 variables ID, Gender, Age,Height,Weight,Year. All are numeric except gender variable. I have the code below to import and apply the macros from the txt file to csv file. I am getting an error message on running this code as below.
outcsvv is the name of HTWT dataset imported in SAS.
%include "C:\Users\komal\Desktop\Advanced SAS\Macro definition.txt";
%contents_of(outcsvv)
%print_data(outcsvv)
Warning:Apparent Invocation of macro "contents_of" not resolved
Error: Unable to complete processing of INCLUDE. Expected a filename or fileref
Expected a statement keyword: found "("
The second error I am getting is probably due to the macro definition(s) from the text file which are as follows.
%macro contents_of(name);
proc contents data=&name;
run;
%mend;
%macro print_data(name);
proc print data=&name;
run;
%mend;
Please let me know your advice on how to solve it. Thank you for your time.
You can setup your own macro Autocall Library. Just split your file; save one macro per-file. more.
or you can add this code to the begining of your program:
options insert=(sasautos="/C:\Users\komal\Desktop\Advanced SAS") ;
this will search for the macros in this directory.

SAS macros to save and list all macros in a session

I would like to save all the macros permanently defined as part of an exercise and list all the macros. I have 6 macros which I want to save and retrieve in this session:
%macro one(a,b,c)
%macro gchart(dseti,Weight,Gender)
%macro plot(dsetin,height,weight)
%macro one(a,b,c,strtpt,endpt)
%macro test
%macro name(dsetin,year,revenue)
%macro import_myfile(i=)
I have the code below and the error message follows it.
options mstored sasmstore=macross;
libname mjstore "C:\Users\komal\Desktop\Advanced SAS";
proc catalog cat=mjstore.macross;
contents;
title "Default Storage of SAS Macros";
quit
Error: Catalog "MJSTORE.MACROSS" not found
Please let me know your advice on how to solve it. Thank you for your time.
The default catalog is WORK.SASMACR
%macro one(a,b,c); %mend;
%macro gchart(dseti,Weight,Gender); %mend;
%macro plot(dsetin,height,weight); %mend;
%macro one(a,b,c,strtpt,endpt); %mend;
%macro test; %mend;
%macro name(dsetin,year,revenue); %mend;
%macro import_myfile(i=); %mend;
proc catalog cat=work.SASMACR;
contents;
title "Default Storage of SAS Macros";
quit;
The best way to find out which macros were defined during your program is to not use stored macro catalog options. Instead just let SAS default to storing them a WORK catalog. You can then use PROC CATALOG to see what macros have been compiled. Normally that will be WORK.SASMACR catalog, but if you are using alternative ways of running SAS (Enterprise Guide, SAS/Studio, stored process servers etc) it might be WORK.SASMACR1 catalog instead.
proc print data= sashelp.vcatalg width=min;
where libname='WORK' and memname='SASMACR'
and memtype='CATALOG' and objtype='MACRO'
;
var objname modified objdesc ;
run;
If you are using autocall macros newer versions of SAS will store the filename in the OBJDESC field in the metadata. Otherwise here is a link to a macro that will generate a list of the compiled macros and try to match them to a corresponding source file from the autocall library or other directories you might provide it. https://github.com/sasutils/macros/blob/master/maclist.sas

How to write macro for importing multiple excel files(xlsx) in sas and append it

I am having some 50 excel files (xlsx format) to be imported to sas and then need to append it for analysis. All the excel files header are same i.e., the variable names are same for all the file. I need macro for importing and appending all of them at a time rather than importing all the files one by one and then later append it. Your help is much appreciated.
The other issue with the excel file is that there is a blank column next between the variable name and data points. I have written a code remove it using data step but came we write this also in the macro while importing.
Data XXX.yyy;
Set XXX.yyy;
if missing(coalesceC(of ASC Brand Cdesc1 Cust_ DGM Desc Family Grp1 High_Level_Product_Desc
Issf Name Prod_Desc Product__Code RVP SA_Desc Terr_ UOM Yr
)) and missing(coalesce(of Acc Int_Margin M_Cost Mth Net_Sales Sls__ Uts )) then delete;
run;
It sounds as though your existing code already does what you need it to do. I doubt there will be much of a performance gain from attempting to import all 50 files in one data step (which is possible via dde, but rather fiddly).
If your existing code is set up to process just one hard-coded file, I'd suggest using it to write a simple macro that takes one excel file as input, imports that file, and appends it to the master dataset. Then you can call the macro 50 times.
e.g. You could write the macro as something like this, incorporating all the relevant bits of your code, and replacing all references to specific files with macro variables:
%macro import_and_append(excel_file,base_dataset);
proc import datafile = "&excel_file" dbms = excel out = t_import;
run;
proc append base = &base_dataset data = t_import;
run;
proc datasets lib = work nolist nowarn;
delete t_import;
run;
quit;
%mend;
Then you can call the macro like so:
%import_and_append(c:\excel_file_01.xls,work.master_dataset)
Another way to do this would be to use the Excel LIBNAME Engine. You declare a library to each of your files, and then read all the sheets in 1 Data Step.
In this example, I have 2 workbooks (Book1.xlsx and Book2.xlsx) in C:\temp. All data is in Sheet1. 3 variables -- X, Y, and Z. Modify as needed for your purpose.
data files;
format file $12.;
input file $;
datalines;
Book1.xlsx
Book2.xlsx
;
run;
%macro read_excel(dir,outdata,files);
data _null_;
set &files end=last;
call execute("libname t" || strip(put(_n_,8.)) || " excel '&dir\" || strip(file) || "';");
if last then
call symput("n",_n_);
run;
data &outdata;
set
%do i=1 %to &n;
t&i.."Sheet1$"n
%end;
;
a = sum(x,y,z);
if missing(a) then delete;
run;
%do i=1 %to &n;
libname t&i clear;
%end;
%mend;
%read_excel(c:\temp,data_from_excel,files);

SAS macro do loop-- import multiple flat files

I have a list of 17 flat files that I'm trying to import into different data sets. All of the files have the same data step, so I'm trying to write a do while loop to import all the files.
I've been trying to adapt some code from here without success:
http://www.sas.com/offices/europe/uk/support/sas-hints-tips/tips-enterprise-csv.html
http://support.sas.com/documentation/cdl/en/mcrolref/61885/HTML/default/viewer.htm#a000543785.htm
I'm getting an error that says the %do statement is not valid in open code. Here is my code:
% let path1 = 'c:\path1'
% let path2 = 'c:\path2'
...
% let pathN = 'c:\pathN'
%let n=1;
%do %while (&n <= 17);
%let pathin = &path&n;
data retention&n;
infile &pathin;
<data step-->
run;
%let n=%eval(&n+1);
%end;
I've tested the data step outside of the do-while loop and it works fine for 1 file at a time using the %let pathin = &path&n code. The code still writes the datafile for the 1st data set; but, I need to be able to loop through all the files and can't figure out how. Sorry if this is a novice question; I'm just learning SAS.
Thanks,
-Alex
Welcome to SAS programming! The error message you got is a clue. "Open code" refers to statements that are executed directly by the SAS system. A %do statment is part of the SAS Macro Language, not "normal" SAS. A %let statement can be executed in open code and is use to create a macro variable (distinct from a compiled macro).
Compiled SAS macros are created by code that appears between the %macro and %mend statements. For example, using your code:
%macro run_me;
%let n=1;
%do %while (&n <= 17);
%let pathin = &path&n;
data retention&n;
infile &pathin;
<data step-->
run;
%let n=%eval(&n+1);
%end;
%mend;
But all that does is define/compile the macro. To execute it, you must issue the statement %run_me;. Note that the name run_me was just a name I made up.
For more info, please consult the SAS Macro Reference, especially the introductory section.
To convert your progma to macro, turn your macro variables declared by LET statement into macro arguments:
%macro readfile(n, pathin);
data retention&n;
infile &pathin;
<data step-->
run;
%mend;
A data step to repetitively call your macro.
Here the data included in CARDS statement, but also can be read from some table via SET statement.
The macro call is performed via call execute routine.
data _null_;
length path $200 stmt $250;
input path;
stmt = catt('%readfile(', putn(_N_, 3. -L), path, ')');
call execute(stmt);
cards;
c:\file1.txt
c:\file2.txt
c:\file3.txt
;
run;