Skip to main Content

Building Dynamic Menus with Proc PMENU

This tip demonstrates how to build pull-down menus for SAS/AF, SAS/FSP or even the data step windowing environments. The inspiration for this tip was a question raised on Twitter, with a need to create the menus dynamically.  A link to download the full program can be found at the end of this tip.

Here, we demonstrate a technique for adding items to a File menu, that represent a list of Most Recently Used files (MRU).

Firstly, we assign a libref that is used to store a SAS catalog that contains an entry for the PMENU definition.  The library is assigned to the current SAS folder:

libname app ".";

  

Next, lets create some sample data that represents the list of MRU files as you might see on a Windows platform.

data mru;
infile datalines dlm=',';
input recent_fullname $ :char32. recent_alias $ :char32.;
datalines;
C:\My Project\My Program1.sas,My Program1.sas
C:\My Project\My Program2.sas,My Program2.sas
C:\My Project\My Program3.sas,My Program3.sas
C:\My Project\My Program4.sas,My Program4.sas
C:\My Project\My Program5.sas,My Program5.sas
run;

  

The approach is to build a pair of macro variables for each file, one containing the full filename and one with a user friendly name - which we will display on the menu later. 

Here we use Proc SQL to create the macro variables.  The first SELECT statement counts the number of MRU items.  To alter the maximum number MRU items displayed on the File menu, change the number 4 below.  If  more than 9 are desired tweak the format length too, or for all records just use &sqlobs rather than creating the mru_item_count macro variable.

The second SELECT statement creates one pair of macro variables for each row in the input data set. 

proc sql noprint;
select min(count(*),4) format=1. into :mru_item_count
from mru;

  
%put NOTE: Found &mru_item_count. items.;

  
  * Build a name-value paired list of macro variables;
select distinct recent_fullname, recent_alias
into: mru_recent_fullname1-:mru_recent_fullname&mru_item_count,
: mru_recent_alias1-:mru_recent_alias&mru_item_count.
from mru;

  
* Debug;
%put _user_;
quit;

  

The %PUT statement above will display the list of user created SAS macro variables in the log window.

Now we define the macro that will loop over the name-value list of macro variables, constructing the menus and commands.  A little knowledge of Proc PMENU syntax is required here.  Full documentation can be found in your help system, however here we are creating one menu item per file and one command per file.  On selecting a menu item, a command is issued that moves to an Enhanced Editor Window, then opens the selected file.

%macro build_mru;
menu file;
%do i = 1 %to &mru_item_count.;
item "&&mru_recent_alias&i." selection=cmd&i. ;
%end;
  %do i = 1 %to &mru_item_count.;
selection cmd&i. "wpgm;fileopen ""&&mru_recent_fullname&i.""";
%end;
%mend build_mru; 

  

The next line turns on a macro a debugging option causing the generated SAS statements to be shown in the log window.

options mprint;

  

Finally, build a File pull-down menu and (dynamically) its MRU items. Again, some appreciation of the PMENU syntax is required to fully understand this next step; however - the PMENU definition is now stored in a catalog called MENUS, in the APP library.  There is a container menu called MAIN.  It has one item on it called "File".  When that is clicked on, the MRU items, added by the macro call, appear underneath.

proc pmenu cat=app.menus;
menu main;
item 'File' menu=file mnemonic='F';
%build_mru
run;
quit;

  

Finally, we test the example by using a simple data step window (generally there are far better techniques for creating interfaces in SAS today - however this simple method works nicely as an example).

Two menus will be shown in the SAS Display Manager "File", created by the code above, in addition to the default "Window" menu:

data _null_;
window testwindow menu=app.menus.main
#2 @10 'Hello PMENU World';
display testwindow;
run;

  

The code can be downloaded by clicking here.  This was created in response to a question posted to twitter.com/dgshannon, on SAS 9.2 for Windows.