Chapter Contents

Previous

Next
SAS/AF Software: Class Dictionary

Using Data Forms and Data Tables


Moving Widgets in a Data Form

A data form includes widgets or controls that users work with to input or modify data. For documentation purposes, the terms widget and control can be used interchangeably to refer to the visual components on a data form. Control refers specifically to a visual component that is based on the SAS Component Object Model (SCOM), while widget can be either a legacy visual object (that is, one based on Version 6) as well as the collective term associated with any visual component on a data form.

Widgets can be moved within a page or across pages in a data form. To move a widget within a page, use the pop-up menu or drag and drop operations.

To move a widget across pages in a data form, follow these steps:

  1. Go to the page of the data form where the widget is displayed.

  2. Select the widget.

  3. Select Cut from the pop-up menu for the widget.

  4. Go to the page where you want to paste the widget.

  5. Select Paste to paste the widget on the new page.


Moving Columns in a Data Table

You can rearrange columns in a data table by following these steps:

  1. Select the column or columns by clicking the select mouse button on the column's label and dragging the mouse until all of the columns you want to move are highlighted.

  2. Drag the column or columns onto the column that you want them to follow and release the mouse button.

In some cases, the new location for your dragged column is not currently displayed; it is either to the left or to the right of the displayed columns, and you need to scroll to the new location. You can easily scroll to the new location at the same time that you are dragging a column by simply moving your cursor to the edge of the data table object as you drag the column. This will cause the data table object to "power scroll" to columns that aren't currently visible. When the new location is visible, drop the dragged column onto the column that you want it to follow and release the mouse button.

If you wish to change the display order of the columns in a Data Table and have that order saved then follow these steps:

  1. Assign a DATAFORM entry to the Data Table so that customizations will be saved.

  2. In BUILD mode, move the columns around to obtain the desired display order.

The column order you set in build mode will be used each time the Data Table is displayed.

You can also use SCL to do this at run time by using the _setDisplayedColumns method.


Host Controls

By default, the data table uses host-based controls when its cells are edited. When a user edits a particular cell in a specified column, the host control appears when the cell is set as the active cell. Supported host controls that you can apply to a cell to assist with editing include a text entry control (the default), a spin box control, and a combo box control.


Selecting Cells in a Data Table

Cells in a data table can be selected interactively by a user or programmatically through SCL. A user can single-click a cell to make that cell the current (or active) cell. All keystrokes and other user input are directed to the active cell. If the IN_CELL_CONTROLS attribute is set to 'Y', then a blinking I-beam cursor appears in the active cell. If the IN_CELL_CONTROLS attribute is set to 'N', then the data table distinguishes the active cell with a highlighted border that is referred to as the "active cell indicator." A user can move this indicator using the cursor keys. Users can select or highlight a contiguous range of cells by dragging the mouse over the desired region of cells.

Selecting a row or column highlights all of the cells contained within the row or column. A user can single-click any cell to deselect the area.


Locking Rows in a Data Table

Many actions, such as editing a row, require that you first lock the row in the data table. By default, to lock a row in a data table, double-click the row.

Note:   If host controls are active for a data table and the object label is set to run on a double-click event (that is, either the Lock row on attribute of the Attribute Window's Customize table.../[Setup] setting is set to "Double-click" or the DOUBLE_CLICK attribute of the data table's _setAttributes method is set to 'Y'), the object label may not execute and a row may not be locked until a user makes a third click in the table. The first click that the user makes actually sets focus to the data table, which then requires two additional clicks to run its object label and to lock a row.  [cautionend]

You can change the lock row behavior to respond to a single-click action by changing the Lock Row on attribute in the attributes window's Customize columns.../[Setup] setting to Single-click or by setting the SINGLE_CLICK attribute of the _setAttributes method to 'Y'. The action defaults to single click if you disable the double-click option in the attributes window or if you use the _setAttributes method to set DOUBLE_CLICK to 'N'.


Editing Cells in a Data Table

The default text entry control provides horizontal scrolling and marking regardless of whether the cell is protected. The spin box and combo box each consist of an input field that enables a user to enter a value and a control that enables a user to select a value from a list. You can specify that a cell use either a combo box or spin box for data entry with the _setColumnAttribute model method. For example,

dcl list itemslist={'Red', 'White', 'Blue'};
dcl list spinlist;
dcl num rc;
rc=insertl(spinlist, itemslist, --1, 'ITEMS')
call notify('table', '_setColumnAttribute', 'color', 
             'dataClass', 'SPINBOX');
call notify('table', '_setColumnAttribute', 'color', 
             'dataAttributes', spinlist);
This code specifies that the color column of the table data table use a spinbox control to display the items contained in itemslist.

You can also specify a custom editor that can assist with the data entry for a column value. An editor is accessible from a cell via an ellipsis (...) button that appears in the right side of the cell. For example, you might want to provide access to a color selector for a cell value. When a user selects the ellipsis button in the cell, the color selector dialog box appears.

An editor can be used in combination with either a combo box control or a spin box control. You can define an editor for a column with the _setColumnAttribute model method. For example,

call notify('table', '_setColumnAttribute', 'color', 'editor',
              'sashelp.classes.colorEditor.frame');
This code specifies that the color column of the table data table use the colorEditor.frame entry as an editor. For details and examples, see Data Form and Data Table: _setColumnAttribute.

You can disable host controls by setting the IN_CELL_CONTROLS attribute to 'N' with the data table's _setAttributes method. When host controls are not used, a user can double-click a cell to make it active and to enable cell edit mode if the cell is not protected. Cell edit mode provides editing within a cell where the text cursor is placed on the selected character while the right and left cursor keys move the text cursor rather than moving the active cell indicator. A user terminates cell edit mode by clicking on another cell, tabbing or moving the cursor to another cell, pressing the Enter key, issuing a command, or scrolling. A user can also edit unprotected cells by making them active and entering a character. In this case, the typed character replaces the previous contents of the cell, and the right and left cursor keys are used to move the active cell indicator. This action can be useful when a user must enter a row or column of data.


