PMENU Procedure

Example 3: Creating a Dialog Box to Search Multiple Variables

Features:

DIALOG statement : SAS macro invocation

ITEM statement : DIALOG= option

RADIOBOX statement option: DEFAULT=

RBUTTON statement option: SUBSTITUTE=

Other features:

SAS macro invocation

Details

This example shows how to modify the menu bar in an FSEDIT session to enable a search for one value across multiple variables. The example creates customized menus to use in an FSEDIT session. The menu structure is the same as in the preceding example, except for the WHERE dialog box.
When selected, the menu item invokes a macro. The user input becomes values for macro parameters. The macro generates a WHERE command that expands to include all the variables needed for the search.
Tasks include these:
  • associating customized menus with an FSEDIT session
  • searching multiple variables with a WHERE clause
  • extending PROC PMENU functionality with a SAS macro

Program

libname proclib
'SAS-data-library';
proc pmenu catalog=proclib.menucat;
   menu project;
      item 'File' menu=f;
      item 'Edit' menu=e;
      item 'Scroll' menu=s;
      item 'Subset' menu=sub;
      item 'Help' menu=h;
      menu f;
         item 'Goback' selection=g;
         item 'Save';
         selection g 'end';
      menu e;
         item 'Cancel';
         item 'Add';
      menu s;
         item 'Next Obs' selection=n;
         item 'Prev Obs' selection=p;
         item 'Top';
         item 'Bottom';
         selection n 'forward';
         selection p 'backward';
      menu sub;
         item 'Where' dialog=d1;
         item 'Where Clear';
      menu h;
         item 'Keys';
         item 'About this application' selection=hlp;
         selection hlp 'sethelp proclib.menucat.staffhlp.help;help';
       dialog d1 '%%wbuild(%1,%2,@1,%3)';
          text #1 @1 'Choose a region:';
          radiobox default=1;
             rbutton #3 @5 'Northeast' substitute='NE';
             rbutton #4 @5 'Northwest' substitute='NW';
             rbutton #5 @5 'Southeast' substitute='SE';
             rbutton #6 @5 'Southwest' substitute='SW';
          text #8 @1 'Choose a contaminant:';
          radiobox default=1;
             rbutton #10 @5  'Pollutant A' substitute='pol_a,2';
             rbutton #11 @5  'Pollutant B' substitute='pol_b,4';
          text #13 @1 'Enter Value for Search:';
          text #13 @25 len=6;
          text #15 @1 'Choose a comparison criterion:';
          radiobox default=1;
             rbutton #16 @5 'Greater Than or Equal To'
                             substitute='GE';
             rbutton #17 @5 'Less Than or Equal To'
                             substitute='LE';
             rbutton #18 @5 'Equal To' substitute='EQ';
quit;

Program Description

Declare the PROCLIB library. The PROCLIB library is used to store menu definitions.
libname proclib
'SAS-data-library';
Specify the catalog for storing menu definitions. Menu definitions will be stored in the PROCLIB.MENUCAT catalog.
proc pmenu catalog=proclib.menucat;
Specify the name of the catalog entry. The MENU statement specifies STAFF as the name of the catalog entry. The menus are stored in the catalog entry PROCLIB.MENUCAT.PROJECT.PMENU.
   menu project;
Design the menu bar. The ITEM statements specify the items for the menu bar. The value of the MENU= option is used in a subsequent MENU statement.
      item 'File' menu=f;
      item 'Edit' menu=e;
      item 'Scroll' menu=s;
      item 'Subset' menu=sub;
      item 'Help' menu=h;
Design the File menu. This group of statements defines the selections under File on the menu bar. The first ITEM statement specifies Goback as the first selection under File. The value of the SELECTION= option corresponds to the subsequent SELECTION statement, which specifies END as the command that is issued for that selection. The second ITEM statement specifies that the SAVE command is issued for that selection.
      menu f;
         item 'Goback' selection=g;
         item 'Save';
         selection g 'end';
Design the Edit menu. The ITEM statements define the selections under Edit on the menu bar.
      menu e;
         item 'Cancel';
         item 'Add';
Design the Scroll menu. This group of statements defines the selections under Scroll on the menu bar. If the quoted string in the ITEM statement is not a valid command, then the SELECTION= option corresponds to a subsequent SELECTION statement, which specifies a valid command.
      menu s;
         item 'Next Obs' selection=n;
         item 'Prev Obs' selection=p;
         item 'Top';
         item 'Bottom';
         selection n 'forward';
         selection p 'backward';
Design the Subset menu. This group of statements defines the selections under Subset on the menu bar. The DIALOG= option names a dialog box that is defined in a subsequent DIALOG statement.
      menu sub;
         item 'Where' dialog=d1;
         item 'Where Clear';
