BookmarkSubscribeRSS Feed
remainmack
Calcite | Level 5

Hello!

 

I have written a macro which contains no errors or warnings but it is not outputting straightforward proc means and freqs inside it.  I checked for imbalance in quotes, etc and didn't see.  I also checked and build it up slowly.  Basically the output of the macro only outputs to right before the 'data _null_' part and then nothing else outputs.  Thank you for any advice.

 

Below is my macro and macro call (afterwards I post the log):  

%macro codebook(lib=,ds=);

%if &lib=BLANK|&ds=BLANK %then %do;
	%put &=lib;
	%put &=ds;
	%abort;
%end;


ods select variables;
proc contents data=&lib..&ds. out=_contents_ ; run;
proc format; value tfmt 1='NUM' 2='CHAR'; run;

data _null_;
	set _contents_ end=last;
	
	call symput("vname"||strip(put(_n_,best.)), strip(name));
	call symput("vtype"||strip(put(_n_,best.)), strip(put(type,tfmt.)));
	call symput("vlabel"||strip(put(_n_,best.)), strip(label));

	if last then call symput("nVars",strip(put(_n_,best.)));
run;


%do j = 1 %to &nVars.;
	title1 "Analysis of &&vlabel&j (Variable=%upcase(&&vname&j.)) ";
	%if %upcase(&&vtype&j)='NUM' %then %do;
		proc means data=&lib.&ds.;
			var &&vname&j.;
		run;
	%end;
	
	%else %if %upcase(&&vtype&j)='CHAR' %then %do;
	
		proc freq data=&lib..&ds.;
			tables &&vname&j.;
		run;
	%end;
%end;

%mend;
	
	
%codebook(lib=out,ds=adsl)	;

Below is my log: You can see that the output stops after the '_null_' section.

 

 OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 NOTE: ODS statements in the SAS Studio environment may disable some output features.
 73         
 74         
 75         %macro codebook(lib=,ds=);
 76         
 77         %if &lib=BLANK|&ds=BLANK %then %do;
 78         %put &=lib;
 79         %put &=ds;
 80         %abort;
 81         %end;
 82         
 83         
 84         ods select variables;
 85         proc contents data=&lib..&ds. out=_contents_ ; run;
 86         proc format; value tfmt 1='NUM' 2='CHAR'; run;
 87         
 88         data _null_;
 89         set _contents_ end=last;
 90         
 91         call symput("vname"||strip(put(_n_,best.)), strip(name));
 92         call symput("vtype"||strip(put(_n_,best.)), strip(put(type,tfmt.)));
 93         call symput("vlabel"||strip(put(_n_,best.)), strip(label));
 94         
 95         if last then call symput("nVars",strip(put(_n_,best.)));
 96         run;
 97         
 98         
 99         %do j = 1 %to &nVars.;
 100        title1 "Analysis of &&vlabel&j (Variable=%upcase(&&vname&j.)) ";
 101        %if %upcase(&&vtype&j)='NUM' %then %do;
 102        proc means data=&lib.&ds.;
 103        var &&vname&j.;
 104        run;
 105        %end;
 106        
 107        %else %if %upcase(&&vtype&j)='CHAR' %then %do;
 108        
 109        proc freq data=&lib..&ds.;
 110        tables &&vname&j.;
 111        run;
 112        %end;
 113        %end;
 114        
 115        %mend;
 116        
 117        
 118        %codebook(lib=out,ds=adsl);
 
 
 Output Added:
 -------------
 Name:       Variables
 Label:      Variables
 Template:   Base.Contents.Variables
 Path:       Contents.DataSet.Variables
 -------------
 NOTE: The data set WORK._CONTENTS_ has 13 observations and 41 variables.
 NOTE: PROCEDURE CONTENTS used (Total process time):
       real time           0.08 seconds
       cpu time            0.09 seconds
       
 
 NOTE: Format TFMT is already on the library WORK.FORMATS.
 NOTE: Format TFMT has been output.
 NOTE: PROCEDURE FORMAT used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 
 NOTE: There were 13 observations read from the data set WORK._CONTENTS_.
 NOTE: DATA statement used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 119        
 120        
 121        OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 133        