Resizing Columns in a Data Table

A user can resize the columns in a data table by selecting the appropriate column border. If a column label cell has no displayed borders, a user can still resize the column by placing the cursor along the edge of the cell and dragging to the desired location.

Because cursor tracking is the default condition for a data table, the cursor shape changes as it is moved across a border to indicate that the border can be selected. If you disable column resizing for a data table by setting its RESIZE_COLUMN attribute in the _setAttribute method to 'N', cursor tracking is also automatically disabled.


Making Selections in a Data Table

Data table users can select one or more rows or columns in the table when you have enabled these features. Selection features determine whether multiple selected rows can be noncontiguous, called multiple selections, or contiguous, called an extended selection.

You enable selection features by setting attributes for the table. In addition to determining whether users can make multiple selections, other attributes determine whether users can select a row by clicking on any of its columns or select a row or column by clicking on its label.

Multiple Selections

Multiple selections refers to the ability to select or highlight more than one noncontiguous range of cells. The ability to make multiple selections can be enabled with the table attribute MULTIPLE_SELECTIONS. By default, this attribute is not enabled.

You can make multiple selections by pressing the CTRL key before making any selections and holding it down while selecting a cell or range of cells with a single mouse click. See the _getSelections method for information on retrieving the coordinates of the highlighted (selected) cells. To clear all selections, you can either single click anywhere in the table or press the SHIFT key and hold it down while you single click anywhere in the table.

Extended Selection

Extended selection refers to the ability to select or highlight a range of contiguous cells, extending a selection from the active cell (starting anchor point) to the cell last clicked with the mouse (ending anchor point).

You can make an extended selection by first pressing the SHIFT key and then holding it down while selecting a cell with a single mouse click. To clear all selections, single click anywhere in the table.

Extended selection is useful when the anchor points of your selected range are far apart. Instead of dragging out the entire selection you can select the cell that is the starting anchor point with a single click, scroll the table, then press the SHIFT key and hold it down while you select the cell that is the ending anchor point with a single click.

Row Selection Mode

Row selection mode expands a selection of any cell, except column labels, into a selection of the entire row that contains the selected cell. Row selection mode can be enabled with the table attribute SELECT_ROWS. By default, this attribute is not enabled.

When a data table has both the attributes SELECT_ROWS and MULTIPLE_SELECTIONS, table users can select multiple noncontiguous rows by first pressing the CTRL key and holding it down while selecting a row with a single mouse click. Users can deselect a row by pressing the CTRL key and clicking on the selected row.

Row selection mode is useful for mimicking list box behavior.

Column Selection Mode

Column selection mode expands a selection of any cell, except row labels, into a selection of the entire column that contains the selected cell. Column selection mode can be enabled with the table attribute SELECT_COLUMNS. By default, this attribute is not enabled.

When a data table has both the attributes SELECT_COLUMNS and MULTIPLE_SELECTIONS, table users can select multiple noncontiguous columns by pressing the CTRL key and holding it down while selecting a column with a single mouse click. Users can deselect a column by pressing the CTRL key and clicking on the selected column.

Label Selection Mode

Label selection mode expands the selection of any row or column label into a selection of the entire row or column, respectively. Label selection mode can be enabled with the table attribute SELECT_LABELS. By default, this attribute is not enabled.

When a data table has both the attributes SELECT_LABELS and MULTIPLE_SELECTIONS, users can select multiple noncontiguous rows or columns in the table by pressing the CTRL key and holding it down while selecting a row or column label, respectively, with a single mouse click.

Users can deselect a column or row by pressing the CTRL key and clicking on the selected element.

The SELECT_LABELS table attribute also has three companion table attributes, SELECT_ROW_LABELS, SELECT_COLUMN_LABELS, and SELECT_TITLES. The SELECT_LABELS attribute treats label selections as selections of the corresponding row or column. Alternatively, you can enable this behavior individually for row label cells with SELECT_ROW_LABELS, column label cells with SELECT_COLUMN_LABELS, or title cells with SELECT_TITLE_LABELS. Thus, the SELECT_LABELS table attribute is the equivalent of enabling all three of these companion table attributes. By default, none of these companion table attributes are enabled.


Data Form Layouts

In a Data Form, a layout consists of widgets which allow a user to interact with the data from the specified table. As the developer, you can control how the user enters and views the data by displaying the data using any widget available in a FRAME entry. Layouts can be as simple as a default layout or more complex.

The Data Form allows the flexibility to create any type of layout that your particular application needs using all of the normal FRAME operations, such as, make, move, and resize.

Creating a New (Default) Layout

You can create a new layout in one of several ways:

No matter how you create a new layout, you can add, delete, or modify any of the widgets in the layout at any time to customize the layout to your particular application. When using a Data Form, you can start from a blank layout by hiding all of the columns in the Customize Columns attribute window and then create and arrange the widgets inside the layout as needed. To save your customizations, you must specify a DATAFORM entry.

When creating a new layout, a default set of attributes is used to create the layout. These attributes are controlled using either the Customize Form window or by calling methods on the Data Form. The following is a list of methods that control the appearance of a new (default) layout and are called automatically for you:
_setAttributes _setDataBackgroundColor _setDataClass _setDataColor _setDataFont _setLabelBackgroundColor _setLabelClass _setLabelColor _setLabelFont _setLabelRepresentation
For additional information about any of these methods, refer to the specific method description.

Once a default layout has been created, you can execute the frame and the data widgets inside of the Data Form will display the associated column values for the current row. The default layout has many uses. For example, you can use the default layout as a starting point for the design of your particular layout and customize it to fit your needs. Another example is to use a Data Form to display different tables in run-mode. Each time a new table is displayed in the Data Form a new default layout could be created to represent the columns from the new table.

