SAS include dynamic path - macros

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;

Related

SAS Macro operations

I need to create sum of 4 variables multiple times each time with new set of variables. For e.g. A1=sum(a1,a2,a3,a4),B1=sum(b1,b2,b3,b4) & so on. So , I am trying to write a macro that will help me do it easily. Following is the code:
%macro SUM2(VAR1,var2,var3,VAR4);
data Subs_60_new;
set Subs_60;
substr(&var1,1,10)=sum(&var1,&var2,&var3,&var4);
run;
%mend sum2;
options mprint mlogic;sum2(ADDITIONAL_INFO_Q1,ADDITIONAL_INFO_Q2,ADDITIONAL_INFO_Q3,ADDITIONAL_INFO_Q4);
I am using SAS EG for the same & when I run the macro I get the following note:
NOTE: Writing TAGSETS.SASREPORT13(EGSR) Body file: EGSR
& obviously when I try to execute the macro it throws an error.
Can some one help me out?
when calling a macro, you need to precede the macro name with a % symbol, eg as follows:
%macro SUM2(VAR1,var2,var3,VAR4);
data Subs_60_new;
set Subs_60;
substr(&var1,1,10)=sum(&var1,&var2,&var3,&var4);
run;
%mend sum2;
options mprint mlogic;
%sum2(ADDITIONAL_INFO_Q1,ADDITIONAL_INFO_Q2,ADDITIONAL_INFO_Q3,ADDITIONAL_INFO_Q4);
The NOTE is harmless. It is ERRORs and WARNINGs in general that you should be concerned with.
I'd point out that this will probably still throw an error, as you are trying to replace characters in a variable (&var1) that appears as though it should contain a numeric field (being part of a sum function). Given your description of what you are trying to achieve, I'd suggest adding the new variable name as another macro parameter - as follows:
%macro SUM2(VAR1,var2,var3,VAR4,varname);
data Subs_60_new;
set Subs_60;
&varname=sum(&var1,&var2,&var3,&var4);
run;
%mend sum2;
options mprint mlogic;
%sum2(ADDITIONAL_INFO_Q1,ADDITIONAL_INFO_Q2
,ADDITIONAL_INFO_Q3,ADDITIONAL_INFO_Q4
,MyNewVariable);

SAS Macro Variable Quoted Concatenation

I am debugging a macro I am writing that will treat a string as either a prefix or suffix of a dataset name based on user input. Then, the quoted result will be fed into another process downstream.
So if the user says Type=1 and provides the string 'data_', the output of the resulting macro variable will be 'data_%'.
I've tried a few different iterations of the below code, but can't quite get it....any help would be greatly appreciated. Thanks.
%let Type=1;
%let TableName=data_;
data _null_;
if &Type=1 then
call symput('qTableName',%unquote(%str(%')(cats(&TableName.,"%"))%str(%')));
else if &Type=2 then
call symput('qTableName',%unquote(%str(%')(cats("%",&TableName.))%str(%')));
run;
%put &qTableName;
Looks like you are trying to add single quotes to a macro variable.
%let TableName=data_;
%let qTableName='data_%';
So in a data step you can use CATQ().
data _null_;
call symputx('qTableName',catq('1a',cats(symget('TableName'),'%')));
run;
Or in simple macro code just use %bquote() to allow you to add ' and % without preventing macro variable expansion. But you probably want to remove the macro quoting it will cause.
%let qTableName=%unquote(%bquote('&TableName%'));
Or if you only want to add the % when &TYPE=1 then perhaps you could call the IFC() function. I believe that the %sysfunc() call will remove the macro quoting.
%let Type=1;
%let qTableName=%sysfunc(ifc(&type=1,%bquote('&TableName%'),%bquote('&TableName')));

SAS Macro not detecting a file

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;

Call System output in Macro Variable

I want to get the file size of a csv file in AIX and using following X and Call System Command to do. The problem is I cant get the "File Size" in a macro variable which I will be using later in the program.
data _null_;
call system('du -g p_bhj_c_hh100uk01po1.csv');
call symput('space','X du -g p_bhj_c_hh100uk01po1.csv');
%put &space;
run;
WARNING: Apparent symbolic reference SPACE not resolved.
First, the SYMPUT subroutine you call does not work like you are trying to use it (ala Perl). I recommend reading the documentation on it.
The error you get on the SPACE macro is because it is inside the DATA Step. Macros "write" SAS code for you, so it &SPACE macro is trying to be resolved BEFORE the DATA Step executes.
Here is a code example to do what you are looking for:
data _null_;
rc = filename("ref","e:\temp\reg.pdf");
fid = fopen("ref");
infonum = foptnum(fid);
do i=1 to infonum;
infoname = foptname(fid,i);
infoval=finfo(fid,infoname);
put infoname= infoval=;
end;
close = fclose(fid);
run;
/*In Windows, attribute is "File Size (bytes)"*/
data _null_;
rc = filename("ref","e:\temp\reg.pdf");
fid = fopen("ref");
size=finfo(fid,"File Size (bytes)");
call symput("size",size);
close = fclose(fid);
run;
%put &size;
The File Size attribute may be different in AIX. Run the first part to see all the attributes available. Then modify the second accordingly. Likewise, you will need to add the call to produce the file like you are already doing.

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;