Design the Help menu. This group of statements defines the selections under Help on the menu bar. The SETHELP command specifies a HELP entry that contains user-written information for this FSEDIT application. The semicolon that appears after the HELP entry name enables the HELP command to be included in the string. The HELP command invokes the HELP entry.
      menu h;
         item 'Keys';
         item 'About this application' selection=hlp;
         selection hlp 'sethelp proclib.menucat.staffhlp.help;help';
Design the dialog box. WBUILD is a SAS macro. The double percent sign that precedes WBUILD is necessary to prevent PROC PMENU from expecting a field number to follow. The field numbers %1, %2, and %3 equate to the values that the user specified with the radio buttons. The field number @1 equates to the search value that the user enters.
       dialog d1 '%%wbuild(%1,%2,@1,%3)';
Add a radio button for region selection. The TEXT statement specifies text for the dialog box that appears on line 1 and begins in column 1. The RADIOBOX statement specifies that a radio button will appear in the dialog box. DEFAULT= specifies that the first radio button (Northeast) will be selected by default. The RBUTTON statements specify the mutually exclusive choices for the radio buttons: Northeast, Northwest, Southeast, or Southwest. SUBSTITUTE= gives the value that is substituted for the %1 in the DIALOG statement above if that radio button is selected.
          text #1 @1 'Choose a region:';
          radiobox default=1;
             rbutton #3 @5 'Northeast' substitute='NE';
             rbutton #4 @5 'Northwest' substitute='NW';
             rbutton #5 @5 'Southeast' substitute='SE';
             rbutton #6 @5 'Southwest' substitute='SW';