Widget Representations

When creating a default layout or when dragging a column from the Column window onto a Data Form, a model column is represented by a combination of widgets, known as a widget representation. There are four ways a widget representation can be made and each is described below. In the descriptions, the widget that displays the column name or label is referred to as the label widget, and the widget that displays and accepts a value for the column is referred to as the data widget.

Two widgets (the default)
By default, the Pair label/data widgets option in the Customize Form window is deselected and the GROUP_WIDGETS attribute of the Data Form is set to 'N' (through the _setAttributes method). This representation contains a label widget and a data widget.

Three widgets
To use this representation, select the Pair label/data widgets option in the Customize Form window or call the _setAttributes method setting the GROUP_WIDGETS attribute to 'Y'. Then call the _setLabelRepresentation method passing the argument of 'WIDGET'. This representation contains

One widget with a Region Title
To use this representation, deselect the Pair label/data widgets option in the Customize Form window or call the _setAttributes method setting the GROUP_WIDGETS attribute to 'N'. Then call the _setLabelRepresentation method passing an argument of 'REGTITLE'. This representation contains a data widget that displays the linked column's name or label as the region title.

One widget
To use this representation, deselect the Pair label/data widgets option in the Customize Form window or call the _setAttributes method setting the GROUP_WIDGETS attribute to 'N'. Then call the _setLabelRepresentation method passing an argument of 'NOLABEL'. This representation contains only a data widget and does not contain the column name or label.


Placement of Widget Representations in a Default Layout

When creating a default layout, placement of the widget representations is controlled by the WIDGET_PLACEMENT attribute and the ONE_PAGE attribute (which are set using the _setAttributes method or from the Customize Form Attribute Window).

The WIDGET_PLACEMENT attribute controls how the columns are ordered in the form. A value of Vertical (the default) places the columns from top to bottom and left to right beginning in the top left corner. A value of Horizontal places the columns from left to right and top to bottom beginning in the top left corner. For either Vertical or Horizontal, the columns appear in the order that they are stored in the specified table.

Vertical
The placement of widget representations starts in the upper left corner of the Form Editor region and continue from top to bottom and left to right. When the bottom of the Form Editor region is reached, the placement attempts to continue from the top of the region just to the right of the first column of widget representations. The new column of widget representations will be created if and only if each of the data widgets within a representation is at least partly visible for that column of widgets. If one of the data widget extends off of the right side of the Form Editor region, then a new page will be created and the process of placement is repeated until all of the model column have been represented by widgets. For more information about pages, see Pages.

Horizontal
The placement of widget representations starts in the upper left corner of the Form Editor region and continues from left to right and top to bottom. When a data widget from a representation is completely hidden on the right side of the Form Editor region, a new row of representation begins. If this new row exceeds the bottom boundary of the Form Editor region, then a new page is created and the process of placement is repeated until all of the model columns have been represented by widgets. For more information about pages, see Pages.

The ONE_PAGE attribute controls whether the widget representations are placed on one page of the form or if they will span multiple pages of the form. By default, the value of this attribute is 'N'. If ONE_PAGE is set to 'Y', all widget representations are created on a single page. A new page is not created when the next widget representation would extend beyond the region boundary. Instead, placement of representations continues on the page, just shifted down if the placement order is vertical or to the right of the longest widget if the placement order is horizontal.

Modifying a Layout

After creating a new layout using one of the techniques mentioned above, you can modify that layout using all of the normal FRAME operations. The only limitation is that widgets cannot be moved or copied into or out of a Data Form.

In order to make any customizations to a layout, you must specify a DATAFORM entry in the Data Form Attributes window. Without a DATAFORM entry, your customizations are not available when you execute the frame and are lost when you end from the frame.

The Data Form allows you to create a custom layout quickly and easily without requiring an SCL program. Since the Data Form allows you to represent a model column as a widget, you can take advantage of special features of the widgets. They can perform self-validation of values, enable the user to enter values faster and more reliably, and also enhance the appearance of a layout.


Using the Column Window with Data Forms

The Column window enables you to create a new widget representation for a model's column, associate a model's column with an existing widget, make a computed column, and disassociate a model's column from an existing widget. The Column window can be displayed in one of two ways:

setting an attribute
Select the Display Column Window check box in the Customize Form window. If you choose to display the Column window this way, the Column window will automatically display each time you re-edit this frame.

selecting a pop-up menu item
Select the [Form] menu item from the build-mode pop-up menu. Then select [Display Column Window] from the new pop-up menu. Displaying the Column window this way causes the Data Form to display the Column window immediately but it will not automatically display each time you re-edit this frame.

Only one Column window is present (displayed) at any one time. If you have multiple instances of a Data Form, a Form Editor, or a subclass of a Form Editor, in the same frame or multiple frames, then the Column window displays the columns from the active Data Form along with that Data Form's name in the list box title. The Column window automatically closes when the last frame that contains a data form, a form editor, or a subclass of the form editor, closes.

The Column window enables you to perform several actions on a Data Form by using drag and drop between the Column window and the Data Form. Drag the column from the Column window onto the Data Form. If you have selected Display for Drop Highlighting in the Customize Form window, you will notice that as you drag the column across the Data Form or any of its widgets, the region border changes to the NOTE color to indicate valid drop sites. The drop highlight action and color is controlled from the Customize Form window. Releasing the mouse button while either the Data Form or one of its widget's borders is still the NOTE color, finishes the drag and drop operation and the appropriate action will take place as defined below.

The purpose of the Column window and the linking of columns to widgets is to allow the execution of labels within the model SCL. Each time a widget that is linked to a column is modified, the new value is sent to the model which executes the label corresponding to the name of the column linked to that widget. Without linking columns to widgets, the user could not view or edit the values of the column, nor could the developer add code to the model SCL to perform an action based on a user-entered column value.

