When Clarify grids go bad
For the most part, Clarify is pretty easy to customize. Occasionally, you run into Clarify forms that just don’t behave as you would expect. In particular, the “old” Clarify forms, that were all written in C, long before ClearBasic was considered – those can be problematic. ClearLogistics forms are also typically problematic – the initial ClearLogistics development team seemed to have their own way of doing things back then.
We recently assisted a customer with such an issue, and I’m sharing it here so hopefully it may help others in a similar situation.
Customizing the “Select Inventory Parts” form
The requirement at hand was to exclude inventory parts from a certain inventory location when selecting inventory parts – specifically, on Form 519 (Select Inventory Parts).
Here’s the form, showing all inventory parts:
Lets say that we want to exclude those inventory parts that exist in location “12345”.
The traditional approach would be to get the list of records out of the grid (or the contextual object itself), loop through them, remove the ones that match, and repopulate the grid with the updated list of records.
Unfortunately, this yield a Type Mismatch runtime error on this line:
Set partRecord = partsList.ItemByIndex (index)
A little debug code allows us to take a closer look at the the partsList variable:
MsgBox “partsList.ItemType: ” & partsList.ItemType
The ItemType of this list is “long”. We’re expecting a list of records, not longs. And these longs aren’t objids either. I would guess they’re pointers.
No love. Lets try something else.
Another traditional approach
Another way to do this would be to do the query ourselves, excluding the parts we want to exclude, and then simply fill the grid.
The UI doesn’t like this approach at all. Notice that there are the right number of records (2) in the grid, but all of the data is empty:
and double-clicking one of these rows yields this helpful gem:
Ugh. Still no love. So now what?
Approach #1: RemoveByIndex
Perform the same query as the baseline List button. Same filtering, same sorting. Get the list of inventory parts data from the form (from the contextual object). Loop through the list of records that we retrieved from the database. If this is a record to be hidden, then remove it (by index) from the list of data retrieved from the form. Refresh the form data.
One warning here: the query must match exactly – same query, same filtering, same sort order, everything.
|Sub HideInventoryPartsInLocation(locationName As String)
Dim br As New BulkRetrieve
Dim partsList As List
Dim gridList As List
Dim origCount As Integer
Dim index As Integer
Dim obj As Record
Dim recFilter As Record
Dim str_part_number As String
Dim str_mod_level As String
Dim str_part_descr As String
Dim str_part_serial_no As String
Dim str_location_name As String
Dim str_bin_name As String
Dim str_container_id As String
Dim ascDescString As String
Dim ascDesc As Long
Dim sortBy As String’Get the user’s filter criteria
Set recFilter = Cobj_NEW_FILTER.Contents
str_part_number = Trim(recFilter.GetField(“part_number”) )
str_mod_level = Trim(recFilter.GetField(“mod_level”))
str_part_descr = Trim(recFilter.GetField(“part_descr”))
str_part_serial_no = Trim(recFilter.GetField(“part_serial_no”))
str_location_name = Trim(recFilter.GetField(“location_name”))
str_bin_name = Trim(recFilter.GetField(“bin_name”))
str_container_id = Trim(recFilter.GetField(“container_id”))
‘Perform the same query as the List button’s default action
If (str_part_number <> “”) Then
‘Set up the ascending/descending sort order
‘set up the sort by
‘In my testing, baseline Clarify uses location_name
‘Apply the sorting criteria
‘Get the data from the form
‘Loop through the list of records that we retrieved from the database
‘refresh the form data
Now we’ve excluded inventory parts in location “12345”:
Approach #2: A duplicate grid
Here’s another approach that should work as well.
- Setup a 2nd grid that looks like the baseline grid, along with a new LIST button.
- Add a new text box.
- Name: FILTER_BY_OBJID
- Destination COBJ: NEW_FILTER
- Destination field name: objid
- Hide this text box in the non visible part of the form.
- When the user clicks the custom LIST button, perform the same query as the baseline List button (bulkretrieve with the appropriate filters & sorting), and fill the cobj of the 2nd grid.
- On the click action for the 2nd grid:
- Get the objid of the selected row.
- Put this value in the FILTER_BY_OBJID textbox.
- Programmatically Click the baseline LIST button.
- Programmatically Click the first (and only) row in the baseline grid
- Clear the value in the FILTER_BY_OBJID textbox.
- On the double-click action for the 2nd grid:
- Programmatically Double-Click the first (and only) row in the baseline grid
We’ve used this approach in the past, for example on the Dispatch form (form 425).
The code for this is left as an exercise for the reader.
I hope you don’t have to deal with this craziness, but if you do, hopefully you’ll find this post helpful.
Sometimes you have to be a little creative, especially when dealing with forms that were written probably 15 years ago.