DATA Step, Macro, Functions and more

How I do fix the below mentioned SAS Macro Code

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 13
Accepted Solution

How I do fix the below mentioned SAS Macro Code

 

 

 

01JAN2015

NOTE: Line generated by the macro variable "YR".

44 visit_in_JAN2015

____

22

____

200

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, (, /, ;, _DATA_, _LAST_, _NULL_.

ERROR 200-322: The symbol is not recognized and will be ignored.

 

/*CODE*/ 

 

%let startdate= '01Jan2015'd;

%macro loop;

%do i=1 %to 24;

%let prev_month=%sysfunc(intnx(month,"&startdate"d,-1), date9.);

%let date=%sysfunc(intnx(month,"&prev_month"d, &i.), date9.);

%put &date.;

%let month= %sysfunc(month("&date"d));

%let yr= %sysfunc(year("&date"d));

%let mon=%qsubstr(&date, 3,3);

%visit(&mon.,&yr.);

%put &month &yr &mon;

%end;

%mend;

 

%loop;

%let startdate= '01Jan2015'd;

%macro loop;

%do i=1 %to 24;

%let prev_month=%sysfunc(intnx(month,"&startdate"d,-1), date9.);

%let date=%sysfunc(intnx(month,"&prev_month"d, &i.), date9.);

%put &date.;

%let month= %sysfunc(month("&date"d));

%let yr= %sysfunc(year("&date"d));

%let mon=%qsubstr(&date, 3,3);

%visit(&mon.,&yr.);

%put &month &yr &mon;

%end;

%mend;

 

%loop;

 

 


Accepted Solutions
Solution
‎03-18-2018 11:13 AM
Super User
Super User
Posts: 7,844

Re: How I do fix the below mentioned SAS Macro Code

You can either fix the %VISIT() macro by adding an %UNQUOTE() call around the dataset name that is getting broken up because of the macro quoting.

 

Or you can fix your looping/driver program to NOT add the macro quoting to begin with.

Change.

%LET YR =%qsubstr(&date,6,4);
%LET MON =%qsubstr(&date, 3,3);

To

%LET YR =%substr(&date,6,4);
%LET MON =%substr(&date, 3,3);

View solution in original post


All Replies
SAS Super FREQ
Posts: 9,253

Re: How I do fix the below mentioned SAS Macro Code

Hi:

  You have 2 macro programs at work. It is pretty clear that the %loop macro is just creating values that are being passed to the %visit macro. I removed the call to %visit and tested only your other statements in %loop and it appears that they are working correctly. As you can see from running the program a limited number of times, a valid value for YR seems to be generated:

prob_not_inside_loop_macro.png

  Your error message was fairly clear, though, that something that is generated when &YR is used inside %visit is causing the error message. Have you turned on MLOGIC, SYMBOLGEN and MPRINT? What is the %visit macro program doing? My suggestion is that you review what is in %visit outside of the %loop macro program and see why the error is generated inside %visit.

 

Cynthia

PROC Star
Posts: 8,094

Re: How I do fix the below mentioned SAS Macro Code

It would help if you post your %visit macro.

 

Art, CEO, AnalystFinder.com

 

Occasional Contributor
Posts: 13

Re: How I do fix the below mentioned SAS Macro Code

I have replied to TOM , please find the details about VISIT macros. thank you

Super User
Posts: 22,820

Re: How I do fix the below mentioned SAS Macro Code

Use a DATA step and CALL execute to loop your macros rather than another macro loop. It's much easier to work with and debug.

Occasional Contributor
Posts: 13

Re: How I do fix the below mentioned SAS Macro Code

I have a visit macro. Which has to be run from Jan 2015 to current month. to avoid  manually passing parameter values in visit macro,

how to create in DATA step and CALL execute to loop macros .

Can you please provide me sample code to above scenario?

 

%visit(&mon.,&yr.);

Super User
Super User
Posts: 7,844

Re: How I do fix the below mentioned SAS Macro Code

Just a shot in the dark since you have not posted the macro.

 

Why are you adding macro quoting to a three character string that does not contain any special characters?
Try changing to regular substr().

%let mon=%substr(&date, 3,3);
Occasional Contributor
Posts: 13

Re: How I do fix the below mentioned SAS Macro Code

The visit  macro is creating output SAS datasets for each month and respective year. So that we need to add manually for each year and month. instead of that if I can create a macros in do loop and passing parameters for start date and end date so that it will execute.

finally that output format it should be (visit_in_jan2016 and so on...).  that is why I added this statement.

%let mon=%substr(&date, 3,3);

 

To avoid the below steps I created macro. Like that for each year and each month..

%visit(jan,2016);
%visit(feb,2016);
%visit(mar,2016);

 

Please find the below visit macro

 

%macro visit(mon,yr);
data out.visit_in_&mon.&yr.;
  length diag_i_1-diag_i_50 $10.;
  set visit_in_&mon.&yr.;* (obs=100 );
  prov_nbr=COMPRESS(UPCASE(LEFT(TRIM(PROV_NBR))),'-ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ','k');

  array diag_i_ {50}  diag_i_1-diag_i_50;
  array proc_i_ {24}  proc_i_1-proc_i_24;

  do i = 1 to 50;
  diag_i_{i}=compress(diag_i_{i},".");
   if icd_flag=9 then do;
   if diag_i_{i} ne '' and substr(diag_i_{i},1,1) = 'E' and length(diag_i_{i}) > 4 then diag_i_{i} = substr(diag_i_{i},1,4)||"."||substr(diag_i_{i},5,1);
      else if diag_i_{i} ne '' and substr(diag_i_{i},1,1) = 'E' and length(diag_i_{i}) <=4 then diag_i_{i}=diag_i_{i};
      else if diag_i_{i} ne '' and length(diag_i_{i}) > 3 then diag_i_{i}=substr(diag_i_{i},1,3)||"."||substr(diag_i_{i},4,2);
   else if diag_i_{i} ne '' and length(diag_i_{i}) <=3 then diag_i_{i}=diag_i_{i};
   else diag_i_{i}='';
  end;

  if icd_flag=10 then do;
   if diag_i_{i} ne '' and length(diag_i_{i}) > 3 then diag_i_{i}=substr(diag_i_{i},1,3)||"."||substr(diag_i_{i},4,7);
 else if diag_i_{i} ne '' and length(diag_i_{i}) <=3 then diag_i_{i}=diag_i_{i};
 else diag_i_{i}='';
  end; 
  end;

  do j=1 to 24;
    proc_i_{j}=compress(proc_i_{j},".");
  if icd_flag=9 then do;
   do j=1 to 24;
      if proc_i_{j} ne '' and length(proc_i_{j}) > 2 then proc_i_{j}=substr(proc_i_{j},1,2)||"."||substr(proc_i_{j},3,2) ;
   else if proc_i_{j} ne '' and length(proc_i_{j}) <= 2 then proc_i_{j}=proc_i_{j};
   else proc_i_{j} ='';
    end;
  end;
  end;

/*  if mem_gender='' then mem_gender='U';*/
  if claim_id='' then claim_id ='UNK';
  if claim_type='' then claim_type='UK';
  if units=. then units=1;
  if claim_line_nbr = . then claim_line_nbr=1;
  if product_id= . then product_id=-1;
/*  MED_ELIG_CAT_ID=0;*/
  cvx='';
  CPTII_MOD_1='';
  CPTII_MOD_2='';
  PN_IND='';
run;
%mend visit;

%visit(jan,2016);
%visit(feb,2016);
%visit(mar,2016);
%visit(apr,2016);
%visit(may,2016);
%visit(jun,2016);
%visit(jul,2016);
%visit(aug,2016);
%visit(sep,2016);
%visit(oct,2016);
%visit(nov,2016);
%visit(dec,2016);

%visit(jan,2017);
%visit(feb,2017);
%visit(mar,2017);
%visit(apr,2017);
%visit(may,2017);
%visit(jun,2017);
%visit(jul,2017);
%visit(aug,2017);
%visit(sep,2017);
%visit(oct,2017);
%visit(nov,2017);
%visit(dec,2017);
%visit(jan,2018);

data out.visit_in_py;
 set
  out.visit_in_jan2016 out.visit_in_feb2016 out.visit_in_mar2016
  out.visit_in_apr2016 out.visit_in_may2016 out.visit_in_jun2016
  out.visit_in_jul2016 out.visit_in_aug2016 out.visit_in_sep2016
  out.visit_in_oct2016 out.visit_in_nov2016 out.visit_in_dec2016

  out.visit_in_jan2017 out.visit_in_feb2017 out.visit_in_mar2017
  out.visit_in_apr2017 out.visit_in_may2017 out.visit_in_jun2017
  out.visit_in_jul2017 out.visit_in_aug2017 out.visit_in_sep2017
  out.visit_in_oct2017 out.visit_in_nov2017 out.visit_in_dec2017

  out.visit_in_jan2018
  ;
 run;

Super User
Super User
Posts: 7,844

Re: How I do fix the below mentioned SAS Macro Code

[ Edited ]

Inappropriate macro quoting is your problem. Try this simple test program to demonstrate the issue.

%macro test(month,year);
data test_&month.&year ;
  x=1;
run;
%mend test;
options mprint;
%test(jan,2017);
%let mon=%qsubstr(jan,1,3);
%test(&mon,2017);

The first call works fine.

28   %test(jan,2017);
MPRINT(TEST):   data test_jan2017 ;
MPRINT(TEST):   x=1;
MPRINT(TEST):   run;

The second call seems to generate the right code but SAS is confused by it because of the macro quoting.

29   %let mon=%qsubstr(jan,1,3);
30   %test(&mon,2017);
NOTE: Line generated by the macro variable "DSNAME".
30    test_jan2017
              ----
              22
                ----
                200
MPRINT(TEST):   data test_jan2017 ;
MPRINT(TEST):   x=1;
MPRINT(TEST):   run;

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, (, /, ;,
              _DATA_, _LAST_, _NULL_.

ERROR 200-322: The symbol is not recognized and will be ignored.

NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.TEST_ may be incomplete.  When this step was stopped there were 0
         observations and 1 variables.
WARNING: The data set WORK.JAN may be incomplete.  When this step was stopped there were 0
         observations and 1 variables.

Two solutions.

1) Don't add the macro quoting to begin with as it is NOT needed. The three digit codes for months of the year will never contain anything that needs to be macro quoted.

2) Harden the macro to remove any macro quoting that is passed into it.

