Calling the Designer

First all tables have to be declared to List & Label, so that they can be inserted into the project:

LlDbAddTable(hJob, "", ""); // delete existing tables
LlDbAddTable
(hJob, "Orders", "ORDERS");
LlDbAddTable(hJob, "OrderDetails", "ORDER DETAILS");

The first parameter is the usual job handle of the List & Label job. The second parameter is the table ID, which will be returned during printout by LlPrintDbGetCurrentTable(). The third parameter is the display name of the table in the Designer. If you pass NULL or an empty string, the table ID will be used as display name as well.

A special role is assigned to the table name "LLStaticTable". This is reserved and can be used for the insertion of 'static' contents (fixed texts or contents of variables, chart signatures etc.). This type of static table is then available as "Free content" data source and can only be filled with data lines by the user in the Designer. You must react accordingly to the table in your code - a detailed explanation is provided in the Printing subchapter.

In the next step the relations between the tables will be defined. List & Label does not directly differ between different types relationships (n:m, 1:n) – you declare a relation with a relation ID which can be queried at print time:

 

LlDbAddTableRelation(hJob, "OrderDetails", "Orders",
       "Orders2OrderDetails", NULL);

With this command, you have established a relationship between the child table "OrderDetails" and the parent table "Orders". In this case only the ID of the relation was passed and will be displayed in the Designer.

Finally you can pass sort orders for the tables. Again, you define a unique ID for every sort order that can then be queried at print time:

LlDbAddTableSortOrder(hJob, "Orders", "OrderDate ASC",
       "Order Date [+]");
LlDbAddTableSortOrder(hJob, "Orders", "OrderDate DESC",
       "Order Date [-]");

This allows the user to choose one of these sort orders (as well as the default "unsorted") in the Designer. If you use LlDbAddTableEx() to define the tables, you can also support multiple (stacked) sortings.

The remaining action when calling the Designer is analogous to the "normal" call, i.e. the complete scheme for calling the Designer with multiple tables looks like this:

<open job>
       (LlJobOpen, LlJobOpenLCID)
<define List & Label-settings>
       (LlSetOption,
        LlSetOptionString,
        LlSetDebug,
        LlSetFileExtensions,
        LlSetNotificationMessage,
        LlSetNotificationCallback)

<which file?>
       LlSelectFileDlgTitleEx
<define data structure>
       (LlDbAddTable,
        LlDbAddTableRelation,
        LlDbAddTableSortOrder)
<define variables>
       (LlDefineVariableStart,
        LlDefineVariable,
        LlDefineVariableExt,
        LlDefineVariableExtHandle)
<define fields>
       (LlDefineFieldStart,
        LlDefineField,
        LlDefineFieldExt,
        LlDefineFieldExtHandle)
<disable funtions>
       (LlDesignerProhibitAction,
        LlDesignerProhibitFunction)
<call designer>
       (LlDefineLayout)
<close job>
       (LlJobClose)

 

Make sure that you pass all field names in the form of "<tableid>.<fieldname>" in order to enable List & Label can connect these to their corresponding table (e.g. "Orders.OrderID").

If you want to add fields of a 1:1 relation, please refer to chapter Handling 1:1 Relations.