DATA Step, Macro, Functions and more

SAS Macro Issue with Data values

Reply
Super Contributor
Posts: 268

SAS Macro Issue with Data values

Hi,

I am having issues with a rather complex SAS code. The SAS macro create_page generates code in Javascript which is then run by the stored process facility using the _webout option. The SAS code works fine for most data values but seems to trip up for data values which have special characters. The original SAS code is here -

put '<tr><td><b>Population:</b></td>';
put '<td>';
put '<select name="POPULATION">'; 
%let i = 1;
put "<option value='(none)'>Select One</option>";
%if %symexist(POPULATION_LIST) %then %do;
%do %while(%qscan(&POPULATION_LIST,&i,-) ne);
%let n&i = %scan(&POPULATION_LIST,&i,-);
%if %str(&&n&i)= %str(&POPULATION) %then %do;
put %unquote(%str(%'<option value="&&n&i" selected>&&n&i</option>%'));
  %end;
      %else %do;
       put %unquote(%str(%'<option value="&&n&i">&&n&i</option>%'));
     %end;

%let i = %eval(&i+1);
%end;
%end;
put '</SELECT>';
put '</td></tr>';

The java script being created is here -

</SELECT></td></tr><tr><td><b>Population:</b></td><td><select name="POPULATION"><option value='(none)'>Select One</option>

   </SELECT></td></tr>

Depending on the number of records extracted from the database, the list of values for this javascript drop down keep increasing. For some values which have special characters the process is breaking though.

MPRINT(CREATE_PAGE):   put '</SELECT>';
MPRINT(CREATE_PAGE):   put '</td></tr>';
MPRINT(CREATE_PAGE):   put '<tr><td><b>Population:</b></td>';
MPRINT(CREATE_PAGE):   put '<td>';
MPRINT(CREATE_PAGE):   put '<select name="POPULATION">';
MPRINT(CREATE_PAGE):   put "<option value='(none)'>Select One</option>";
SYMBOLGEN:  Macro variable POPULATION_LIST resolves to Boeing All Others-Boeing ForAsgmt (exPat)-Boeing ForAsgmt SP/DP (exPat)-Boeing ILHE-Boeing USA EE-Boeing USA SP/DP
SYMBOLGEN:  Macro variable I resolves to 1
SYMBOLGEN:  Macro variable I resolves to 1
SYMBOLGEN:  Macro variable POPULATION_LIST resolves to Boeing All Others-Boeing ForAsgmt (exPat)-Boeing ForAsgmt SP/DP (exPat)-Boeing ILHE-Boeing USA EE-Boeing USA SP/DP
SYMBOLGEN:  Macro variable I resolves to 1
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable I resolves to 1
SYMBOLGEN:  Macro variable N1 resolves to Boeing All Others
SYMBOLGEN:  Macro variable POPULATION resolves to (none)
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable I resolves to 1
SYMBOLGEN:  Macro variable N1 resolves to Boeing All Others
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable I resolves to 1
SYMBOLGEN:  Macro variable N1 resolves to Boeing All Others
MPRINT(CREATE_PAGE):   put '<option value="Boeing All Others">Boeing All Others</option>';
SYMBOLGEN:  Macro variable I resolves to 1
SYMBOLGEN:  Macro variable POPULATION_LIST resolves to Boeing All Others-Boeing ForAsgmt (exPat)-Boeing ForAsgmt SP/DP (exPat)-Boeing ILHE-Boeing USA EE-Boeing USA SP/DP
SYMBOLGEN:  Macro variable I resolves to 2
SYMBOLGEN:  Macro variable I resolves to 2
SYMBOLGEN:  Macro variable POPULATION_LIST resolves to Boeing All Others-Boeing ForAsgmt (exPat)-Boeing ForAsgmt SP/DP (exPat)-Boeing ILHE-Boeing USA EE-Boeing USA SP/DP
SYMBOLGEN:  Macro variable I resolves to 2
SYMBOLGEN:  && resolves to &.
SYMBOLGEN:  Macro variable I resolves to 2
                                                                                          The SAS System

SYMBOLGEN:  Macro variable N2 resolves to Boeing ForAsgmt (exPat)
ERROR: Required operator not found in expression: &&n&i= &POPULATION
SYMBOLGEN:  Macro variable POPULATION resolves to (none)
ERROR: The macro CREATE_PAGE will stop executing.

The original piece of code is using the %str function to mask the () characters. So, my question is what am I missing here? Or what I should try to ensure that piece of macro logic works regardless of database values?

This is a production issue which means a few sleepless nights for me. Any help will be appreciated.

Thanks,

saspert

Regular Contributor
Posts: 241

Re: SAS Macro Issue with Data values

It gets easier if you separate out the macro part from the non-macro part. Here is one way.

   %*-- args pass by names, not by values --*;
   %macro options(_list=, _pop=);
      %if ^%symexist(&_list) %then %return;

      %local i value qvalue dash selected pop;
      %let pop = %qsysfunc(strip(%superq(&_pop)));
      %let dash = %str(-);

      %let i = 1;
      %let value = %qsysfunc(strip(%qscan(%superq(&_list), &i, &dash)));
      %do %while (&value^=);
         %if &value = &pop %then %let selected = selected;
         %else %let selected =;
         %let value = %qsysfunc(htmlencode(&value));
         %let qvalue = %qsysfunc(quote(&value));

         %*;%unquote(
            put "<option value="&qvalue" &selected>&value</option>";
         )

         %let i = %eval(&i + 1);
         %let value = %qsysfunc(strip(%qscan(%superq(&_list), &i, &dash)));
      %end;
   %mend  options;


   %*-- check --*;
   %let population_list = Boeing All Others-
      Boeing ForAsgmt (exPat)-Boeing ForAsgmt SP/DP (exPat)
      -Boeing ILHE-Boeing USA EE-Boeing USA SP/DP;
   %let population = Boeing ILHE;

   data _null_;
      put '<tr><th>Population:</th>';
      put '<td><select name="population">';
      put '<option value="(none)">Select One</option>';

      %options(_list=population_list, _pop=population)

      put '</select></td>';
      put '</tr>';
   run;
   %*-- on log
   <tr><th>Population:</th>
   <td><select name="population">
   <option value="(none)">Select One</option>
   <option value="Boeing All Others" >Boeing All Others</option>
   <option value="Boeing ForAsgmt (exPat)" >Boeing ForAsgmt (exPat)</option>
   <option value="Boeing ForAsgmt SP/DP (exPat)" >Boeing ForAsgmt SP/DP (exPat)</option>
   <option value="Boeing ILHE" selected>Boeing ILHE</option>
   <option value="Boeing USA EE" >Boeing USA EE</option>
   <option value="Boeing USA SP/DP" >Boeing USA SP/DP</option>
   </select></td>
   </tr>
   --*;

Super Contributor
Posts: 268

Re: SAS Macro Issue with Data values

Hi,

Appreciate your solution to decode. Since I was short on time, I tried a couple of alternative macro qoutation functions and %bquote seem to work. So I replaced %str (in red above in my code) to %bquote and it seemed to work for now.

I do want to spend some time on your code and understand your logic. It seems impressive to go through the code and split out the required javascript from that.

Regards,

saspert.

Super User
Super User
Posts: 6,498

Re: SAS Macro Issue with Data values

Why are you processing the text with macro logic instead of using DATA step statements instead? You will not have any macro quoting issues then.

Ask a Question
Discussion stats
  • 3 replies
  • 489 views
  • 3 likes
  • 3 in conversation