Creating a New Widget Representation

To create a new widget representation, drag and drop the column onto the Data Form. This creates a default widget representation based on the current Data Form settings at the location of your mouse pointer.

Linking a Column to a Widget Representation

Instead of creating a default widget representation, you can make any widget inside the Data Form (for example, a radio box or a text entry control) and then associate a model column to that widget. After you create a widget inside of the Data Form, drag a column and drop it on a widget inside the Data Form. By performing this action, the widget is now linked to the model column that was dropped on it. Once linked, the widget displays the current row value of the linked column during run-mode.

Disassociating a Column from a Widget

If you no longer want a model column linked to a widget within the Data Form, drag and drop the Unlink Object item onto the widget in the Data Form. When you release the mouse button, the widget is no longer linked to a model column. In run mode, the widget's value will no longer reflect the current row value of the previously linked model column.

Making a Computed Column Based on an Existing Widget

As mention above, a modified widget inside Data Form does not execute any labeled section in the model SCL unless it is linked to a column, either a real or computed column. The Make Computed Column item allows you to quickly create a computed column which is then automatically linked to the widget it was dropped on.

The name of the computed column will be the name of the widget, unless that name already exists. If the name exists, a number is appended to the name of the widget to create a unique name, for example RADIO1, RADIO2, etc. The name of the computed column now displays in the Column window. When the widget associated with the computed column is modified, the labeled section that you have added to the model SCL, and which corresponds to the name of the computed column, executes.

The type of the computed column is the same as the type for the widget. All computed columns of type character are created with a default length of 8.

Using Commands Instead of Drag and Drop

Each of the actions mentioned in the previous sections can be performed without doing drag and drop operations; instead simply issue a command. Click in an empty section of the Data Form to make it the active object. Use the following command and substitute any of the column names appearing in the Column window for the 'column-name' argument:

   LINK widget-name column-name

To disassociate a column from a widget, issue the following command to the Data Form:

   UNLINK widget-name
See Commands for the Data Form and Data Table.


Data and Label Widgets

The widgets inside a Data Form can be divided into three categories:

Unlinked Widgets
Widgets that are not linked to a model column.

Data Widgets
Widgets that are linked to model columns that allow a user to view and modify the column's value. Data widgets can be created at any time during the construction of a layout by creating new widget representations or transforming an unlinked widget into a data widget by linking a model column to it. By default the class used to create this widget is a text entry control. You can customize this by calling the _setDataClass methods or by using the CLASSES window in the Customize Columns Attribute window.

Label Widgets
Widgets that display either the name or label of a model column. These widgets are internally linked to a model column and can only be created when a new widget representation is made. When a widget representation is made, an internal association is made between the data and label widgets. When the column name or label of the associated data widget changes, that change is reflected in the label widget. By default, the class used to create the label widget is an text label control. You can customize this by calling the _setLabelClass method or through the data form object's attribute window.

When data and label widgets are internally linked, we will use the text of the column name or column label for the text of the label widget instead of any changes to the text you make at the widget level. This also applies if you display the label text as a region title.

The process used by the Data Form to get and set widget attributes depends on whether a legacy class (that is, a Version 6 class) or an SCOM-enabled class (that is, a class defined using a Nashville release of SAS/AF software) is used to represent a column or label. If a legacy class is used, then Data Form calls the following methods to get and set attributes:
_getBackgroundColor _getFormat
_setBackgroundColor _setFormat
_getColor _getInformat
_setColor _setInformat
_getFont _getJustify
_setFont _setJustify

If a method is not defined for a particular class, then that attribute is neither set (if the set method does not exist) nor retrieved (if the get method does not exist).

If an SCOM-based class is used, then the following attributes will be set using the _setAttributeValue method and retrieved using the _getAttributeValue method:
backgroundColor format
textColor (for data controls) informat
labelColor (for label controls) justification
font visible
borderTitleFont (for labels represented as the borderTitle) editable

If the attribute does not exist for a particular SCOM class, then that attribute is neither set nor retrieved.

The attributes that are set for the data and label widgets are controlled by the Data Set Data Model. The model has a set of attribute values that are specific to a particular column; see Data Form and Data Table: _setColumnAttribute for details. If the column linked to a data or label widget has any attribute values specifically set, then those values take precedence over the default attribute values of the Data Form. For example, if a model column has a background color specified, then that color is used instead of the default background color of the Data Form. Otherwise, the Data Form default background color will be used.

The Data Form has default attribute values for the data background and foreground color and font as well as similar settings for the label. The Data Form does not have default settings for the format, informat, or justification attributes, so these attributes are not set unless the model specifies them. The _get methods listed are used to query the attributes from the data or label widgets that you have set in the widget's attribute window.

Note:   The Data Form calls the _setData method to set the widget's value to the value of the linked model column. The Data Form calls the _getData method to retrieve the widget value modified by the user to be stored in the linked model column. These methods are called on all data widgets and are crucial for every data widget. Without the _setData and _getData methods, the data widgets could not display or retrieve changes made to linked model columns. The widgets supplied by SAS/AF software each have a _setData and _getData method defined.

When using a legacy class, the default action of the _getData and _setData methods is based on type of the linked model column. If the linked model column is a character type, then the _setData and _getData methods will call the _setText and _getText methods, respectively. If the linked model column is a numeric type, then the _setData and _getData methods will call the _setValue and _getValue methods, respectively. If you create your own legacy subclass, then you must define a _getData and _setData method or _getText and _setText and _getValue and _setValue methods for the class in order to use that subclass in a Data Form.

