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

Hi,

I'm trying to use exist function, but it seems doesn't work as I would like.

I want assign macrovalue different value conditionally if a dataset exist or not.

I provide an example:

 

/***** TEST DATA ******/

DATA test_1;
	x = 2;
run;
DATA test_2;
	x = 2;
run;

/* assing different value to macrovalue date1 and date2 if ds test_1 and 
   test_2 exist or not */

%let ds1_in = work.test_1;
%let ds2_in = work.test_2;

%macro exist;
	%global date1 date2;
		  %if %sysfunc(exist(&ds1_in.) %then %do;
				%let date1 = 20171231;
				%let date2 = 20180131;
		   %end;
	%else %if %sysfunc(exist(&ds2_in.) %then %do;
			        %let date1 = 20180131;
				%let date2 = 20180228;
	%end;
	%else %put "error";
%mend;
%exist;

%put date1 = &date1.;
%put date2 = &date2.;

 I surly make some errors because when I submit macro program the follow massage is written in the log:

 

NOTE: Remote submit to RHOST commencing.
47   %macro exist;
48       %global date1 date2;
49             %if %sysfunc(exist(&ds1_in.) %then %do;
ERROR: Macro keyword DO appears as text.
ERROR: A dummy macro will be compiled.
50                   %let date1 = 20171231;
ERROR: Macro keyword LET appears as text.
51                   %let date2 = 20180131;
ERROR: Macro keyword LET appears as text.
52             %end;
ERROR: Macro keyword END appears as text.
53       %else %if %sysfunc(exist(&ds2_in.) %then %do;
ERROR: There is no matching %IF statement for the %ELSE.
ERROR: Macro keyword IF appears as text.
54                   %let date1 = 20180131;
ERROR: Macro keyword LET appears as text.
55                   %let date2 = 20180228;
ERROR: Macro keyword LET appears as text.
56       %end;
ERROR: Macro keyword END appears as text.
57       %else %put "error";
ERROR: There is no matching %IF statement for the %ELSE.
ERROR: Macro keyword PUT appears as text.
58   %mend;
ERROR: Macro keyword MEND appears as text.
59   %exist;
60   %put date1 = &date1.;
ERROR: Macro keyword PUT appears as text.
61   %put date2 = &date2.;
ERROR: Macro keyword PUT appears as text.
NOTE: Remote submit to RHOST complete.

Can you explain me why?

Mybe is better to use exist function in a datestep than in a macroprogram?

Thanks for your help and time...I have spent several days on this but I can't fix it.

 

1 ACCEPTED SOLUTION

Accepted Solutions
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Or you could just simplfy your code to:

data _null_;
  if exist("&ds1_in.") then do;
    call symputx("date1","20171231","g");
    call symputx("date2","20180131","g");
  end;
  else do;
    call symputx("date1","20180131","g");
    call symputx("date2","20180228","g");   
  end;
run;

However I strongly advise against creating global macro variables in a macro.  This can lead to some very difficult debugging down the line.  Global macro variables affect the whole system.  

Secondly, why would you need to create macro variables for these?  You obviously want the end of the current month as lower, and end of the next month as upper, based on the existence of some file?  Effectively all you are doing is hardcoding in the formula:

intnx('month',<date>,0,"e") ... intnx('month',<date>,1,"e")

Which is really just a waste of code space, use the formula and ditch all the messy useless macro code.

View solution in original post

6 REPLIES 6
PaigeMiller
Diamond | Level 26

How about having matching left and right parentheses? Such as:

 

%macro exist;
	%global date1 date2;
		  %if %sysfunc(exist(&ds1_in.)) %then %do;
				%let date1 = 20171231;
				%let date2 = 20180131;
		   %end;
	%else %if %sysfunc(exist(&ds2_in.)) %then %do;
			        %let date1 = 20180131;
				%let date2 = 20180228;
	%end;
	%else %put "error";
%mend;
--
Paige Miller
r_behata
Barite | Level 11

Looks like you are missing a parenthesis .

 

%sysfunc(exist(&ds1_in.) 

 

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Or you could just simplfy your code to:

data _null_;
  if exist("&ds1_in.") then do;
    call symputx("date1","20171231","g");
    call symputx("date2","20180131","g");
  end;
  else do;
    call symputx("date1","20180131","g");
    call symputx("date2","20180228","g");   
  end;
run;

However I strongly advise against creating global macro variables in a macro.  This can lead to some very difficult debugging down the line.  Global macro variables affect the whole system.  

Secondly, why would you need to create macro variables for these?  You obviously want the end of the current month as lower, and end of the next month as upper, based on the existence of some file?  Effectively all you are doing is hardcoding in the formula:

intnx('month',<date>,0,"e") ... intnx('month',<date>,1,"e")

Which is really just a waste of code space, use the formula and ditch all the messy useless macro code.

Ccasagran737
Fluorite | Level 6

Hi,

I have followed your advice...do you mean something like this? I have tried and it seems work.

Thank for your help!

 

data _null_;
  		if exist("&ds2_in.") then do;
  			dt_rep_1 = put("31OCT2018"d, date9.);
  			dt_rep_2 = put(intnx("month","31OCT2018"d,-1,"e"), date9.);
  		end;
  	else if exist("&ds1_in.") then do;
  			dt_rep_1 = put(intnx("month","31OCT2018"d,-1,"e"), date9.);
  			dt_rep_2 = put(intnx("month","31OCT2018"d,-2,"e"), date9.);
  	end;
    call symputx("date1",dt_rep_1,"g");
    call symputx("date2",dt_rep_2,"g");
run;

 

RW9
Diamond | Level 26 RW9
Diamond | Level 26

No.  What I mean is do not create the macro variables at all.  In your code, where you would have used the macro variables, you use the simply intnx() formula provided.  This avoids creating macro code at all.

mansour_ib_sas
Pyrite | Level 9

Hello,

 

The name of macro is same of function

DATA test_1;
	x = 2;
run;
DATA test_2;
	x = 2;
run;

/* assing different value to macrovalue date1 and date2 if ds test_1 and 
   test_2 exist or not */

%let ds1_in = work.test_1;
%let ds2_in = work.test_2;

%macro tt();
	%global date1 date2;
		  %if %sysfunc(exist(&ds1_in.)) %then %do;
				%let date1 = 20171231;
				%let date2 = 20180131;
		   %end;
	%else %if %sysfunc(exist(&ds2_in.)) %then %do;
			        %let date1 = 20180131;
				%let date2 = 20180228;
	%end;
	%else %put "error";
%mend;
%tt;

%put date1 = &date1.;
%put date2 = &date2.;

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 6 replies
  • 11988 views
  • 1 like
  • 5 in conversation