Using Context Sensitive Pop-Menus to Enter Values in a SAS

Download Report

Transcript Using Context Sensitive Pop-Menus to Enter Values in a SAS

Using Context Sensitive Menus
to Enter Values in a SAS/AF
Data Table Object
Richard A. DeVenezia
Context Menus

Widespread use




Windows
Office 97
SAS
Right mouse click

Present menu of
choices applicable to
task at hand
Sample Application
Enter data for a fitness study
 Add columns to SASUSER.FITNESS

– SMOKES
– DIET
– EXERCISE

Hands off data entry using context menus
SASUSER.FITNESS

SMOKES
 Number

DIET
 Diet

of packs smoked a day
followed at time of fitness measures
EXERCISE
 Comma
separated list of types of regular
exercises performed
SAS/AF Front End
Default Context Menu
Desired Context Menus

SMOKES
 List

DIET
 List

of numbers
of diets
EXERCISE
 List
of exercises
– Add or remove an exercise from subject’s list of
exercises
Desired Context Menus
Smokes
Diet
Exercise
Control of Context Menu

Max Packs
 Restricts

Exercises
 Restricts

number of packs listed in menu
number of comma separated exercises
Life Style Choices
 Control
data set
Life Style Choices

Data set of choices
to be shown in
context menus

Aspect value
matches name of
column in table
being edited
SAS/AF Makes It Happen
Frame class
 Data Table class
 Methods
 SCL Lists
 WPOPUP command

– Causes the pop up menus for a window to appear
– By default under Windows (and UNIX), this
command is associated with the right mouse button
Making the FRAME entry

Issue command
 BUILD
 This

SASUSER.NESUG99.MAIN.FRAME
creates an instance of a Frame class
Make a Data Table
click in Frame and select Make
or Issue command RM MAKE
 Right
 Create
an instance of a Data Table class named
FITNESS
Data Table: Command Processing

Right click on the Data Table
 Select
Object Attributes
– Left click on Command Processing...

Note the Popmenu Processing setting
 Use

_POPUP_ method
This is the ‘hook’ for installing the
popmenu, I.e. the context menu
FRAME: Core Concepts

Override Data Table _POPUP_ method
 This

becomes the WPOPUP event handler
Attach column handler specifiers to the
Data Table widget for the event handler to
use
FRAME: Sample

Override _POPUP_

