BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
SAS_PA1
Calcite | Level 5

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.

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

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;

View solution in original post

11 REPLIES 11
ChrisNZ
Tourmaline | Level 20

You have a problem with the %trim macro.

1. How do you create TOTOBS?

2. What happens if you don't use  %trim ?

SAS_PA1
Calcite | Level 5
data compnm;
infile compnm ;
input fname $46.;
put _infile_;
run;

data _null_;
set compnm;
CALL SYMPUT( 'TOTOBS' , _N_ );
%put &TOTOBS;
run;
ChrisNZ
Tourmaline | Level 20

Try to use symputx instead of symput, and do not call %trim

Patrick
Opal | Level 21

@SAS_PA1

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.

 

 

Tom
Super User Tom
Super User

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;
SAS_PA1
Calcite | Level 5

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;

Tom
Super User Tom
Super User

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|;

 

SAS_PA1
Calcite | Level 5

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;

Tom
Super User Tom
Super User

@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;

 

Patrick
Opal | Level 21

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;
SAS_PA1
Calcite | Level 5

Thank you. Its working fine

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 908 views
  • 1 like
  • 4 in conversation