Add a radio button for pollutant selection. The TEXT statement specifies text for the dialog box that appears on line 8 (#8) and begins in column 1 (@1). The RADIOBOX statement specifies that a radio button will appear in the dialog box. DEFAULT= specifies that the first radio button (Pollutant A) will be selected by default. The RBUTTON statements specify the mutually exclusive choices for the radio buttons: Pollutant A or Pollutant B. SUBSTITUTE= gives the value that is substituted for the %2 in the preceding DIALOG statement if that radio button is selected.
          text #8 @1 'Choose a contaminant:';
          radiobox default=1;
             rbutton #10 @5  'Pollutant A' substitute='pol_a,2';
             rbutton #11 @5  'Pollutant B' substitute='pol_b,4';
Add an input field. The first TEXT statement specifies text for the dialog box that appears on line 13 and begins in column 1. The second TEXT statement specifies an input field that is 6 bytes long that appears on line 13 and begins in column 25. The value that the user enters in the field is substituted for the @1 in the preceding DIALOG statement.
          text #13 @1 'Enter Value for Search:';
          text #13 @25 len=6;
Add a radio button for comparison operator selection. The TEXT statement specifies text for the dialog box that appears on line 15 and begins in column 1. The RADIOBOX statement specifies that a radio button will appear in the dialog box. DEFAULT= specifies that the first radio button (Greater Than or Equal To) will be selected by default. The RBUTTON statements specify the mutually exclusive choices for the radio buttons. SUBSTITUTE= gives the value that is substituted for the %3 in the preceding DIALOG statement if that radio button is selected.
          text #15 @1 'Choose a comparison criterion:';
          radiobox default=1;
             rbutton #16 @5 'Greater Than or Equal To'
                             substitute='GE';
             rbutton #17 @5 'Less Than or Equal To'
                             substitute='LE';
             rbutton #18 @5 'Equal To' substitute='EQ';
quit;
The following dialog box appears when the user selects Subset and then Where.
Where Dialog Box

Details

Associating a Menu Bar with an FSEDIT Session

The SAS data set PROCLIB.LAKES has data about several lakes. Two pollutants, pollutant A and pollutant B, were tested at each lake. Tests were conducted for pollutant A twice at each lake, and the results are recorded in the variables POL_A1 and POL_A2. Tests were conducted for pollutant B four times at each lake, and the results are recorded in the variables POL_B1 - POL_B4. Each lake is located in one of four regions. The following output lists the contents of PROCLIB.LAKES:

                                 PROCLIB.LAKES                                 1

region    lake         pol_a1    pol_a2    pol_b1    pol_b2    pol_b3    pol_b4

  NE      Carr          0.24      0.99      0.95      0.36      0.44      0.67
  NE      Duraleigh     0.34      0.01      0.48      0.58      0.12      0.56
  NE      Charlie       0.40      0.48      0.29      0.56      0.52      0.95
  NE      Farmer        0.60      0.65      0.25      0.20      0.30      0.64
  NW      Canyon        0.63      0.44      0.20      0.98      0.19      0.01
  NW      Morris        0.85      0.95      0.80      0.67      0.32      0.81
  NW      Golf          0.69      0.37      0.08      0.72      0.71      0.32
  NW      Falls         0.01      0.02      0.59      0.58      0.67      0.02
  SE      Pleasant      0.16      0.96      0.71      0.35      0.35      0.48
  SE      Juliette      0.82      0.35      0.09      0.03      0.59      0.90
  SE      Massey        1.01      0.77      0.45      0.32      0.55      0.66
  SE      Delta         0.84      1.05      0.90      0.09      0.64      0.03
  SW      Alumni        0.45      0.32      0.45      0.44      0.55      0.12
  SW      New Dam       0.80      0.70      0.31      0.98      1.00      0.22
  SW      Border        0.51      0.04      0.55      0.35      0.45      0.78
  SW      Red           0.22      0.09      0.02      0.10      0.32     
0.01
The PROCLIB.LAKES DATA step creates PROCLIB.LAKES.
The following statements initiate a PROC FSEDIT session for PROCLIB.LAKES:
proc fsedit data=proclib.lakes screen=proclib.lakes;
run;
To associate the customized menu bar menu with the FSEDIT session, do any one of the following:
  • enter a SETPMENU command on the command line. The command for this example is
    setpmenu proclib.menucat.project.pmenu
    Turn on the menus by entering PMENU ON on the command line.
  • enter the SETPMENU command in a Command window.
  • include an SCL program with the FSEDIT session that uses the customized menus and turns on the menus, for example:
    fseinit:
      call execcmd('setpmenu proclib.menucat.project.pmenu;
                    pmenu on;');
    return;
    init:
    return;
    main:
    return;
    term:
    return;

How the WBUILD Macro Works

Consider how you would learn whether any of the lakes in the Southwest region tested for a value of .50 or greater for pollutant A. Without the customized menu item, you would issue the following WHERE command in the FSEDIT window:
where region="SW" and (pol_a1 ge .50 or pol_a2 ge .50);
Using the custom menu item, you would select Southwest, Pollutant A, enter .50 as the value, and choose Greater Than or Equal To as the comparison criterion. Two lakes, New Dam and Border, meet the criteria.
The WBUILD macro uses the four pieces of information from the dialog box to generate a WHERE command:
  • One of the values for region, either NE, NW, SE, or SW, becomes the value of the macro parameter REGION.
  • Either pol_a,2 or pol_b,4 become the values of the PREFIX and NUMVAR macro parameters. The comma is part of the value that is passed to the WBUILD macro and serves to delimit the two parameters, PREFIX and NUMVAR.
  • The value that the user enters for the search becomes the value of the macro parameter VALUE.
  • The operator that the user chooses becomes the value of the macro parameter OPERATOR.
To see how the macro works, again consider the following example, in which you want to know whether any of the lakes in the southwest tested for a value of .50 or greater for pollutant A. The values of the macro parameters would be
REGION
SW
PREFIX
pol_a
NUMVAR
2
VALUE
.50
OPERATOR
GE
The first %IF statement checks to make sure that the user entered a value. If a value has been entered, then the macro begins to generate the WHERE command. First, the macro creates the beginning of the WHERE command:
where region="SW" and (
Next, the %DO loop executes. For pollutant A, it executes twice because NUMVAR=2. In the macro definition, the period in &prefix.&i concatenates pol_a with 1 and with 2. At each iteration of the loop, the macro resolves PREFIX, OPERATOR, and VALUE, and it generates a part of the WHERE command. On the first iteration, it generates pol_a1 GE .50
The %IF statement in the loop checks to determine whether the loop is working on its last iteration. If it is not working, then the macro makes a compound WHERE command by putting an OR between the individual clauses. The next part of the WHERE command becomes OR pol_a2 GE .50
The loop ends after two executions for pollutant A, and the macro generates the end of the WHERE command:
)
Results from the macro are placed on the command line. The following code is the definition of the WBUILD macro. The underlined code shows the parts of the WHERE command that are text strings that the macro does not resolve:
%macro wbuild(region,prefix,numvar,value,operator);
       /* check to see if value is present */
    %if &value ne %then %do;
       where region="&region" AND (
               /* If the values are character,     */
               /* enclose &value in double quotation marks. */
         %do i=1 %to &numvar;
             &prefix.&i &operator &value
                /* if not on last variable,  */
                /* generate 'OR'             */
            %if &i ne &numvar %then %do;
                 OR
            %end;
         %end;
          )
    %end;

%mend wbuild;