%macro test(month,year);
%local dsname ;
%let dsname=%unquote(test_&month.&year);
data &dsname ;
  x=1;
run;
%mend test;

 

Occasional Contributor
Posts: 13

Re: How I do fix the below mentioned SAS Macro Code

As per given fist solution, can you please provide me some more clarity on this how to fix my code. because I'm unable to fix it.

it's causing same error.

 

1) Don't add the macro quoting to begin with as it is NOT needed. The three digit codes for months of the year will never contain anything that needs to be macro quoted.

 

The second solution the one which you given me, we have to pass hardcode manually for each year and months. That's not the case .

Occasional Contributor
Posts: 13

Re: How I do fix the below mentioned SAS Macro Code

Please find the below code. Help me how to resolve the issues?

 

%macro visit(mon,yr);;
data test_&mon.&yr.;
set sashelp.class;
run;
%mend;
Options macrogen symbolgen mlogic mprint mfile;
%let startdate= '01Jan2015'd;
%let Curr_Date= '28FEB2016'd;
%let Counter = %sysfunc(intck(month,&startdate,&Curr_Date));
%put &counter.;
options spool ;
%macro loop;
%do i=1 %to &counter.;
   %let prev_month=%sysfunc(intnx(month,"&startdate"d,-1), date9.);
   %let date=%sysfunc(intnx(month,"&prev_month"d, &i.), date9.);

   %put &date.;
   /*%let month= %sysfunc(month("&date"d));*/
   /*%let yr= %sysfunc(year("&date"d));*/
   %GLOBAL yr;
