As alluded to before, the KBBlock object is the most important type of object in Rekall. First, however, note that a KBBlock never exists in its own right: in a form it will appear as a KBFormblock (or KBFormsubblock, see below) or in a report as a KBReportblock (or KBReportsubblock, see below). However, we will use KBBlock as shorthand.
Unless the KBBlock is the outermost, it itself holds a value from the enclosing KBBlock, in exactly the same way as a KBField or any other control which displays data. The difference compared to these controls is that the value is not actually displayed. Instead, the value is used when forming the SQL query that retrieves data for controls which are enclosed in the nested KBBlock. In the form-subform examples earlier, the inner block (ie., the subform) was set to retrieve ClientID from the outer block (the Parent field setting), and link this to ClientID in its own query (the Child field setting). Hence, the query generated for the inner block would be like:
select ... from Orders where Orders.ClientID = value |
where value is the ClientID value from the Clients table which is shown in the outer KBBlock. As you step through records in the outer block, the query for the nested block is repeated to get the correct set of orders for the client now being displayed. Confused? Fair enough. I have to think about it each time I revisit the code. But it works! If you bring up the query log window (via the scroll-and-Q toolbar icon, you can see the text of the queries as they are executed.
A block can display a single row of data at a time, or it can display more than one; one of the properties of a block is the number that should be displayed. A special case is if this is set to zero, in which case the number of rows is calculated to just fit the space available.
There is one further subtlety. Normally, in a form-subform arrangement, the outer block (the form) would show exactly one row of data (such as a client), and the inner block (the subform) would show multiple rows (such as orders for the client). However, in Rekall, the outer block can, if you wish, display more than one row. In this case the inner block displays rows of data related to the current row in the other block - if you think about it, the outer-one-row situation is just a special case of this, where the current outer row is always the one displayed.
Why would you want to do this? Suppose you have a form which shows several rows of clients information, but you would also like to display a notes memo control for just the client corresponding to the row which is current at any given time (because this field will take up quite a lot of space). You would add a nested block which also retrieves data from the clients table, with the inner and outer blocks linked on the client identifier; this means the select query for the inner block is
select Notes from Client where Client.ClientID = value |
with value being the current client identifier from the outer block. The inner block need only display a single row. This is shown in the screenshot below. Note that the outer block has a container whose Y-mode is set to stretch, and the inner block has Y-mode set to float; this means the form height can be changed by the user with sensible results.