BookmarkSubscribeRSS Feed
niby
Calcite | Level 5

Hi,

Hope you can help.

 

I have a dataset with a list of file names - I want to run a macro for each file seperately. I have done it like this:

data _null_;
set PHFN038;
call execute('%PHFN038('||"file"||');');
run;

Inside the macro I have to divide every file in to four subsets two headers, one body and one footer. The problem is that SAS unfortunately cant run this data null statement "inside" the execute data null statement...

Does anybody have a solution? 

%macro PHFN038 (file);

filename PHFN038 "&FISpath./&file.";

data import;
infile PHFN038 truncover;
input Data $ 1-1768;
run;

data header1;
set import (firstobs=1 obs=1);
format data01 $9. date ddmmyyd10. data03 $6. data04 $1768.;
data01=substr(Data,1,9);
date=input(substr(Data,10,8),yymmdd8.);
data03=substr(Data,19,6);
data04=substr(Data,25);
run;
data header2;
set import (firstobs=2 obs=2);
format data01 $33. date ddmmyyd10. data03 $1768.;
data01=substr(Data,1,33);
date=input(substr(Data,34,8),yymmdd8.);
data03=substr(Data,42);
run;

%let _end=0;
data _null_;
set import;
nobs=_n_;
call symput('_end',nobs);
call symput('_end_b',nobs-1);
run;
%put &_end;


data body;
set import (firstobs=3 obs=&_end_b.);
format cod_tran $2. data02 $2. corp $2. key_num_acct $16. cod_rsn $2. data06 $30. date ddmmyyd10. data08 13. amount commax12.2 currency $3. data11 $108. data12 11. data13 $1768.;
cod_tran=substr(Data,1,2);
data02=substr(Data,3,2);
corp=substr(Data,5,2);
key_num_acct=substr(Data,7,16);
cod_rsn=substr(Data,29,2);
data06=substr(Data,31,30);
date=input(substr(Data,61,8),yymmdd8.);
data08=input(substr(Data,69,13),13.);
amount=input(substr(Data,82,12),12.)/100;
currency=substr(Data,94,3);
data11=substr(Data,97,108);
data12=input(substr(Data,205,11),11.);
data13=substr(Data,216);
run;

data footer;
set import (firstobs=&_end. obs=&_end.);
format data01 $3. count 6. data03 $34. amount commax12.2 data04 $1768.;
data01=substr(Data,1,3);
count=input(substr(Data,4,6),6.);
data03=substr(Data,10,34);
amount=input(substr(Data,44,12),12.)/100;
data04=substr(Data,56);
run;

Can I change somthing with: (firstobs=3 obs=&_end_b.)?
Can I find the last obs some way else?

Or can I call the macro for each line without a data null statement??

7 REPLIES 7
FredrikE
Rhodochrosite | Level 12

How about some more macro....:)

 

%macro showName(_name);

%put Actual name: &_name;

%mend;

 

%macro t;

/* open table */

%let dsid = %sysfunc(open(sashelp.class));

 

%if (&dsid) %then %do;

/* iterate over the rows */

%do %while(%sysfunc(fetch(&dsid)) ne -1);

%let name = %sysfunc(getvarc(&dsid,%sysfunc(varnum(&dsid,name))));

%showName(&name);

%end;

/* close table */

%let _rc = %sysfunc(close(&dsid));

%end;

%mend;

%t;

 

SASKiwi
PROC Star

Well for starters your CALL EXECUTE step looks like it should be:

 

data _null_;
set PHFN038;
call execute('%PHFN038('||file||');');
run;

The FILE variable name must not be in quotes otherwise SAS will treat it as the text string "FILE".

 

This won't necessarily fix all your problems but it might get you a step closer. 

Kurt_Bremser
Super User

When you call a macro with call execute from a data step, all macro statements in the macro are executed immediately, while all data or procedure steps are delayed until the calling data step finishes.

So, instead of

%let _end=0;
data _null_;
set import;
nobs=_n_;
call symput('_end',nobs);
call symput('_end_b',nobs-1);
run;
%put &_end;

I'd try

data _null_;
call symput('_end',put(nobs),best.);
call symput('_end_b',put(nobs-1,best.));
put nobs;
set import nobs=nobs;
stop;
run;
RW9
Diamond | Level 26 RW9
Diamond | Level 26

What does your data look like, its just seems to be an awful faff splitting thngs up, multiple reads, mulitple files etc.  Sure there isn't a simpler method?

niby
Calcite | Level 5

My data have to be divided into several datasets due to the further processing. It is possible that it can be done easier - but i am not that experienced. Do you have an idea?

RW9
Diamond | Level 26 RW9
Diamond | Level 26

"My data have to be divided into several datasets due to the further processing"

Sounds like your whole process is a bit overcomplicated then.

Astounding
PROC Star

Given that you have solved so much of the problem with one approach, a slight modification should overcome the problems:

 

call execute('%nrstr(%PHFN038('|| strip(file) ||')')');

 

As was pointed out by other posters, the variable name FILE should not be in quotes, and you need to delay execution of %phfn038 until the DATA step finishes, in order to delay executing the %LET statement within.  A small note:  semicolon are not needed to execute a macro so one semicolon was removed on purpose.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 1749 views
  • 1 like
  • 6 in conversation