An example for this would be a list of customers followed by a chart of employees. Both tables can be independent. The print loop for this looks very similar to the print loop in the last chapter – with one difference. Usually, you tell List & Label that a table is finished (no more data) by calling LlPrintFieldsEnd(). Now you may get the return value LL_WRN_TABLECHANGE, meaning that there is another table to print in the layout.
We suggest splitting your print loop into different subroutines.
The first part declares the data and the structure, starts the print job and initializes the first page so that printing of a table can be started. For ease of reading, the optional part of the print loop is not shown here, as it has already been shown in the last chapter.
<define data
structure>
(LlDbAddTable,
LlDbAddTableRelation,
LlDbAddTableSortOrder)
<define all possible
variables>
(LlDefineVariableStart,
LlDefineVariable,
LlDefineVariableExt,
LlDefineVariableExtHandle)
<define all possible
fields>
(LlDefineFieldStart,
LlDefineField,
LlDefineFieldExt,
LlDefineFieldExtHandle)
LlSetPrinterDefaultsDir
<begin
print>
(LlPrintStart,
LlPrintWithBoxStart)
<define
options>
(LlPrintSetOption,
LlPrintSetOptionString,
LlPreviewSetTempPath)
<define fixed
variables>
(LlDefineVariable,
LlDefineVariableExt,
LlDefineVariableExtHandle)
<print
variables> (print all
objects)
(LlPrint)
<as long as warning
repeat>
(LlPrint)
The second part of the print loop needs an auxiliary function. This function prints the data of a single (database) table
function
PrintTable(DataTable Dataobject)
{
//
DataTable is an adequate object for data access, e.g.
a
// table of a database, a class array
or similar
<repeat>
{
<define fields of
DataTable>
(LlDefineField,
LlDefineFieldExt,
LlDefineFieldExtHandle)
<print
line>
(LlPrintFields)
<as long as warning repeat
>
(LlPrint,
LlPrintFields)
<next data record in
DataTable>
}
<until last data record in
DataTable reached>
<print footer line>
(Ret = LlPrintFieldsEnd)
<as long
as warning "page full"
repeat>
(Ret = LlPrintFieldsEnd)
<result =
Ret>
}
The return value specifies whether another table follows (LlPrintFieldsEnd() returns LL_WRN_TABLECHANGE) or if the print can be finished (return value 0).
With this function, the second part of the print – the part after the initialization of the first page – can be coded as follows:
<repeat>
{
<get current table name
>
(LlPrintDbGetCurrentTable)
<get
current
sorting>
(LlPrintDbGetCurrentTableSortOrder)
<generate a corresponding DataTable
object>
<Ret=PrintTable(DataTable)>
}
<until Ret <>
LL_WRN_TABLECHANGE>
<finish
printout>
(LlPrintEnd)
If you have declared the "LLStaticTable" table for free contents and LlPrintDbGetCurrentTable() provides this table as the current table, your printing loop must react to it by printing a single data line via LlPrintFields(). In the above example, you could simply generate a DataTable object with just one data record for the case of "LLStaticTable", and printing will then automatically run correctly.
This code already allows an arbitrary sequence of multiple tables in series. In the following chapter, we will expand it to print sub-tables as well.