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

Hello Everyone! 

I read about a technique called %TableDrivenMacro to repeatedly call a target macro using data from a dataset as the parameters here: https://support.sas.com/resources/papers/proceedings/pdfs/sgf2008/102-2008.pdf

However, whenever I run this macro, I get the following statement:

WARNING: Apparent invocation of macro TABLEDRIVENMACRO not resolved.
ERROR 180-322: Statement is not valid or it is used out of proper order.

 

My code is below. I have a flattened dataset (postraw.flatdiscrep) with one unique observation for one row and am trying to make the dataset long. 

data postraw.scorelong (keep=encounterid registryid eventid varnum varsort sectionnum varname disclevel varraw varadjud discnote majdenom alldenom);
length encounterid 8
varname $255
;

merge postraw.rawrcenc (in=inanalysis keep=encounterid)
postraw.rawsite (rename=(pacencounterid=encounterid))
postraw.flatdiscrep
;
by encounterid; if inanalysis;

%tabledrivenmacro(Table=Scorevars,
Macro=Byvarv1,
Parms=varname varnum varsort sectionnum hasmajoryn hasminoryn parentvar1 parentval1 parentvar2 parentval2 parentvar3 parentva13
parentvar4 parentval4);
/* deal with age-dependent */
if pacagestartd <= 365 then do;
%tabledrivenmacro(Table=Infant,
Macro=Byvarv1,
Parms=varname varnum varsort sectionnum hasmajoryn hasminoryn parentvar1 parentval1 parentvar2 parentval2 parentvar3 parentva13
parentvar4 parentval4);
end;
run;

 

I have an %include statement to reference the Byvarv1 macro. I noticed that discusses %TableDrivenMacro is from 2008, so is it possible that it isn't available in SAS 9.4? 

Thank you! 

1 ACCEPTED SOLUTION

Accepted Solutions
6 REPLIES 6
PaigeMiller
Diamond | Level 26

You have not defined (or %include-d) the macro named TABLEDRIVENMACRO

--
Paige Miller
Reeza
Super User
If this is what you need to do, I'd recommend using CALL EXECUTE instead.

Here's an example of how that can work, which seems more straightforward IMO.
https://gist.github.com/statgeek/beb97b1c6d4517dde3b2

Tom's answer is likely correct, you haven't shown the code for the %macro tabledrivenmacro that would be the macro definition which you have to run before you call the macro itself.
lkhadr
Calcite | Level 5

Hello again! 

Here is the Byvarv1 macro I referenced earlier. I run this before I run the %tabledrivenmacro 

%macro byvarv1(varname
,varnum
,varsort
,sectionnum
,hasmajoryn
,hasminoryn
,parentvar1
,parentval1
,parentvar2
,parentval2
,parentvar3
,parentva13
,parentvar4
,parentval4);

/* has parent var */
%if not(%sysevalf(%superq(parentvar1)=,boolean)) %then %do;
/* parent had no discrepancy */
if (&parentvar1.lvl = . | &parentvar1.lvl = 0)

%if not(%sysevalf(%superq(parentval1)=,boolean)) %then %do;
*Boolean expression searches for true/false. True=if the argument, in this case value of the parent field=1 or has a length greater than 0 (character variables).
It will read something as false if the parent field=0 or has a length of 0.;
& &parentvar1 = "&parentval1"
%end;


%if not(%sysevalf(%superq(parentvar2)=,boolean)) %then %do;
& (&parentvar2.lvl = . | &parentvar2.lvl = 0)
& not(missing(&parentvar2))
%end;

%if not(%sysevalf(%superq(parentval2)=,boolean)) %then %do;
& &parentvar2 = "&parentval2"
%end;

%if not(%sysevalf(%superq(parentvar3)=,boolean)) %then %do;
/* parent had no discrepancy */
& (&parentvar3.lvl = . | &parentvar3.lvl = 0)
& not(missing(&parentvar3))
%end;

%if not(%sysevalf(%superq(parentva13)=,boolean)) %then %do;
& &parentvar3 = "&parentval3"
%end;


%if not(%sysevalf(%superq(parentvar4)=,boolean)) %then %do;
if (&parentvar4.lvl = . | &parentvar4.lvl = 0)
& not(missing(&parentvar4))
%end;

%if not(%sysevalf(%superq(parentval4)=,boolean)) %then %do;
& &parentvar4 = "&parentval4"
%end;

then do;
%end;

if &varname.lvl in (.,0,1,2) then do;
/* has major */
%if &hasmajoryn = 1 %then %do;
majdenom = 1;
alldenom = 1;
%end;
%else %do;
majdenom = 0;
%if &hasMinorYN=1 %then %do;
alldenom=1;
%end;
%else %do; alldenom=0; %end;
%end;
end;

else if not(missing(&varname.lvl)) then do;
majdenom = 0;
alldenom = 0;
end;

varname = "&varname";
varnum = &varnum;
varsort = &varsort;
sectionnum = &sectionnum;
disclevel = &varname.lvl;
if not(missing(&varname.rc)) then varraw = &varname.rc;
else varraw = &varname;
varadjud = &varname.aud;
discnote = &varname.nte;
output;

%if not(%sysevalf(%superq(parentvar1)=,boolean)) %then %do;
end;
%end;
end;
%mend;

Reeza
Super User

You need the similar macro definition for %tabledrivenmacro. It's not built into SAS it's something a user wrote and if you want to use it, you need to use their code as well and you need to provide that code to use it. 

Kurt_Bremser
Super User

The code that defines the macro can be found at the end of the paper. Copy/paste it into your editor, save it to a file, and %include that file whenever you want to use the macro.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 947 views
  • 0 likes
  • 4 in conversation