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.
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.
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;
Looks like you are missing a parenthesis .
%sysfunc(exist(&ds1_in.)
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.
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;
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.
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.;
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!
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.
Ready to level-up your skills? Choose your own adventure.