When using an SCOM-based class, the default action of the _getData and _setData methods is to process the attribute defined in the object's defaultAttribute attribute. (The defaultAttribute is set to the name of the critical attribute for that class.) The _getData and _setData methods retrieve and set the value of the attribute that is defined by the defaultAttribute attribute. For example, the Text Entry control's defaultAttribute is set to 'text'. So when the _getData and _setData methods are called, they will actually query and set the value of the 'text' attribute. If you create your own SCOM subclass, then you must set the value of the 'defaultAttribute' in order to use that subclass in a Data Form.   [cautionend]


Pages

The contents of a Data Form layout can be split into units called pages. If a model has more columns than will fit on the initial page, other pages are added to display those model columns. You may also decide to add additional pages. Pages allow you to

The Data Form has no limit on the number of pages it can have, nor is there a limit on the number of widgets per page. You are only limited by the resources available on your system. A model column may be linked to a widget on more than one page. But realistically, you should limit the number of pages and widgets per pages since the more pages and widgets per page you have, the longer it takes for the frame to display.

The scroll bars, when active, allow you to scroll within the current page, not between pages or rows. Because the scroll bars scroll within a page, the page can be as large as you like. During the creation of a default layout, the page size is set to the size of the Data Form's region size. This size can be changed by scrolling down or to the right and adding widgets. Any page customizations that are done, are stored in the DATAFORM entry. DATAFORM entries can be used interchangeably between Data Forms; so if a new Data Form is smaller than the original Data Form, the scroll bars will allow you to view the entire contents of the pages.

During build mode, the scroll bars have no boundary, which enables you to place widgets anywhere within a page. During run mode, scroll bars enable you to scroll only to the lowest and right-most widget on the current page.

Adding and Deleting Pages

All Data Form layouts have at least one page. The Data Form allows you to add pages via the build mode pop-up menu items, [Add page after current] and [Add page before current]. After selecting one of these pop-up menu items, you are positioned on the new empty page. After a page is added, all of the pages are renumbered and now are referenced using the new numbers.

You can delete any page from a layout by selecting the build mode pop-up menu item [Delete Page...]. You will be prompted with a dialog box to verify that you want to delete this page. When a page is deleted, all widgets that were contained on that page are deleted also. The page that has been deleted cannot be recovered unless it was previously stored in a DATAFORM entry and you cancel out of the frame. By cancelling out of the frame, you also lose other changes that you have made, so be careful when deleting pages. After a page is deleted, all of the remaining pages are renumbered and now are referenced by using the new numbers. You cannot delete the last page remaining in a layout.

Navigating Between Pages

When a Data Form layout has multiple pages, users can navigate between the pages in order to view and enter the data. There are several ways that this can be done:

Run mode pop-up menu
There are four items on this menu that allow you to navigate between the pages of a layout: First Page, Previous Page, Next Page, and Last Page.

Earmarks
Earmarks make the layout look as though it has a turned down page in either the upper left, the upper right, or both corners. An earmark shown in the upper right corner indicates that there are additional pages. An earmark shown in the upper left corner indicates that there are previous pages. By double clicking on the left earmark, you will be taken to the first page. By double clicking on the right earmark, you will be taken to the last page.

You can control the display of earmarks from the Customize Form window or by calling the _setAttributes method and passing an item of EARMARK with a value of 'Y' or 'N'. The color of the earmarks can also be controlled from the attribute screen or by calling _setEarmarkColor or _setEarmarkOutlineColor.


Pop-up Menus for Data Form

Build-mode Pop-up Menu

When you use the pop-up menu button of your mouse to open the standard build-mode widget pop-up menu, the following two items are added to the build-mode pop-up menu for the form. The other items in the build-mode pop-up are described in the Widget Class.

Form
Displays another pop-up menu that contains items specific to the Data Form. The items in this pop-up are defined as follows:

Display Column Window
opens a separate window with a list box that contains one item for each of the columns currently defined in the model.

Once the Column window is displayed, it remains displayed until one of the following happens:

  • You end the Column window.

  • You end all currently open frames containing a Form Editor, subclass of the Form Editor, or Data Form.

Edit SCL...
opens a source window containing the model's associated SCL. The item is grayed when there is no associated SCL entry specified in the attributes window.

To compile this SCL, issue the COMPILE command from the EDIT SCL window

Compile SCL
compiles the associated model's SCL entry that is specified in the attributes window. The item is grayed when there is no associated SCL.

Refill using attributes...
deletes all widgets and pages in your layout and then refills the Data Form using the current attribute settings from the Attribute Window. This action is a destructive operation, so you are prompted with a dialog box to allow you to cancel the action. Choosing this pop-up item calls the _refillUsingAttributes method of the Data Form passing an argument of 'Y'. This will cause a dialog to appear and prompt you to accept or deny the refill requested.

The Refill using attributes... pop-up item is used when you want to completely start over as if you were creating a new Data Form from scratch along with a default layout.

Turn Column Describe On/Off
displays the name of the column associated with the current data widget. Each time you click a widget associated with a column, the following message displays on the message line:

NOTE: The object 'object-name' is linked to column 'column-name'.

If you click a widget that is not linked to a column, you see the following message displayed on the message line:

NOTE: The object 'object-name' is not linked to any column.

First Page, Previous Page, Next Page, and Last Page
navigate between the currently defined pages. Each of the commands is appropriately grayed, depending on the current page. The page navigation menu items call the _hscroll method with the appropriate parameters for the requested command.

Add Page Before Current and Add Page After Current
insert a blank page before or after the current page. After the page is added, you are positioned on the newly added page.

Delete Page...
removes the current page along with any widgets that are on that page. Before the page is deleted, you are prompted to confirm the requested deletion.


Run-mode Pop-up Menu

You can use your mouse to display a pop-up menu in run mode.

The menu items specific to the Data Form class are defined as follows.

