This is not working because the call execute executes after the data step is complete, so FLAG isn't set until after the data step is done.
Why are you calling the macro using call execute? Is this just an example from a larger solution?
Well this version works. How does it not work in your situation?
DATA X; INPUT X$ Y$; DATALINES; X 2 ; RUN; DATA Y; X="2"; RUN; %MACRO TEST(); %GLOBAL FLAG; PROC SQL; SELECT DISTINCT X,Y INTO :A,:B FROM X; QUIT; %LET A=%LEFT(%TRIM(&A)); %LET B=%LEFT(%TRIM(&B)); %IF &A. = %BQUOTE('&B.') %THEN %LET FLAG=Y; %ELSE %LET FLAG=N; %MEND; %TEST(); DATA NEW; SET Y; FLAG="&FLAG"; RUN;
Your example is confusing me. You are trying to call that macro while accessing data set Y, but you are not actually referencing any values in that table.
I suggest backing up and telling us what you are trying to do, as I don't think this approach will work.
Remember, macro write code, they cannot read the values in a data step.
I think this is what you want.
DATA X;
INPUT X$ Y$;
DATALINES;
X 2
;
RUN;
DATA Y;
X="2";
RUN;
%MACRO TEST();
%let dsid = %sysfunc(open(work.X));
%do %while(%sysfunc(fetch(&dsid)) = 0);
%let varname = %sysfunc(getvarc(&dsid,1));
%let varval = %sysfunc(getvarc(&dsid,2));
if &varname = "&varval" then FLAG = 'Y';
else FLAG = 'N';
%end;
%let rc = %sysfunc(close(&dsid));
%MEND;
options mprint;
DATA NEW;
SET Y;
%TEST();
RUN;
Notice the MPRINT option. This will show you in the log the code that got created.
Here is a call execute version. Remember all it does is write code as well.
data _null_;
set x end=finished;
if _n_ = 1 then do;
CALL EXECUTE('DATA NEW;');
CALL EXECUTE('SET Y;');
end;
CALL EXECUTE('if ' || X || ' = "' || strip(Y) || '" then FLAG="Y";');
CALL EXECUTE('else FLAG="N";');
if finished then do;
CALL EXECUTE('run;');
end;
run;
@Aman4SAS wrote:
By this i wont be able to create x dynamicly. I need to pick 1st row for 1st condition , 2nd row for 2nd condition, i need to call same macro recursively.
Show us what you mean, "pick 1st row..."
You should be able to call the macro from within a data set using the code from @CurtisMackWSIPP
You can just add rows to the X table and it should work.
You can't call a macro for every row in a data step. The macros write code that is then executed. Look at this call execute that will sets FLAG to equal which variable matched the values in the X. Pay attention to the log. It will show you the code that is actually generated.
DATA X;
INPUT X$ Y$;
DATALINES;
X 2
Y 4
;
RUN;
DATA Y;
X="2";Y="0"; output;
X="0";Y="4"; output;
X="5";Y="3"; output;
RUN;
data _null_;
set x end=finished;
if _n_ = 1 then do;
CALL EXECUTE('DATA NEW;');
CALL EXECUTE('SET Y;');
CALL EXECUTE('if 0 = 1 then FLAG="";');
end;
CALL EXECUTE('else if ' || X || ' = "' || strip(Y) || '" then FLAG="' || strip(X) || '";');
if finished then do;
CALL EXECUTE('else FLAG="N";');
CALL EXECUTE('run;');
end;
run;
Show some example values from both of these "variables" and why you think they are equal.
Or set
Options mprint mlogic symbolgen before running your macro.
The %Left (%Trim( &A.)) is not going to remove, reduce or effect the spacing between different bits of &A. The whole string gets shifted left and the only thing "trimmed" is what comes after the last bit.
Example:
%let A = Some words with differing spaces betweeeen ; %let A = %trim(%left(&A.)); %put &A.;
You might need to Strip the variables (equivalent to Left(trim())) and specify Separated by ' ' to force on blank between the values of the variables. However if some values of the A or B data set variables have differing numbers of blanks embedded in them you really need to provide example data and what you expect.
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.