For the below code I am getting error, please suggest me the changes. Thank you.
%macro LOOP;
%global fname2 fname;
%DO I=1 %TO &TOTOBS;
data _Null_;
set compnm (Firstobs=&I obs=&i);
call SYMPUT('fname2',trim(fname));
run;
%put &fname2;
%internal_db_Mh_Prod1(&i,&fname2);
%END;
%MEND LOOP;
%LOOP;
Data Med_Cases;
Set PDATA_1-PDATA_%TRIM(&TOTOBS);
Proc sort ; by Task_datetime;
run;
Proc datasets;
Delete PDATA_1-PDATA_%TRIM(&TOTOBS);
delete compnm;
Run;
LOG FILE ERROR
4169 records were read from the infile PDATA.
The minimum record length was 77.
The maximum record length was 111.
NOTE: The data set WORK.PDATA_109 has 2132 observations and 8 variables.
NOTE: Compressing data set WORK.PDATA_109 decreased size by 40.00 percent.
Compressed is 6 pages; un-compressed would require 10 pages.
NOTE: DATA statement used (Total process time):
real time 45.00 seconds
cpu time 0.02 seconds
119
120 Data Med_Cases;
121 Set
121 ! PDATA_1-PDATA_%TRIM(&TOTOBS);
NOTE: Autocall member, TRIM, has not been compiled by the macro processor. It might contain a macro syntax error or not define a
macro with the same name as the member. To autocall this member again, set OPTION MRECALL.
121 (&TOTOBS);
_
22
76
ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, _DATA_, _LAST_, _NULL_.
ERROR 76-322: Syntax error, statement will be ignored.
122
123
NOTE: Compression was disabled for data set WORK.MED_CASES because compression overhead would increase the size of the data set.
NOTE: The SAS System stopped processing this step because of errors.
Where did you define the TOTOBS macro variable? It is not set in the code you posted.
Perhaps something more like this for your %LOOP macro?
%macro LOOP;
%if not %symexist(totobs) %then %global totobs;
data _null_;
if eof then call symputx('totobs',put(_n_-1,32.));
set compnm end=eof ;
call execute(cats('%nrstr(%internal_db_Mh_Prod1)(',_n_,',',fname,')'));
run;
%mend LOOP;
%LOOP;
Although in that case why make it a macro at all?
data _null_;
if eof then call symputx('totobs',put(_n_-1,32.));
set compnm end=eof ;
call execute(cats('%nrstr(%internal_db_Mh_Prod1)(',_n_,',',fname,')'));
run;
You have a problem with the %trim macro.
1. How do you create TOTOBS?
2. What happens if you don't use %trim ?
Try to use symputx instead of symput, and do not call %trim
Looking at your code what you're trying to achieve with the %TRIM() macro is to left align the value in macro var &TOTOBS.
%TRIM() doesn't give you that. TRIM is "cutting off" trailing blanks but you want to "cut off" leading blanks. That's done with the LEFT function or on a macro level you can also use the OOTB function style macro %LEFT()
Even though %TRIM is not the appropriate macro in first place it's still a bit worrying that %TRIM() throws a syntax error. This is an OOTB SAS macro. "Someone" must have overwritten/overlayed it with invalid syntax. If it wasn't you then "someone" at your site messed up the SAS environment. Contact your SAS Admin as this needs fixing.
By setting options mautolocdisplay; in your code you'll see in the log where from a macro has been picked up. The path you should see for %trim() and %left is something like ...\SASFoundation\9.4\core\sasmacro\trim.sas
And last but not least go for what @ChrisNZ proposes and ensure that the values are left aligned when populating the macro var by using symputx(). In doing so you won't need %trim() or %left() at all in your code.
Where did you define the TOTOBS macro variable? It is not set in the code you posted.
Perhaps something more like this for your %LOOP macro?
%macro LOOP;
%if not %symexist(totobs) %then %global totobs;
data _null_;
if eof then call symputx('totobs',put(_n_-1,32.));
set compnm end=eof ;
call execute(cats('%nrstr(%internal_db_Mh_Prod1)(',_n_,',',fname,')'));
run;
%mend LOOP;
%LOOP;
Although in that case why make it a macro at all?
data _null_;
if eof then call symputx('totobs',put(_n_-1,32.));
set compnm end=eof ;
call execute(cats('%nrstr(%internal_db_Mh_Prod1)(',_n_,',',fname,')'));
run;
The code that which I have provide in the beginning its working fine using FTP command, when I am using with sftp I am getting provided Log error
filename compnm sftp ''ls cd= /path
data compnm;
infile compnm ;
input fname $46.;
put _infile_;
run;
data _null_;
set compnm;
CALL SYMPUT( 'TOTOBS' , _N_ );
%put &TOTOBS;
1) Do not use call symput() instead of call symputx(), unless you really really really want to make macro variables with leading and/or trailing spaces in them.
2) Don't reference a macro variable before it has been created!.
data _null_;
set compnm end=eof;
if eof then do;
CALL SYMPUTX( 'TOTOBS' , _N_ );
CALL SYMPUT( 'BAD_TOTOBS' , _N_ );
end;
run;
%put |&TOTOBS| |&BAD_TOTOBS|;
Refrencing Macro variable after it has created below is the code format. Thank you.
filename compnm sftp ''ls cd= /path
data compnm;
infile compnm ;
input fname $46.;
put _infile_;
run;
data _null_;
set compnm;
CALL SYMPUT( 'TOTOBS' , _N_ );
%put &TOTOBS;
%macro LOOP;
%global fname2 fname;
%DO I=1 %TO &TOTOBS;
data _Null_;
set compnm (Firstobs=&I obs=&i);
call SYMPUT('fname2',trim(fname));
run;
%put &fname2;
%internal_db_Mh_Prod1(&i,&fname2);
%END;
%MEND LOOP;
%LOOP;
Data Medhok_Cases;
Set PDATA_1-PDATA_%TRIM(&TOTOBS);
Proc sort ; by Task_datetime;
run;
Proc datasets;
Delete PDATA_1-PDATA_%TRIM(&TOTOBS);
delete compnm;
Run;
@SAS_PA1 wrote:
Refrencing Macro variable after it has created below is the code format. Thank you.
filename compnm sftp ''ls cd= /path
data compnm;
infile compnm ;
input fname $46.;
put _infile_;
run;data _null_;
set compnm;
CALL SYMPUT( 'TOTOBS' , _N_ );
%put &TOTOBS;
%macro LOOP;
%global fname2 fname;
%DO I=1 %TO &TOTOBS;
data _Null_;
set compnm (Firstobs=&I obs=&i);
call SYMPUT('fname2',trim(fname));
run;
%put &fname2;
%internal_db_Mh_Prod1(&i,&fname2);
%END;
%MEND LOOP;
%LOOP;
Data Medhok_Cases;
Set PDATA_1-PDATA_%TRIM(&TOTOBS);
Proc sort ; by Task_datetime;
run;
Proc datasets;
Delete PDATA_1-PDATA_%TRIM(&TOTOBS);
delete compnm;
Run;
You don't seem to be reading any of the replies to your question. Have you tried making the changes suggested?
Why do you still have a %PUT &TOTOBS statement in the middle of the data step that is going to set the value of that macro variable when it runs?
You start defining a DATA _NULL step and then before finishing it, so that SAS can run it, you add
1) A %PUT
2) A %macro definition block.
3) A call do the macro.
So when the %LOOP macro runs the data _NULL_ step has NOT YET RUN and the macro variable TOTOBS had not been created.
data_null_;
set compnm;
CALL SYMPUTX( 'TOTOBS' , _N_ );
run;
%put &TOTOBS;
You really should end any data step and proc step with a RUN; command.
Below code bit...
data _null_;
set compnm;
CALL SYMPUT( 'TOTOBS' , _N_ );
%put &TOTOBS;
....would be more efficient and actually do what you're after if coded like...
data _null_;
CALL SYMPUTx( 'TOTOBS' , nobs );
stop;
set compnm nobs=nobs;
run;
%put &TOTOBS;
Thank you. Its working fine
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.