First Row, Previous Row, Next Row, and Last Row
navigate between rows. The First Row and Previous Row menu items are grayed when the data form displays the model's first row. However, the Next and Last Row menu items are never grayed since the model's last row can change dynamically. This enables you to access any new rows that may have been added by an outside source. For example, the data set used by the data form may be on a SHARE server. If the data set is located on a SHARE server, several people may be adding rows; so the Next Row and Last Row items allow you to access these newly added rows.

On a new row, Previous Row and Next Row position the pointer on the row that you were on before the add or copy function, then scrolls backward or forward from there.

The row navigation menu items call the _vscroll method with the appropriate parameters for the requested command.

First Page, Previous Page, Next Page, and Last Page
navigate between the currently defined pages. Each of the commands are appropriately grayed depending on the current page. The page navigation menu items call the _hscroll method with the appropriate parameters for the requested command.

Add Row
runs the _addRow method to add a pending row.

Copy Row
runs the _copyRow method to make a pending copy of the locked row in the table.

Commit New Row
runs the _commitNewRow method to add the pending row to the table if you have added or copied a row.

Delete Row
runs the _deleteRow method to delete the locked row from the table.

Cancel Row Edits
runs the _reread method to reread the current row from the table. If you have added or copied a row, this item cancels the add or copy without saving the pending row on the table. Otherwise, this item cancels any edits that you have made on the locked row.

Help
runs the _columnHelpText method to obtain column help from the model.

Where
runs the _setWhere method to open the interactive WHERE window to specify a WHERE clause for the data.

Where Clear
runs the _setWhere method to clear a WHERE clause for the data.

Record Level Locking/Member Level Locking
runs the _setOpenMode method to alternate between RECORD level locking and MEMBER level locking.

Browse Mode/Edit Mode
runs the _setOpenmode method to alternate between BROWSE mode and EDIT mode.

Override
runs the _override method to override required and error fields. This item enables you to override a column that is in error if option settings allow.


Pop-up Menus for Data Table

Build-mode Pop-up Menu

You can use your mouse to open the standard widget build pop-up menu with the Table item added. The build-mode pop-up menu items specific to the Data Table class are defined as follows:

Edit SCL
opens a source window that contains the model's associated SCL. This item is grayed when there is no associated SCL entry specified in the Data Table attributes window. To compile this SCL issue the COMPILE command from the EDIT SCL window.

Compile SCL
compiles the associated SCL. The item is grayed when there is no associated SCL entry specified in the Data Table Attributes window.

Clear Active Cell
deselects the active cell. This item is grayed when there is no active cell.

Clear Selections
deselects the selected (highlighted) area. This item is grayed when there is no selected area.

Print Setup
displays the host-specific Print Setup window.

Print...
displays the Print window that asks for the necessary information to print the table.

Print Preview...
displays the Print Preview window


Run-mode Pop-up Menu

You can use your mouse to display a pop-up menu in run mode.

The pop-up menu items for the Data Table class are defined as follows:

Clear Active Cell
deselects the active cell. This item is grayed when there is no active cell.

Clear Selections
deselects the selected (highlighted) area. This item is grayed when there is no selected area.

Print Setup
displays the host-specific Print Setup window.

Print...
displays the Print window that asks for the necessary information to print the table.

Print Preview...
displays the Print Preview window

Add Row
runs the _addRow method to add a pending row.

Copy Row
runs the _copyRow method to make a pending copy of the locked row in the table.

Commit New Row
runs the _commitNewRow method to add the pending row to the table if you have added or copied a row.

Delete Row
runs the _deleteRow method to delete the locked row from the table.

Cancel Row Edits
runs the _reread method to reread the current row from the table. If you have added or copied a row, this item cancels the add or copy without saving the pending row on the table. Otherwise, this item cancels any edits that you have made on the locked row.

Help
runs the _columnHelpText method to obtain column help from the model.

Where
runs the _setWhere method to open the interactive WHERE window to specify a WHERE clause for the data.

Where Clear
runs the _setWhere method to clear a WHERE clause for the data.

Browse Mode/Edit Mode
runs the _setOpenmode method to alternate between BROWSE mode and EDIT mode.

Record Level Locking/Member Level Locking
runs the _setOpenMode method to change alternate between RECORD level locking and MEMBER level locking.

Override
runs the _override method to override required and error fields. This item enables you to override a column that is in error if option settings allow.


Units of Measure

Several of the data table and data form methods accept a unit of measure argument. The following table lists the valid units and provides a definition:

Name Description
in inches
cm centimeters
mm millimeters
pt points (72 points equal 1 inch)
pc picas
el l-space (one-third the width of an em)
em the width of a piece of type about as wide as it is tall; usually 1 ln in the x-direction
en n-space (half the width of an em)
ex x-space (the height of the x character)
fg figure width (width of the zero-character)
sp space (width of the space character)
cc width of the widest character in the font
ht height of the tallest character in the font
dp depth of the deepest character in the font
ln line space (1 ht + 1 dp)


Coordinate Lists

All of the data table viewer methods that operate on a particular row, column, or cell have coordinate arguments. These arguments are SCL lists rather than simple numerics in order to deal with multi-dimensional data, that is, nested rows or columns. For the Data Table, these coordinate lists contain a single integer value that represents a row or column in the data table. While the Data Table does not support multidimensional data, see Creating a Multi-dimensional Model Class for Use with the Table Editor for more information on multidimensional data with the Table Editor class.


Commands for the Data Form and Data Table

The following commands can be used by the Data Form and Data Table classes through the _execCmd method. Note that SCL programs should use the method which corresponds to the command; commands are provided for interactive end-user use.

n
scrolls the display to the absolute row referenced by the command. If the n value is greater than the number of rows in the table, the last row in the table displays.

This command returns an error when the access method used to read the table does not support access by absolute row number or when a WHERE clause is in effect.

This command corresponds to the method _gotoAbsoluteRow.

ADD
adds a pending row.