%LET YR =%qsubstr(&date,6,4);

   %GLOBAL mon;
%LET MON =%qsubstr(&date, 3,3);

   %PUT &MON;


   %visit(&mon.,&yr.);

%end;

%mend;
%loop;

Solution
‎03-18-2018 11:13 AM
Super User
Super User
Posts: 7,844

Re: How I do fix the below mentioned SAS Macro Code

You can either fix the %VISIT() macro by adding an %UNQUOTE() call around the dataset name that is getting broken up because of the macro quoting.

 

Or you can fix your looping/driver program to NOT add the macro quoting to begin with.

Change.

%LET YR =%qsubstr(&date,6,4);
%LET MON =%qsubstr(&date, 3,3);

To

%LET YR =%substr(&date,6,4);
%LET MON =%substr(&date, 3,3);
Occasional Contributor
Posts: 13

Re: How I do fix the below mentioned SAS Macro Code

It's working perfect!!

Thank you so much for continuous support to me.

thank you all. It's a great experience for me..

 

 

Occasional Contributor
Posts: 13

Re: How I do fix the below mentioned SAS Macro Code

 

 

Please find the below I given details for Visit macros. If I normally tested it is creating successfully.

 

NOTE: There were 19 observations read from the data set SASHELP.CLASS.

NOTE: The data set WORK.TEST_JAN2015 has 19 observations and 5 variables.

NOTE: DATA statement used (Total process time):

real time 0.01 seconds

cpu time 0.02 seconds

 

%macro visit(mon,yr);;

data test_&mon.&yr.;

set sashelp.class;

run;

%mend;

%visit(jan,2015);

 

Could you please assist me ?

☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 13 replies
  • 190 views
  • 1 like
  • 5 in conversation