Monthly Archives: January 2024

Quickdex in OpenInsight 10

Overview

QUICKDEX.MFS and RIGHTDEX.MFS are programs that provide a quick method to obtain a list of all keys in a table, and both call the subroutine LRDEX.SUB. This stored procedure maintains a sorted list of keys in a special record named %RECORDS%. You can read this list in one operation. For example:

Keys = Xlate(‘MYTABLE’,’%RECORDS%’, ”, ‘X’)

However, there is a cost to maintaining this record. LRDEX.SUB must lock, read, scan, and if needed update the %RECORDS% row every time a row is written or deleted. This creates a potential bottleneck in a busy table. READNEXT operations must scan the result list to remove ‘%RECORDS%’.  The read method must rebuild the %RECORDS% row if it does not exist. The special %RECORDS% row is not compatible with other BFS’s. The LRDEX.SUB program originated with early versions of Advanced Revelation. At that time, storing a list of keys offered a substantial performance benefit. The benefit justified the cost for smallish tables that rarely change. These tables often populate dropdowns for data entry forms, where a quick read of all keys is useful.

When reviewing LRDEX.SUB for OpenInsight 10 we realized it needed revision. The sorting depended on the Arev language sets feature and was incompatible with DICT.MFS, causing crashes.  Rebuilding the %RECORDS% rows was not optimized. We wanted to address these and other issues and improve performance.

Changes

We started by optimizing the %RECORDS% rebuild. We needed to perform a rapid table scan and write a sorted list of keys.  OI10’s RList already provides optimized table scans, so we reused that with V119 to sort the list.  Surprisingly, reading %RECORDS% with and without the new rebuild showed a negligible performance difference!  We realized that storing a list of keys no longer offered much benefit.  We could remove the overhead of maintaining the list without sacrificing performance.  Thus, the revised LRDEX.SUB will perform a table scan when you ask for %RECORDS%. It does not lock or write anything. It still checks for %RECORDS% in a READNEXT. It will delete the record if it finds it. Quickdex.mfs remains best suited to smaller tables. However, it will not fail unexpectedly as a table grows, and it will work with any of the BFS’s.

Sharing data with OpenInsight 9

Note that the OI10 version of LRDEX.SUB is not compatible with the OI 9 version. OI9 requires the %RECORDS% row, OI10 deletes it. For that reason we soft-coded LRDEX.SUB so you can specify which version to use with a configuration setting.  If you need share tables between OI9 and OI10 you must configure OI10 to use the same logic as OI9.  Create a record in the SYSENV table named “RTI_CFG_LRDEX” with “RTI_LRDEX_SUB_9” in the first row.

Summary

OpenInsight 10 offers a simplified Quickdex/Rightdex capability with similar benefits and without the shortcomings of the OI9 version. The simplified version cannot be used on tables shared with OI9. You can configure OI10 to use the OI9 version if needed.

ListBoxes and TreeListBoxes – Checkbox Items

A recent question on the Revelation forum touched on the subject of using checkbox items in LISTBOX and TREELISTBOX controls, and this highlighted the need to document some of the new properties in OpenInsight v10 that support this functionality. In this post we’ll take a look at how you can use these to make adding checkbox items to your controls a simple task.

In previous versions of OpenInsight adding checkboxes to items was done with “smoke and mirrors”, i.e. actual item images were used to represent the checkbox, and the control itself had no concept of a checked state for any of it’s contents. Usually, when the user clicked on the item’s checkbox image, the UPDATE method was used toggle the image from checked to unchecked and vice versa. The checked state would be obtained by looking at the image number using the LIST property. Unfortunately this technique has two main drawbacks:

  • The code for detecting the mouse clicks can be complex, and when added to the image manipulation code itself the intent of the code can become obscured.
  • The images themselves must be maintained manually and updated to match the current Windows visual styling.

In OpenInsight v10 checkbox items are supported “natively” so that the control itself knows which items are “checked” and exposes the properties described below to support this. This results in less coding and a much cleaner program. 

The CHECKBOXES property

This is a simple boolean property that can be set in the Form Designer or at runtime. Setting it to TRUE$ ensures that all items in the control are drawn with a checkbox – this is all that needs to be done to use checkbox items.

The CHECKED property

This property allows you to get or set the checked state of one or more items using an @fm-delimited dynamic array of boolean flags.

// Set the second and fourth items in the LISTBOX to checked, ensure the
// third item is NOT checked.

CheckedItems = Get_Property( CtrlEntID, "CHECKED" )
CheckedItems<2> = TRUE$
CheckedItems<3> = FALSE$
CheckedItems<4> = TRUE$

Call Set_Property_Only( CtrlEntID, "CHECKED", CheckedItems )

The CHECKED property may also be used with the index parameter to get or set the state of a single item at a time:

// Set the ninth item to checked, and uncheck the tenth item
Call Set_Property_Only( CtrlEntID, "CHECKED", TRUE$, 9 )
Call Set_Property_Only( CtrlEntID, "CHECKED", FALSE$, 10 )

The CHECKEDX property

This property is similar to the CHECKED property but only applies to TREELISTBOX controls, and gets or sets the checked state for all items in the fully expanded list. 

CHECKEDLIST property

This property returns an @fm-delimited dynamic array of item indexes that have been checked. This is an optimization property so that you don’t have to iterate over the CHECKED property to find out what has been checked.

AllCheckedItems = Get_Property( CtrlEntID, "CHECKEDLIST" )

CheckedCount = FieldCount( AllCheckedItems, @Fm )
For N = 1 To CheckedCount
 CheckedItemNo = AllCheckedItems<N>
Next

CHECKEDLISTTEXT property

This property is similar to the CHECKEDLIST property except that it returns an @fm-delimited dynamic array of text for the checked items rather than their index.

AllCheckedItemsText = Get_Property( CtrlEntID, "CHECKEDLISTTEXT" )

CheckedCount = FieldCount( AllCheckedItemsText, @Fm )
For N = 1 To CheckedCount
 CheckedItemText = AllCheckedItemsText<N>
Next

Conclusion

So that wraps up this short post on checkbox items – hopefully you’ll find them much easier to use in your v10 applications.

Bonus Trivia

The CHECKED property name is a synonym for the original OpenInsight CHECK property name, and you may use either as it suits you – Here at Revelation we prefer to use CHECKED as it feels more natural. Note that this convention applies to other controls like the CHECKBOX control too.