Note:   The ADD command is not valid when browsing a table or if the NOADD option is specified.  [cautionend]

By default, all values in a new row are missing. If an initial value has been stored for the column, the value for a new row contains the initial value for the column.

This command corresponds to the method _addRow.

AUTOSAVE <n>
specifies how frequently the model automatically saves the table. The autosave value determines how many rows must be modified before an automatic save is performed. By default, the table is saved automatically whenever 25 rows have been modified since the last save.

To check the current autosave parameter value, issue the AUTOSAVE command without specifying an n value.

Regardless of the AUTOSAVE parameter value, you can save the table at any time by using the SAVE command.

This command corresponds to methods: _getAutosave, _save, and _setAutosave.

CREATE tablename <REPLACE> <WITH <ALL | varlist>>
creates a new SAS table using some or all of the columns from the current table. The new table duplicates both the structure and contents from the current table. If you issue the CREATE command from an attached viewer, then computed columns are not written to the created table. For more information, see Using the Data Set Model Class

DELETE <row<...row-n>>
deletes one or more rows in the table. The DELETE command is an editing command and is not valid when browsing a table.
CAUTION:
Deletions cannot be recovered. You cannot recover the contents of a deleted row.  [cautionend]

Note:   The DELETE command is not allowed if the NODELETE option is specified.  [cautionend]

In record-level locking, the DELETE command deletes only the currently-locked row in the table. In member-level locking, you can delete one or more rows at a time. To delete a single row, follow the DELETE command with a row number for the row to be deleted. If you are currently editing a row, issuing the DELETE command deletes that row.

To delete multiple rows, follow the DELETE command with a list of row numbers. Separate the row numbers with at least one space. For example, issue the following command to delete rows 5 and 10:

delete 5 10

To delete a range of rows, specify the first and last row numbers of the range, separated by a dash. For example, the following command deletes all rows between 5 and 10, inclusive:

delete 5-10

This command corresponds to the method _deleteRow.

DROP column <...column-n>
excludes one or more columns from the display. See also the _hideColumn method.

DUP <n<row>>
copies the current row to a pending row. In record level locking, you must lock the row you want to copy.

Note:   The DUP command is not valid when browsing a table or if the NOADD option is specified.  [cautionend]

By default, the row is duplicated once. To duplicate the same row again, leave the cursor on the command line and execute the DUP command again. Alternatively, you can follow the DUP command with the desired number of copies. Only the last added row is displayed. The rest of the rows are automatically committed to the table. For example, the dup 3 command duplicates the current row three times, committing the first two rows and leaving the third row in pending mode.

In member level locking, the DUP command copies the specified row n times and adds n-1 rows to the table. The last row is a pending row presented for editing. If no row is specified, the current row is used.

You can select the row to copy by supplying its number as the row argument in the DUP command. To specify the row argument, you must also specify the n argument (the number of times you want the row duplicated). For example, the following command duplicates row 5 two times:

dup 2 5

This command corresponds to the method _copyRow.

FIND find-request
finds the next row (beginning at the current row, or at row 1 if there is no current row) that meets the specified find-request.

This command corresponds to method _findRow.

MOVE start after end
moves a range of columns that start with the start column and end with the end column after the after column.

This command corresponds to the method _moveColumn.

PROTECT ON | OFF column <...column-n>
protects a column or a range of columns.

This command corresponds to the method _protectColumn.

RFIND
finds the next row that meets the find-request that was previously specified on a FIND command.

If the last FIND or RFIND command reached the end of the table without a match, the search begins at the beginning of the table.

This command corresponds to the method _repeatFindRow.

SAVE
stores all changes made to the table since the last time it was saved. See also the AUTOSAVE command.

This command corresponds to the method _save.

SHOW column <column-n>
redisplays dropped or hidden columns.

This command corresponds to the method _unhideColumn.

SORT <ASCENDING | DESCENDING> column </options>
sorts the table by the specified columns, and if no output table is specified, the table is sorted in place. Multiple columns can be specified. The SORT command uses the sorting program that SAS supports for your operating environment. If multiple columns are specified, the table is sorted by those columns in the order in which they are specified.

The SORT command is not valid in browse mode unless you specify an output table.

You can specify sort options to be used for the sort depending on your operating environment. All sort options must be preceded by a slash (/). See the _sort method for a list of sort options.

UPDATE <RECORD | MEMBER>
changes the model from browsing to editing, or changes the control level of the model when already open for editing by specifying the argument.

Note:   The UPDATE command is not allowed when the BRONLY option has been specified  [cautionend]

The table can be opened for editing with a control level of either RECORD or MEMBER. If you do not use either argument, the default control level used is the control level specified in the attribute window of the attached viewer or in the CNTLLEV table option (if one is specified).

When the table is opened for editing, you can use the UPDATE command to change the current control level for the table by specifying the parameter.

The UPDATE command fails if the specified control level would cause a locking conflict. For example, you cannot specify UPDATE MEMBER if the table is open with a control level of RECORD in another window or SAS session.

This command corresponds to the _setOpenmode method.

WHERE <<ALSO>expression> | <UNDO | CLEAR>
imposes one or more sets of conditions that rows in the table must meet in order to be read. Expression is any valid SAS expression involving one or more of the columns in the table. Rows that do not satisfy the specified conditions cannot be edited.

The complete set of conditions is called a temporary WHERE clause. The conditions can be modified or canceled during the lifetime of the object. In contrast, the WHERE option (specified in the ATTRIBUTE window) defines a permanent WHERE clause that cannot be changed or canceled during the FRAME session and which is not affected by WHERE commands.

The WHERE command has several forms:

WHERE expression
applies the conditions specified in the expression as the new temporary WHERE clause, replacing any clause previously in effect.

WHERE ALSO expression
adds the conditions specified in the expression to the existing temporary WHERE clause.

