DesignBais Tip – Changing MV Header Behavior

A user in the DesignBais forum asked if there was a way to use a Header Process to put data at the bottom of an MV grid, rather than changing the value of the currently selected MV value. This was a fun and challenging problem, and I have a solution. I don’t know if it’s the right one. But it works!

DesignBais is just itching to do what it’s been told to do, which is to insert selected data into the current MV row. To get back control we need to cancel what DesignBais wants to do and substitute what we want to do.

We’re going to use a bit of Indirection again here. Rather than calling directly to the selection process, call to a program, then have that call the selection process. My example below is called BUILD.MV. Save and compile/catalog the program. Then set Hdr Process to BUILD.MV, and set the Parameter for that call to "A0". This is a just a custom flag so that the program knows what it’s expected to do, the value doesn’t matter, just be consistent.

Rather than using the standard code template and figuring out which event is being fired, I’m writing this all into one program:

SUB BUILD.MV
INCLUDE DBI DBI.COMMON
IF DBSTORE(51) = "" THEN ; * first time here
  IF PROCESS.PARAMETER = "A0" THEN ; * only authorized forms allowed
    DBSTORE(51) = PROCESS.PARAMETER ; * save flag from calling form
    PROCESS.STACK = "DBCLIENT_SEL1" ; * launch the selection process
    RETURN
  END
  * do something else or just exit
RETURN
END
* apparently we’ve set the DBSTORE flag
IF DBVALUE = "" THEN ; * oops, no data
  DBSTORE(51) = "" ; *reset flag
  RETURN ; * exit without modifying MV grid
END
IF DBSTORE(51) = "A0" THEN ; * we know what we want to do here
  DBMVCOUNT = DCOUNT(DBRECORD<11>,@VM) + 1 ; * new last line
* use your own custom code here to manipulate your data
  DBRECORD<11,DBMVCOUNT> := DBVALUE ; * contains selected ID
  DBRECORD<14,DBMVCOUNT> := 123 ; * build the MV data…
  DBVALUE = "" ; * reset so DesignBais doesn’t update grid!
  DBSTORE(51) = "" ; * reset for the next execution
  RETURN
END
* other flags from other forms will take different actions
RETURN

I randomly selected DBSTORE(51) as a place to hold my flag. When we first come from the form we save the process parameter and then re-route the request to run the selection process. Why? Because when the selection is done, we use the Process After Selected field/event to call this program again. Note this pattern: set a flag, go do something, then come back and operate on the results.

So now we’re back in this program. DBSTORE has a value that tells us we should have some data that we need to work on. We recognize the A0 code so we know what we need to do. The first thing is to reset DBMVCOUNT to the last new value in the MV set. Then we manually manipulate the data if required. If you have a column that processes a Read operation from DesignBais, then just set that column. Otherwise in my example I build two attributes, 11 and 14. You can do any manipulation of the MV data here that you like.

To clean up, reset DBVALUE. This makes DesignBais think the user exited without selecting data, so it will take no further action. Finally, reset the DBSTORE flag so that it doesn’t accidentally execute any of this code if the program somehow gets executed again for some different purpose.

Rather than some code like A0, you could use the form name and Process.EventSource as the data you’re holding in DBSTORE. And rather than hard coding data manipulation, you could CALL or CALL@ to a separate program that builds the MV grid. I’m just showing you the first draft solution that worked I’ll leave "elegance" to you.

Leave a Reply