12 REPLIES 12
Reeza
Super User

Run it with a check to see if it enters the IF conditions. 

 


	%if %upcase(&&vtype&j)='NUM' %then %do;

               %PUT Condition was Met on &&vtype&j;

		proc means data=&lib.&ds.;
			var &&vname&j.;
		run;
	%end;

And/or turn on the debugging options, re-run and post that log. 

 

options mprint symbolgen mlogic;
remainmack
Calcite | Level 5

Thanks for the de-bugging advice.  I added both checks.  Below is my log and I specifically looked at the end.  I run through 13 variables as you can see it seems okay looping through the variable types.  The very last line, however, I don't understand 'macro variable graphterm resolves to 138' ?:

 

 SYMBOLGEN:  Macro variable NVARS resolves to 13
 MLOGIC(CODEBOOK):  %DO loop beginning; index variable J; start value is 1; stop value is 13; by value is 1.  
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VLABEL1 resolves to Age
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VNAME1 resolves to AGE
 MPRINT(CODEBOOK):   title1 "Analysis of Age (Variable=AGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VTYPE1 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VTYPE1 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 2; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VLABEL2 resolves to Description of Planned Arm
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VNAME2 resolves to ARM
 MPRINT(CODEBOOK):   title1 "Analysis of Description of Planned Arm (Variable=ARM) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VTYPE2 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VTYPE2 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 3; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VLABEL3 resolves to Planned Arm Code
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VNAME3 resolves to ARMCD
 MPRINT(CODEBOOK):   title1 "Analysis of Planned Arm Code (Variable=ARMCD) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VTYPE3 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VTYPE3 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 4; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VLABEL4 resolves to Country
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VNAME4 resolves to COUNTRY
 MPRINT(CODEBOOK):   title1 "Analysis of Country (Variable=COUNTRY) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VTYPE4 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VTYPE4 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 5; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VLABEL5 resolves to Race
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VNAME5 resolves to RACE
 MPRINT(CODEBOOK):   title1 "Analysis of Race (Variable=RACE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VTYPE5 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VTYPE5 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 6; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VLABEL6 resolves to Age categorization
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VNAME6 resolves to agecat
 MPRINT(CODEBOOK):   title1 "Analysis of Age categorization (Variable=AGECAT) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VTYPE6 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VTYPE6 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 7; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VLABEL7 resolves to Change in diastolic bp
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VNAME7 resolves to diabp_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in diastolic bp (Variable=DIABP_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VTYPE7 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VTYPE7 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 8; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VLABEL8 resolves to Change in heart rate
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VNAME8 resolves to hr_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in heart rate (Variable=HR_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VTYPE8 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VTYPE8 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 9; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VLABEL9 resolves to Numeric Result/Finding in Standard Units
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VNAME9 resolves to pcmax
 MPRINT(CODEBOOK):   title1 "Analysis of Numeric Result/Finding in Standard Units (Variable=PCMAX) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VTYPE9 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VTYPE9 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 10; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VLABEL10 resolves to Highest Value
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VNAME10 resolves to pcmax2
 MPRINT(CODEBOOK):   title1 "Analysis of Highest Value (Variable=PCMAX2) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VTYPE10 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VTYPE10 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 11; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VLABEL11 resolves to Change in systolic bp
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VNAME11 resolves to sysbp_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in systolic bp (Variable=SYSBP_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VTYPE11 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VTYPE11 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 12; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VLABEL12 resolves to Unique Subject Identifier
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VNAME12 resolves to usubjid
 MPRINT(CODEBOOK):   title1 "Analysis of Unique Subject Identifier (Variable=USUBJID) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VTYPE12 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VTYPE12 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 13; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VLABEL13 resolves to Change in weight
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VNAME13 resolves to wgt_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in weight (Variable=WGT_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VTYPE13 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='NUM' is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VTYPE13 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)='CHAR' is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 14; loop will not iterate again.
 MLOGIC(CODEBOOK):  Ending execution.
 124        
 125        
 126        OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 SYMBOLGEN:  Macro variable GRAPHTERM resolves to  
 138     
Reeza
Super User
Yeah, NUM = 'NUM' is false because of quotes so remove the quotes in this line:

%upcase(&&vtype&j)='NUM'
FreelanceReinh
Jade | Level 19

Hello @remainmack,

 

The quotes around the strings 'NUM' and 'CHAR' are incorrect in macro language. Just remove them.

 

Also, add the second period in &lib..&ds. in the PROC MEANS step.

remainmack
Calcite | Level 5

Thank you both for the advice.  I forgot about the quotes.  Removing them, however, caused errors.  So what I did was convert 'NUM' to NUM (error) and then to 1 since that is a numeric type.  I did the same for CHAR renaming to 2 (after that error).  I also added the second period as mentioned, but still the output remains stopped after the proc contents.  The loops still look okay when I use 1 and 2 for those types.  The NUM and CHAR with quotes removed, caused errors.

 

I posted the code and log again below.  

 

Code: 

options mprint symbolgen mlogic;
%macro codebook(lib=,ds=);

%if &lib=BLANK|&ds=BLANK %then %do;
	%put &=lib;
	%put &=ds;
	%abort;
%end;


ods select variables;
proc contents data=&lib..&ds. out=_contents_ ; run;
proc format; value tfmt 1='NUM' 2='CHAR'; run;

data _null_;
	set _contents_ end=last;
	
	call symput("vname"||strip(put(_n_,best.)), strip(name));
	call symput("vtype"||strip(put(_n_,best.)), strip(put(type,tfmt.)));
	call symput("vlabel"||strip(put(_n_,best.)), strip(label));

	if last then call symput("nVars",strip(put(_n_,best.)));
run;


%do j = 1 %to &nVars.;
	title1 "Analysis of &&vlabel&j (Variable=%upcase(&&vname&j.)) ";
	%if %upcase(&&vtype&j)=1 %then %do;
		
		%PUT Condition was Met on &&vtype&j;
		
		proc means data=&lib..&ds.;
		
		
			var &vname;
		run;
	%end;
	
	%else %if %upcase(&&vtype&j)=2 %then %do;
	
		proc freq data=&lib..&ds.;
			tables &vname;
		run;
	%end;
%end;

%mend;
	
	
%codebook(lib=out,ds=adsl)	;

 

Log:

 
 1          OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 SYMBOLGEN:  Macro variable _SASWSTEMP_ resolves to /folders/myfolders/.sasstudio/.images/ab67408b-9085-47c6-aa5d-fd1ebb399085
 SYMBOLGEN:  Some characters in the above value which were subject to macro quoting have been unquoted for printing.
 SYMBOLGEN:  Macro variable GRAPHINIT resolves to  
 NOTE: ODS statements in the SAS Studio environment may disable some output features.
 73         
 74         *************
 75         project: BIOS 511
 76         
 77         Name: lab-13-task-2-710929473-Task1.sas
 78         
 79         Author: Alexandre Lockhart
 80         
 81         Date: 2019-11-26
 82         
 83         Purpose:  Lab 13 Task 2 of BIOS 511.   Implement codebook macro for ADSL and DM datasets.
 84         *************;
 85         
 86         
 87         
 88         
 89         
 90         %let root = /folders/myfolders/BIOS511;
 91         %let lab = Lab-13;
 92         %let dataPath = &root/Lab/&lab./Data;
 SYMBOLGEN:  Macro variable ROOT resolves to /folders/myfolders/BIOS511
 SYMBOLGEN:  Macro variable LAB resolves to Lab-13
 93         %let macroPath = &root/Lab/&lab./Macros;
 SYMBOLGEN:  Macro variable ROOT resolves to /folders/myfolders/BIOS511
 SYMBOLGEN:  Macro variable LAB resolves to Lab-13
 94         
 95         
 96         libname echo "&root./data/echo" access=read;
 SYMBOLGEN:  Macro variable ROOT resolves to /folders/myfolders/BIOS511
 NOTE: Libref ECHO was successfully assigned as follows: 
       Engine:        V9 
       Physical Name: /folders/myfolders/BIOS511/data/echo
 97         libname out "&dataPath." access=read;
 SYMBOLGEN:  Macro variable DATAPATH resolves to /folders/myfolders/BIOS511/Lab/Lab-13/Data
 NOTE: Libref OUT was successfully assigned as follows: 
       Engine:        V9 
       Physical Name: /folders/myfolders/BIOS511/Lab/Lab-13/Data
 SYMBOLGEN:  Macro variable ROOT resolves to /folders/myfolders/BIOS511
 SYMBOLGEN:  Macro variable LAB resolves to Lab-13
 98         
 99         
 100        %let outpath=&root/Lab/&lab./Output;
 101        
 102        
 103        *ods pdf file='&outpath./tst.pdf';
 104        options mprint symbolgen mlogic;
 105        %macro codebook(lib=,ds=);
 106        
 107        %if &lib=BLANK|&ds=BLANK %then %do;
 108        %put &=lib;
 109        %put &=ds;
 110        %abort;
 111        %end;
 112        
 113        
 114        ods select variables;
 115        proc contents data=&lib..&ds. out=_contents_ ; run;
 116        proc format; value tfmt 1='NUM' 2='CHAR'; run;
 117        
 118        data _null_;
 119        set _contents_ end=last;
 120        
 121        call symput("vname"||strip(put(_n_,best.)), strip(name));
 122        call symput("vtype"||strip(put(_n_,best.)), strip(put(type,tfmt.)));
 123        call symput("vlabel"||strip(put(_n_,best.)), strip(label));
 124        
 125        if last then call symput("nVars",strip(put(_n_,best.)));
 126        run;
 127        
 128        
 129        %do j = 1 %to &nVars.;
 130        title1 "Analysis of &&vlabel&j (Variable=%upcase(&&vname&j.)) ";
 131        %if %upcase(&&vtype&j)=1 %then %do;
 132        
 133        %PUT Condition was Met on &&vtype&j;
 134        
 135        proc means data=&lib..&ds.;
 136        
 137        
 138        var &vname;
 139        run;
 140        %end;
 141        
 142        %else %if %upcase(&&vtype&j)=2 %then %do;
 143        
 144        proc freq data=&lib..&ds.;
 145        tables &vname;
 146        run;
 147        %end;
 148        %end;
 149        
 150        %mend;
 151        
 152        
 153        %codebook(lib=out,ds=adsl);
 MLOGIC(CODEBOOK):  Beginning execution.
 MLOGIC(CODEBOOK):  Parameter LIB has value out
 MLOGIC(CODEBOOK):  Parameter DS has value adsl
 SYMBOLGEN:  Macro variable LIB resolves to out
 SYMBOLGEN:  Macro variable DS resolves to adsl
 MLOGIC(CODEBOOK):  %IF condition &lib=BLANK|&ds=BLANK is FALSE
 MPRINT(CODEBOOK):   ods select variables;
 SYMBOLGEN:  Macro variable LIB resolves to out
 SYMBOLGEN:  Macro variable DS resolves to adsl
 MPRINT(CODEBOOK):   proc contents data=out.adsl out=_contents_ ;
 MPRINT(CODEBOOK):   run;
 
 
 Output Added:
 -------------
 Name:       Variables
 Label:      Variables
 Template:   Base.Contents.Variables
 Path:       Contents.DataSet.Variables
 -------------
 NOTE: The data set WORK._CONTENTS_ has 13 observations and 41 variables.
 NOTE: PROCEDURE CONTENTS used (Total process time):
       real time           0.11 seconds
       cpu time            0.10 seconds
       
 
 MPRINT(CODEBOOK):   proc format;
 MPRINT(CODEBOOK):   value tfmt 1='NUM' 2='CHAR';
 NOTE: Format TFMT is already on the library WORK.FORMATS.
 NOTE: Format TFMT has been output.
 MPRINT(CODEBOOK):   run;
 NOTE: PROCEDURE FORMAT used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 MPRINT(CODEBOOK):   data _null_;
 MPRINT(CODEBOOK):   set _contents_ end=last;
 MPRINT(CODEBOOK):   call symput("vname"||strip(put(_n_,best.)), strip(name));
 MPRINT(CODEBOOK):   call symput("vtype"||strip(put(_n_,best.)), strip(put(type,tfmt.)));
 MPRINT(CODEBOOK):   call symput("vlabel"||strip(put(_n_,best.)), strip(label));
 MPRINT(CODEBOOK):   if last then call symput("nVars",strip(put(_n_,best.)));
 MPRINT(CODEBOOK):   run;
 
 NOTE: There were 13 observations read from the data set WORK._CONTENTS_.
 NOTE: DATA statement used (Total process time):
       real time           0.00 seconds
       cpu time            0.00 seconds
       
 
 SYMBOLGEN:  Macro variable NVARS resolves to 13
 MLOGIC(CODEBOOK):  %DO loop beginning; index variable J; start value is 1; stop value is 13; by value is 1.  
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VLABEL1 resolves to Age
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VNAME1 resolves to AGE
 MPRINT(CODEBOOK):   title1 "Analysis of Age (Variable=AGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VTYPE1 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 1
 SYMBOLGEN:  Macro variable VTYPE1 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 2; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VLABEL2 resolves to Description of Planned Arm
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VNAME2 resolves to ARM
 MPRINT(CODEBOOK):   title1 "Analysis of Description of Planned Arm (Variable=ARM) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VTYPE2 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 2
 SYMBOLGEN:  Macro variable VTYPE2 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 3; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VLABEL3 resolves to Planned Arm Code
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VNAME3 resolves to ARMCD
 MPRINT(CODEBOOK):   title1 "Analysis of Planned Arm Code (Variable=ARMCD) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VTYPE3 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 3
 SYMBOLGEN:  Macro variable VTYPE3 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 4; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VLABEL4 resolves to Country
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VNAME4 resolves to COUNTRY
 MPRINT(CODEBOOK):   title1 "Analysis of Country (Variable=COUNTRY) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VTYPE4 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 4
 SYMBOLGEN:  Macro variable VTYPE4 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 5; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VLABEL5 resolves to Race
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VNAME5 resolves to RACE
 MPRINT(CODEBOOK):   title1 "Analysis of Race (Variable=RACE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VTYPE5 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 5
 SYMBOLGEN:  Macro variable VTYPE5 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 6; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VLABEL6 resolves to Age categorization
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VNAME6 resolves to agecat
 MPRINT(CODEBOOK):   title1 "Analysis of Age categorization (Variable=AGECAT) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VTYPE6 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 6
 SYMBOLGEN:  Macro variable VTYPE6 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 7; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VLABEL7 resolves to Change in diastolic bp
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VNAME7 resolves to diabp_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in diastolic bp (Variable=DIABP_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VTYPE7 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 7
 SYMBOLGEN:  Macro variable VTYPE7 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 8; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VLABEL8 resolves to Change in heart rate
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VNAME8 resolves to hr_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in heart rate (Variable=HR_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VTYPE8 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 8
 SYMBOLGEN:  Macro variable VTYPE8 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 9; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VLABEL9 resolves to Numeric Result/Finding in Standard Units
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VNAME9 resolves to pcmax
 MPRINT(CODEBOOK):   title1 "Analysis of Numeric Result/Finding in Standard Units (Variable=PCMAX) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VTYPE9 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 9
 SYMBOLGEN:  Macro variable VTYPE9 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 10; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VLABEL10 resolves to Highest Value
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VNAME10 resolves to pcmax2
 MPRINT(CODEBOOK):   title1 "Analysis of Highest Value (Variable=PCMAX2) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VTYPE10 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 10
 SYMBOLGEN:  Macro variable VTYPE10 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 11; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VLABEL11 resolves to Change in systolic bp
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VNAME11 resolves to sysbp_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in systolic bp (Variable=SYSBP_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VTYPE11 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 11
 SYMBOLGEN:  Macro variable VTYPE11 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 12; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VLABEL12 resolves to Unique Subject Identifier
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VNAME12 resolves to usubjid
 MPRINT(CODEBOOK):   title1 "Analysis of Unique Subject Identifier (Variable=USUBJID) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VTYPE12 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 12
 SYMBOLGEN:  Macro variable VTYPE12 resolves to CHAR
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 13; loop will iterate again.
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VLABEL13 resolves to Change in weight
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VNAME13 resolves to wgt_change
 MPRINT(CODEBOOK):   title1 "Analysis of Change in weight (Variable=WGT_CHANGE) ";
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VTYPE13 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 SYMBOLGEN:  Macro variable J resolves to 13
 SYMBOLGEN:  Macro variable VTYPE13 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=2 is FALSE
 MLOGIC(CODEBOOK):  %DO loop index variable J is now 14; loop will not iterate again.
 MLOGIC(CODEBOOK):  Ending execution.
 154        
 155        
 156        
 157        
 158        /*
 159        %include "macroPath.\codebook.sas"
 160        
 161        ods pdf file="&outputPath.\ADSL-CODEBOOK-PID.pdf" style=sasweb;
 162        %codebook(lib=out,ds=adsl,maxVal=4);
 163        ods pdf close;
 164        
 165        ods pdf file="&outputPath.\ADSL-CODEBOOK-DM.pdf" styke=sasweb;
 166        %codebook(lib=echo,ds=dm,maxVal=4);
 167        ods pdf close;
 168        
 169        
 170        
 171        */
 172        
 173        
 174        
 175        OPTIONS NONOTES NOSTIMER NOSOURCE NOSYNTAXCHECK;
 SYMBOLGEN:  Macro variable GRAPHTERM resolves to  
 187        

 

Reeza
Super User
 SYMBOLGEN:  Macro variable VTYPE7 resolves to NUM
 MLOGIC(CODEBOOK):  %IF condition %upcase(&&vtype&j)=1 is FALSE
 SYMBOLGEN:  && resolves to &.
 

Your conversion didn't work. Make sure to test each step when you make a change. Changing too many things at once makes things complicated.

 

remainmack
Calcite | Level 5

Thank you everyone. I backed up and my output appears to be okay.  I tried to add one feature to my proc freqs to finish. I am adding a parameter for the maximum number of unique values for a character variable for if the number of unique values for the variable is less than or equal to the parameter, a frequency analysis is included in the macro presenting data for all unique values of the variable in question. If the number of unique values is large than the parameter, then only the parameter most frequent values should be displayed. The default value of the parameter I am setting to 5 for now. 

 

The issue I am having is 1) I don't know how to set both sides of the condition (greater or less than) for my third parameter and 2) set my default number within the macro (trying to set to 5).

 

%macro codebook(lib=,ds=,maxVal=);

%if &lib= BLANK | &ds = BLANK %then %do;
	%put &=lib;
	%put &=ds;
	%abort;
%end;


ods select variables;
proc contents data=&lib..&ds. out=_contents_  ; run;
proc format; 

value tfmt 

1 = 'NUM' 
2 = 'CHAR'; 

run;




data _null_;
	set _contents_ end=last;
	
	call symput('vname'||strip(put(_n_,best.)), strip(name));
	call symput('vtype'||strip(put(_n_,best.)), strip(put(type,tfmt.)));
	call symput('vlabel'||strip(put(_n_,best.)), strip(label));

	if last then call symput('nVars',strip(put(_n_,best.)));
run;






%do j = 1 %to &nVars.;
	title1 "Analysis of &&vlabel&j (Variable=%upcase(&&vname&j.)) ";
	%if &&vtype&j=NUM %then %do;
		
		%PUT Condition was Met on &&vtype&j;
		
		proc means data=&lib..&ds.;
		
		
			var &&vname&j.;
		run;
	%end;
	
	%else %if &&vtype&j=CHAR %then %do;
	
		proc freq data=&lib..&ds.;
			tables &&vname&j./out=freqtab;
		run;
		
		%let printALL=YES;
		
		
		
		data _null_;
			
			set freqtab;
			
			if _n_ > &maxVal. then
				call symput('printAll','NO');
			run;
	%end;
%end;

%mend;
	
%codebook(lib=out,ds=adsl,maxVal=4)	;
	
Tom
Super User Tom
Super User

Not a big fan of generating dozens (hundreds) of macro variables, but if you must why not just use PROC SQL to do it?

Why do you care whether the values of VTYPExxx is coded as 1 or NUM?  Just right the code to use the value it has.

%macro codebook(lib=,ds=);
%local nvars j ;
 
%if 0=%length(&lib) or 0=%length(&ds) %then %do;
	%put ERROR: Please provide both LIB and DS.  &=lib &=ds ;
%end;
%else %do;

ods select variables;
title1 "Variables for &lib..&ds";
proc contents data=&lib..&ds. out=_contents_ ; 
run;

proc sql noprint ;
  select name,type,coalesce(label,name)
    into :vname1-,:vtype1-,:vlabel1-
    from _contents_
    order by name
  ;
%let nvars=&sqlobs;
quit;

  %do j = 1 %to &nVars.;
title1 "Analysis of &&vlabel&j (Variable=%upcase(&&vname&j.)) ";
  	%if %upcase(&&vtype&j)=1 %then %do;
proc means data=&lib..&ds.;
	var &&vname&j.;
run;
  	%end;
  	%else  %do;
proc freq data=&lib..&ds.;
	tables &&vname&j.;
run;
  	%end;
  %end;
%end;
%mend codebook;

And let's try it.

%codebook(lib=sashelp,ds=class(keep=age sex));

.image.png

 

remainmack
Calcite | Level 5

Thanks for the suggestion, Tom. You're right: I could use sql to do it.  But it didn't solve my recent question. Since my latest question is pertaining to dealing with that third parameter, I will post a new thread to avoid confusion.

Reeza
Super User

https://communities.sas.com/t5/SAS-Communities-Library/PROC-DOC-III-Self-generating-Codebooks-Using-...

 

There's a lot of these out there already, perhaps finding an example that's close to what you want will help. 

https://www.lexjansen.com/search/searchresults.php?q=codebook

 

You may also want to look at the NLEVELS option within PROC FREQ statement which tells you the number of levels so you don't have to figure it out yourself. 

 

 

 

 

ErikLund_Jensen
Rhodochrosite | Level 12

hI @remainmack 

 

It is much easier to drop the macro altogether and do the same in a data step with Call Execute:

** NOTE: New code with stop statement ***

 

data have;
	a = 1; b = 3; c = 'ole'; 
run;

%let lib = work;
%let ds = have;

data _null_; set have;
	array num{*} _numeric_;
	array char{*} _character_;
	length thisvar $32;
	do i = 1 to dim(num);
		call vname(num{i},thisvar);
		call execute ("proc means data=&lib..&ds; var " || trim(thisvar) || '; run;');
	end;
	do j = 1 to dim(char);
		call vname(char{j},thisvar);
		call execute ("proc freq data=&lib..&ds; tables " || trim(thisvar) || '; run;');
	end;
	stop;
run;

Regards

Erik

 

 

ErikLund_Jensen
Rhodochrosite | Level 12

Hi @remainmack 

 

Sorry, I missed  a very important stop statement. The code is updated.

SAS Innovate 2025: Call for Content

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!

Submit your idea!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 12 replies
  • 3221 views
  • 2 likes
  • 5 in conversation