WHERE UNDO
deletes the most recently added set of conditions from the temporary WHERE clause.

WHERE | WHERE CLEAR
cancels the current temporary WHERE clause.

If you use the ADD or DUP command to add a new row and enter values that do not meet the WHERE conditions, the row cannot be edited once you go to a new row.

Note:   The WHERE command cannot be used in conjunction with the _setKey method.  [cautionend]

This command corresponds to the method _setWhere.


Master/Detail Example

This section illustrates how to use data entry objects to synchronize master and detail records stored in separate files. The example details how to

In the example, information about a company's employee and the employee's dependents is displayed using a data form object and a data table object within the data form. Basic information about the employee (such as name, address, gender, and birthdate) along with a photographic image of the employee is stored in a master file. The master file is associated with a data form.

Information about dependents is stored in a separate details file and is associated with the data table. For each employee's record in the master file, the detail file can contain several dependents' records.

Both the master file and the details file have a common column called SSN and are indexed by this column. The SSN column is registered as the Key Column and provides the link between the data form and the data table.

When the data form displays a new employee, the dependents' information displayed in the data table changes accordingly.

Steps to Link the Data Form and the Data Table Objects

Follow these steps to link the data form and data table objects:

  1. Create a data form.

  2. Create a data table within the data form.

  3. To link the data table to the data form, you will need to set the Key Column attribute in the data table. From the Data Table Attributes window, select Customize table.

  4. Within the Customize Table window, select [Setup].

  5. Within the Setup attributes, specify SSN for Key Column.

  6. Select OK twice to return to the frame.

  7. Using the Column window, link the SSN column in the data form to the data table object.


SCL Code Behind the Frame

dcl char(40) title command;
dcl num dfid;
init:                             
   /* Make sure all commands get sent to the frame */
   control always;

   /* Get the ID of the form object and move    */
   /* to first row                              */
   _frame_._getWidget( 'df', dfid ); 
   call send( dfid, '_vscroll', 'max', -1 ); 
   link SETTITLE;                                   
return;              

main:  
   /* Get last command that was issued to see if it was */
   /* a record scrolling command                        */
   command = upcase( word(1) );
   select( command );          
      /* Goto the previous row */
      when ( 'BACKWARD' )           
         call send( dfid, '_vscroll', 'row', -1 );
         call nextcmd();
         
      /* Goto the next row */
      when ( 'FORWARD' )        
         call send( dfid, '_vscroll', 'row', 1 );
         call nextcmd();                          
                                                        
     /* Goto the first row */
      when ( 'TOP' )             
         call send( dfid, '_vscroll', 'max', -1 );
         call nextcmd();
                             
      /* Goto the last row */
      when ( 'BOTTOM' )         
         call send( dfid, '_vscroll', 'max', 1 );
         call nextcmd();
                        
      /*  Otherwise see if the model knows what to do  */
      /*    with the current command.                  */
      otherwise                                          
         if ( command ^= _BLANK_ ) then                  
            call send(dfid, '_execCmd');               
   end;                                                  
                                                         
   link SETTITLE;                                        
return;
                                                   
/*  Update the form's region border to show which  */
/*  record is currently being displayed.           */

SETTITLE: 
   /* Get the current row from the data form */ 
   call send( dfid, '_getCurrentRowNumber', rownbr ); 

   /* Get the maximum number of rows in the table from */
   /* the model, if possible.                          */
   call send( dfid, '_getMaxRow', maxrows );           
   title = 'Employee Demographics: Row ';             
   if ( maxrows ^= -1 ) then                             
      title = title || rownbr || " of " || maxrows;      
   else                                                  
      title = title || rownbr;                           
                                                         
   /* Set the region title */                            
   _frame_._setTitle( title );
return; 

Model SCL for the Data Form Object

 
/* For each row displayed, run the INIT label to: */                              
/* -  Set up the display of the photo             */                              
/* -  Calculate the age                           */                              
                                                                              
INIT:                                                                         
   link EMPNO;                                                                
   link BIRTHDAY;                                                             
return;                                                                       
                                                                              
                                                                              
/* When the column EMPNO is changed, this section sets   */                   
/* up the name of the photo to display and verifies that */                   
/* the photo exists.                                     */                   
EMPNO:                                                                        
   photo = 'dfdtdemo.mastdet.emp' || empno || '.image';                       
   if ( ^cexist( photo ) ) then                                               
      photo = '';                                                             
return;                                                                       
                                                                              
                                                                              
/* When the column BIRTHDAY is changed, AGE is   */                           
/* calculated based on the date of birth         */                           
BIRTHDAY:                                                                     
   age = int( ( today() - birthday ) / 365 );                                 
return;                                                                       
                                                                              
                                                                              
/* Validates the state when the column STATE is changed */                    
STATE:                                                                        
   if state in ( 'AK', 'AL', 'AR', 'AZ', 'CA', 'CO', 'CT', 'DC',              
                 'DE', 'FL', 'GA', 'HI', 'IA', 'ID', 'IL', 'IN',              
                 'KS', 'KY', 'LA', 'MA', 'MD', 'ME', 'MI', 'MN',              
                 'MO', 'MS', 'MT', 'NC', 'ND', 'NE', 'NH', 'NJ',              
                 'NM', 'NV', 'NY', 'OH', 'OK', 'OR', 'PA', 'RI',              
                 'SC', 'SD', 'TN', 'TX', 'UT', 'VA', 'VT', 'WA',              
                 'WI', 'WV', 'WY' ) then                                      
      call send( _self_, '_errorOffColumn_', 'state' );                      
   else                                                                       
   do;                                                                        
      call send( _self_, '_errorOnColumn_', 'state' );                       
      _msg_ = "The entered state is not valid.";                              
   end;                                                                       
return;           


Chapter Contents

Previous

Next

Top of Page

Copyright 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.