Initializing Dynamics and Macro Variables

The main difference between dynamics and macro variables is that they are initialized differently.
For dynamics, use the DYNAMIC statement with PROC SGRENDER. Values for dynamics that resolve to column names or strings should be quoted. Numeric values should not be quoted:
proc sgrender data=financial template=timeseries;
  dynamic yvar="inflation" ylabel="Inflation Rate";
For macro variables, use the current symbol table (local or global) to look up the macro variable values at runtime:
%let locate=inside;
%let trans=.3;
proc sgrender data=financial template=timeseries;
  dynamic yvar="inflation" ylabel="Inflation Rate";
No initialization is needed for automatic macro variables like the system date and time value SYSDATE.
It is the responsibility of the person or process that initializes the dynamics or macro variables to ensure that the expected value type and value that is supplied is appropriate for the substitution context. If necessary, you can use conditional logic to evaluate the supplied values of dynamics or macro variables. Conditional logic is discussed in Using Conditional Logic and Expressions.
If a dynamic is used to supply a GTL option with a specific value and the supplied value is not valid or it is not initialized, then the option specification is ignored and the option's default value is used. For example, the HALIGN= option accepts the values RIGHT, CENTER, and LEFT. If the dynamic variable ALIGN is defined and then the template code specifies HALIGN=ALIGN, the ALIGN dynamic must be initialized with one of the values RIGHT, CENTER, or LEFT. If it is initialized with another value, TOP for example, the HALIGN= specification in the template is ignored, the default setting for HALIGN= is used, and you might see a warning in the SAS log.
If a dynamic is used to supply a required argument such as a column name, and the name is misspelled or not provided, then a warning is issued and that plot statement drops out of the final graph. A graph will still be produced, but it might be a blank graph, or it might show the results of all statements except those that are in error.
The following example shows how to create a generalized template that can be used to show the distribution of any numeric variable. The dynamic named VAR must be set, but the other dynamics are optional: BINS (sets the number of histogram bins) and FOOTNOTE. In the example, the DYNAMIC and MVAR variables are highlighted to emphasize where they are being used.
proc template;
 define statgraph distribution;
  mvar SYSDATE ;
    entrytitle "Distribution of " VAR " with Normal Density Curve";
    entryfootnote halign=left FOOTNOTE halign=right "Created " SYSDATE ;
    layout lattice / rowweights=(.9 .1) columndatarange=union
        columnaxis / display=(ticks tickvalues);
      layout overlay / yaxisopts=(offsetmin=.04 griddisplay=auto_on);
        histogram VAR / scale=percent nbins=BINS ;
        densityplot VAR / normal( ) name="Normal";
        fringeplot VAR / datatransparency=.7;
      boxplot y=VAR / orient=horizontal primary=true boxwidth=.9;
The following execution of the template initializes the dynamic variables VAR and FOOTNOTE, but it does not initialize BIN:
proc sgrender data=sashelp.heart template=distribution;
  dynamic var="Cholesterol"
  footnote="From Framingham Heart Study (SASHELP.HEART)";
In this case, the template option bins=BINS drops out because the BINS dynamic has not been initialized.
BINS Dynamic Drops Out
This next execution of the template assigns values to each of the dynamics VAR, BIN, and FOOTNOTE, using different values from the previous example:
proc sgrender template=distribution;
  dynamic var="Invoice" bins=20 footnote="From SASHELP.CARS";
BINS Dynamic is Initialized
The next example shows a simplified version of the previous graph, this time adding an inset. The inset statistics are computed external to the template and passed into the template at runtime, using dynamics and macro variables. For more information on coding insets in graphs, see Adding Insets to a Graph.
proc template;
 define statgraph inset;
  dynamic VAR FOOTNOTE; 
  mvar N MEAN STD;
   entrytitle "Distribution of " VAR;
   entryfootnote halign=left FOOTNOTE;
   layout overlay / yaxisopts=(griddisplay=on);
    histogram VAR / scale=percent;
    layout gridded / columns=2
        autoalign=(topleft topright) border=true
        opaque=true backgroundcolor=GraphWalls:color;
      entry halign=left "N"; entry  halign=left N ;
      entry halign=left "Mean"; entry halign=left MEAN ;
      entry halign=left "Std Dev"; entry halign=left STD ;
We will now define a macro that can pass values to this template. For a given numeric variable, the macro computes the number of observations, the mean, and the standard deviation, storing these statistics in macro variables N, MEAN, and STD. The macro variables are available to the SGRENDER step when the macro executes. Here is the definition for the macro, which we will name HIST:
%macro hist(dsn,numvar,footnote);
  /* these macro variables are declared in the template */
  %local N MEAN STD;
  proc sql noprint;
    select  put(n(&numvar),12. -L),
            put(mean(&numvar),12.2 -L),
            put(std(&numvar),12.2 -L) into :N, :MEAN, :STD
    from &dsn;
  /* remove trailing blanks */
  %let N=&N; %let MEAN=&MEAN; %let STD=&STD;

  proc sgrender data=&dsn template=inset;
    dynamic VAR="&numvar" FOOTNOTE="&footnote"; 
Here are results of two executions of the macro with different input data. Notice the placement of the inset might change on based on the amount of space that is available and the setting for the AUTOALIGN= option.
%hist(sashelp.heart, cholesterol, From SASHELP.HEART)
Initializing Dynamics for SASHELP.HEART Data
%hist(, Weight, From SASHELP.CARS)
Initializing Dynamics for SASHELP.CARS Data
If you are familiar with the macro facility, you can create macros that validate the parameters before executing the template. It is also possible to validate the parameters within the compiled template, using the conditional logic syntax of GTL. For more information, see Using Conditional Logic and Expressions.
GTL supports user-defined computed expressions within compiled templates. This means that the inset statistics could have been computed directly within template, eliminating the need to pass them in with dynamics or macro variables. An example of how to do this is also discussed in Using Conditional Logic and Expressions.
For developers who would like to create a library of reusable templates, see the discussion on creating shared templates in Creating Shared Templates.