call send (_frame_,
'_get_widget_',’FITNESS',tabid);
call send (tabid,
'_SET_INSTANCE_METHOD_','_POPUP_',
'SASUSER.NESUG99.CONTEXT.SCL',
'POPUPCEL');
FRAME: Sample

Attach column handler specifiers

rc = setnitemn (tabid, _smokes,
'RMB_LIST_FOR_SMOKES');
rc = setnitemn (tabid, _diet,
'RMB_LIST_FOR_DIET');
rc = setnitemc (tabid,'CONTEXT:EXERCISE',
'RMB_LIST_FOR_EXERCISE');

Both _smokes and _diet are SCL lists made
and populated in INIT, and repopulated by
user front end actions
Column Handler: Core Concept
A column handler specifier is a named item
attached to the Data Table widget
 Item name is
RMB_LIST_FOR_<column_name>


Item value is
– numeric: event handler assumes it is an SCL list id
– character: event handler assumes it is an SCL
method defined with statement:
method _self_ 8 row 8 column_name $32 _pop 8;
WPOPUP Event Handler

Method statement must conform to:
method plist sel 8;

plist
 the

sel
 the

SCL list that is about to be popmenu’ed
number of the item selected
Neither argument is used in the sample
application
Event Handler Sample

Catalog entry
SASUSER.NESUG99.CONTEXT.SCL

Has this method statement in it
POPUPCEL:
method plist sel 8;
Event Handler Concepts
Obtain cell coordinates where popup
occurred
 Obtain column name cell is in
 Check for column handler specifier
 Set active cell to popup cell
 Get column type
 Dispatch column handler

 Special
case for row 0
Event Handler Details

Obtain cell coordinates


_poprow = makelist();
_popcol = makelist();
call send (_self_,
‘_GET_POPUP_CELL_’,
_poprow, _popcol);
Obtain column name

col = getnitemn (_popcol,1);
call send (_self_,
‘_GET_DISPLAYED_COLUMN_NAME_’,
col, colname);
Event Handler Details

Check for column handler specifier


Set active cell


handlerItem = namedItem (_self_,
‘RMB_LIST_FOR_’ || colname);
call send (_self_,
‘_SET_ACTIVE_CELL_’,
_poprow, _popcol);
Get column type

call send (_self_,
‘_GET_COLUMN_ATTRIBUTE_’,
colname, ‘TYPE’, coltype);
Event Handler Details

Dispatch column handler


select itemType (_self_,handlerItem);
when (‘N’) link popItemN;
when (‘C’) link popItemC;
otherwise;
end;
Special case (not done in Sample)
 If
row=0 call code specific to a column header
 Sorting, formatting, column order, etc...
Column Handler Dispatchers

popItemN:
 Column

handler specifier is an SCL list
popItemC:
 Column
handler specifier is a method name
– Term context method used in later slides

Both dispatchers link to setCell:
 Places
value selected from context menu into
the popup cell or selected region
popItemN: Details
Simplest case
 All work was done in the FRAME
 Just popmenu the SCL list


_pop = getItemN(_self_, handlerItem);
if listlen (_pop) > 0 then do;
 choice = popmenu (_pop); 
if choice > 0 then link setCell;
end;
popItemC: Concepts

Dispatching is easy
 Writing
the method being dispatched is harder
Get the context method
 Call the context method

 No
error checking, bad method calls cause error
messages in the Log
 Must conform to
method _self_ 8 row 8 column_name $32 _pop 8;
popItemC: Concepts

_pop is an SCL list made by dispatcher and
passed to context method
 Upon
return
– If _pop is not empty

dispatcher will present menu and insert values into table
– If _pop is empty or invalid (deleted)


dispatcher will do nothing and exit normally
Context method can perform any actions
 Value
insertion not required
popItemC: Details

Get the context method and call it


popcol_method = getitemc
(_self_, handlerItem);
_pop = makelist (); pophold = _pop;
call method (scan (popcol_method,1,':'),
scan (popcol_method,2,':'),
_self_, row, colname, _pop);
if listlen (_pop) > 0 then do;
 choice = popmenu (_pop); 
if choice > 0 then link setCell;
end;

Context method ignores _pop to prevent
setCell
popItemC: Concepts

Why let method prevent setCell ?
 Value
inserted into table not applicable to
region select
 Additional flexibility
– requires more work
– method should use techniques similar to setCell: if it
wants to insert a value into the table
– method is called with arguments sufficient enough
to do setCell: like processing
setCell:
Long winded grunt code due to filling
selected region feature
 Methods used:

 _GET_SELECTIONS_
 _GET_DATASET_ATTRIBUTES_
 _LOCK_ROW_
/ _UNLOCK_ROW_
 _CLEAR_SELECT_
 _SET_ACTIVE_CELL_
 _SET_COLUMN_TEXT_ / _VALUE_
Context Method Statement

Must conform to
method _self_ 8 row 8 column_name $32 _pop 8;

_SELF_
 Data

ROW & COLUMN_NAME
 Data

Table widget id
Table cell where popup event occurred
_POP
 SCL list
to be populated
Exercise Context Method

Catalog entry
SASUSER.NESUG99.CONTEXT.SCL

Has this method statement in it
EXERCISE: method
_self_ 8 row 8 column_name $32
_pop 8
;

Term Exercise method used in later slides
Exercise Method Overview

End result
 Exercise
value is a comma separated list of M
values taken from the N choice values in
LIFESTYL data set where
aspect=‘EXERCISE’

Coupled with a FRAME object
 Input
field nExer in the FRAME controls M
Exercise Method Concepts
Get FRAME Data Table resides in
 Get nExer value from FRAME
 Get current value of Exercise
 Check if more exercises allowed
 Make a context menu that shows remove
before any exercise already present, and add
before any exercise not present
 Update value in table accordingly

Exercise Method Details

Get nExer value from FRAME Data Table
is in


Get current value of Exercise


call send (getnitemn (_self_, '_FRAME_'),
'_GET_NUM_VAR_', 'NEXER', nExer);
call send (_self_, '_GET_COLUMN_TEXT_',
column_name, exercise);
Check if more exercises allowed

allow_more=(scan(exercise,nExer, ',') = '');
Exercise Method Details

Make a context menu to show values with
remove and add prefaces
 Involved
bit of code using two SCL lists
 List1 are exercises currently in value
 List2 are exercises obtained from lookup
– open LIFESTYL(WHERE=(ASPECT="EXERCISE"))
– populate using LVARLEVEL function
Exercise Method Details

Update value in table

call send (_self_, '_LOCK_ROW_', row);
call send (_self_, '_SET_COLUMN_TEXT_',
column_name, exercise);
call send (_self_, '_UNLOCK_ROW_');
Conclusion
Dare to dream up intuitive interfaces
 SAS/AF is superbly capable
 You can only maximize your AF investment
with deep understanding

Richard A. DeVenezia
Sample application available upon request
[email protected]
SAS and SAS/AF are registered trademarks or trademarks of SAS Institute Inc, in the USA and other countries.  indicates USA registration.