QAD 2017 Enterprise Edition > User Guides > Reporting Framework > Implementing a Progress Data Source Program > Developing the Data Source Program Code > Metadata Block
  
Metadata Block
You define metadata to specify which fields and tables the user can use to design the report. Every table in the data set needs a buffer header metadata section, as well as metadata describing its fields.
To facilitate the coding of metadata, there is a helper program (ReportHelper.p), which is accessible in your data source program through the persistent procedure handle reportHandle. This helper program contains several functions, described below, which populate the metadata data set that gets passed back to the client.
Defining Buffer Name and Creating BufferHeader
The CreateBufferHeader procedure creates the metadata that describes a table, and must be run once for each temp-table in your report data set.
The input parameters to this procedure are listed below; be sure to use the exact temp-table for the table name parameter.

CreateBufferHeader Parameters
 
Seq.
Name
Input/Output
Data Type
Description
1
tableName
Input
Character
Temp-table name
2
tableLabel
Input
Character
Label displayed in Report Designer
Creating Fields for Each Temp-Table
Either of three predefined procedures can be used to create field metadata. The procedures are similar and have the same effect of creating a metadata record for one field. A description of each is given below.
CreateField — this variant allows the programmer to explicitly pass in the values of each metadata parameter.
CreateFieldForDBField — this variant can be used if the field is similar to one in the business database, in which case some of the metadata parameters will be determined by the system based on the database field. For example, the field label, data type, field format, and lookup name will be driven by the database field.
CreateFieldLikeDBField — this variant is almost identical to CreateFieldForDBField except that it allows the field name of the report field to be different from that of the database field.
The following sections list the input parameters for each of these three procedures.
CreateField

CreateField Parameters
 
Name
Input/Output
Data Type
Description
bufferName
Input
Character
Temp-table name
fieldName
Input
Character
Report field name
fieldLabel
Input
Character
User-facing label for this field, as it will appear on the prompt page of the report viewer
dataType
Input
Character
Progress datatype of the field
fieldFormat
Input
Character
Progress format for the field.
In the case of logical-typed fields, the field format string is used to specify the user-facing labels for the true and false values the field can hold; the syntax is: <trueLabel>/<falseLabel>. For example, "Debit/Credit". Note: in a multi-language system, these values should not be hard coded but instead dynamically translated using the getLabel function. The format strings will be used in search condition values on the prompt page, as well as data values in the report output.
lookupName
Input
Character
Program name of the lookup program (if any) that will be invoked from the lookup icon for this field on the prompt page of the report viewer; For example, "gplu340.p". For more information on defining lookups, see Defining Search Field Lookups.
isSearchField
Input
Logical
Whether this field should be a search field on the prompt page
isReadOnlySearch
Input
Logical
Not used: use isEditable instead.
isVisible
Input
Logical
Whether this field is visible in Report Designer
isSingleEntry
Input
Logical
If set to True, then only a single search condition will be allowed for this field.
isOperatorChangeable
Input
Logical
Whether the operator can be changed on the prompt page
isRequiredCondition
Input
Logical
Whether the field is mandatory on the prompt page
isEditable
Input
Logical
Whether the field can be edited on the prompt page
defaultValue
Input
Character
Default value of the first search field
defaultOperator
Input
Character
Default operator of the first search field
defaultValueType
Input
Character
Default value type of the first search field
defaultValue2
Input
Character
Default value of the second search field
defaultValueType2
Input
Character
Default value type of the second search field
CreateFieldForDBField

CreateFieldForDBField Parameters
 
Name
Input/Output
Data Type
Description
bufferName
Input
Character
Temp-table name
tableName
Input
Character
QAD ERP database table name
fieldName
Input
Character
QAD ERP database field name
isSearchField
Input
Logical
Whether this field should be a search field on the prompt page
isReadOnlySearch
Input
Logical
Whether this field is read-only on the prompt page
isVisible
Input
Logical
Whether this field is visible in Report Designer
isSingleEntry
Input
Logical
Always set this to False
isOperatorChangeable
Input
Logical
Whether the operator can be changed on the prompt page
isRequiredCondition
Input
Logical
Whether the field is mandatory on the prompt page
isEditable
Input
Logical
Whether the field can be edited on the prompt page
defaultValue
Input
Character
Default value of the first search field
defaultOperator
Input
Character
Default operator of the first search field
defaultValueType
Input
Character
Default value type of the first search field
defaultValue2
Input
Character
Default value of the second search field
defaultValueType2
Input
Character
Default value type of the second search field
CreateFieldLikeDBField

CreateFieldLikeDBField Parameters
 
Name
Input/Output
Data Type
Description
bufferName
Input
Character
Temp-table name
fName
Input
Character
Field name in the temp-table (report field name)
tableName
Input
Character
QAD ERP database table name
fieldName
Input
Character
QAD ERP database field name
isSearchField
Input
Logical
Whether this field should be a search field on the prompt page
isReadOnlySearch
Input
Logical
Whether this field is a read-only on the prompt page
isVisible
Input
Logical
Whether this field is visible in Report Designer
isSingleEntry
Input
Logical
Always set this to False
isOperatorChangeable
Input
Logical
Whether the operator can be changed on the prompt page
isRequiredCondition
Input
Logical
Whether the field is mandatory on the prompt page
isEditable
Input
Logical
Whether the field can be edited on the prompt page
defaultValue
Input
Character
Default value of the first search field
defaultOperator
Input
Character
Default operator of the first search field
defaultValueType
Input
Character
Default value type of the first search field
defaultValue2
Input
Character
Default value of the second search field
defaultValueType2
Input
Character
Default value type of the second search field
Example: The following is a complete metadata definition code block illustrating a simple case consisting of a single table and three fields.
 
procedure FillMetaData:
bufferName = "ttSalesHeader".
 
run CreateBufferHeader in reportHandle
(bufferName, "Sales Orders").
 
/* The so_nbr field is set as a search field, so the seventh parameter is True. */
run CreateField in reportHandle
(bufferName,
"so_nbr",
getLabel("SALES_ORDER"),
"character",
"x(8)",
"gplu239.p",
true,
false,
true,
false,
true,
false,
true,
"",
{&ParameterOperator_Equals},
{&ParameterValueType_Constant},
"",
{&ParameterValueType_Constant}).
 
/* The following field will have some of its metadata attributes */
/* driven from the so_cust database field. */
 
run CreateFieldForDBField in reportHandle
(bufferName,
"so_mstr",
"so_cust",
true,
false,
true,
false,
true,
false,
true,
"",
{&ParameterOperator_Equals},
{&ParameterValueType_Constant},
"",
{&ParameterValueType_Constant}).
 
/* The following field will be called order_date in the report even though some */
/* of its metadata attributes will be driven from the so_ord_date database field. */
 
run CreateFieldLikeDBField in reportHandle
(bufferName,
"order_date",
"so_mstr",
"so_ord_date",
true,
false,
true,
false,
true,
false,
true,
"",
{&ParameterOperator_Equals},
{&ParameterValueType_Constant},
"",
{&ParameterValueType_Constant}).
 
end procedure.
Note: The above code example is intentionally limited to a single table and three fields for the purpose of illustrating each of the metadata procedures. It does not define the entire metadata necessary to describe the master detail data set structure from the previous example. Please refer to the complete code example at the end of this appendix to see the entire metadata section.
Note: The last example (CreateFieldLikeDBField) is just for the purpose of illustrating this procedure call; it is inconsistent with our temp-table definition in the previous section, whose field name would have to be changed to order_date in order to match the report field name in the procedure call.
Specifying a Discrete Set of Values for a Field
Fields of type character can optionally be defined such that their allowed values can be restricted to a discrete set. If a user creates a search condition on the prompt page for such a field, they will encounter a drop-down box containing the allowed values to select from. Furthermore, the system can display translated labels for these values that map to the actual underlying data values that are stored in the database. This is accomplished by setting the valueList metadata property for the field.
The valueList metadata attribute must be specified using the following comma-separated value format:
<Label 1>,<DB value 1>,<Label 2>,<DB value 2>, ...
In the above format, <Label 1> specifies the user-facing label for the first allowed value; <DB Value 1> specifies the string used in the database for the first allowed value, and so on for the other allowed values.
Note: To escape a comma character “,” in the display values for a value list, use two backslashes: “\\”. For example: "d\\,isp1,value1,disp2,value2,disp3,value3".
For example, consider a field called status that should be restricted to the set of values “New”, “In Process”, and “Completed”, which are stored in the database as the values “1”, “2”, and “3”, respectively. The valueList attribute can be specified by adding the following code statements after this field’s CreateField procedure call:
 
define variable statusValueList as character no-undo.
 
statusValueList = "New,1,In Process,2,Completed,3".
 
run SetFieldMetaParameter in ReportHandle(
bufferName,
"status",
"valueList",
statusValueList).
The SetFieldMetaParameter procedure is used to set a field metadata attribute for a field that has already been created in the metadata. The first input parameter is the buffer name of the field, the second parameter is the field name, the third parameter is the name of the attribute to set (“valueList”, in this example), and the fourth parameter is the value to set the attribute to (the comma-separated list). Please note that in multi-language system environments, the strings “New”, “In Process”, and so on, should first be translated before setting the metadata attribute, as described in the next section.
Translating Metadata Content
When creating reports for systems with multiple languages, most of the translated labels are specified when designing the report layout using the Report Designer (see Using Translated Labels). However, the following attributes of field metadata can also contain strings that may need to be translated:
The fieldLabel attribute
The valueList attribute
The fieldFormat attribute (in the case of logical-typed fields)
When the report client sends a request to the data source program, the language of the user is set in the global_user_lang Progress variable. The data source program should use this setting to determine the language in which to translate labels used in the metadata.
Beginning in the QAD Enterprise Applications 2010 release, a new utility function has been added to the ReportHelper.p program that facilitates looking up translated labels from the QAD system labels:
 
FUNCTION getLabel returns character (
input pTerm as character):
 
The getLabel function takes a label term as its input parameter, and returns the translated label for that term in the language specified in the global_user_lang variable. If no label is found for the input term, then the term itself is output.
In the example above illustrating how to use the CreateField procedure, this technique was used to translate the field label for the so_nbr field by using the function call getLabel("SALES_ORDER") that looks up the translated label for the term "SALES_ORDER".
Setting Date, Logical, and Numeric Type Default Values in Proxy Code
To set date, logical, and numeric type default values in proxy code:
For logical typed fields, the default value you pass to CreateField must be a character type having either the value true or false (regardless of whether alternate labels are used for the user-facing values).
For integer and decimal typed fields, the default value you pass to CreateField must be a character type having the English-locale notation (for example, 123 or 12.345).
For date typed fields, the default value that you pass to CreateField must be a character type and not a date type because Progress will convert a date type to the default date format of the AppServer which is the ymd format and this is not always desired. The format of the date string should be: 9999-99-99. For example, to hard code a default of October 10, 2000, use the default value of 2000-10-20. For non-hard-coded values, see the following example:
 
define variable startDay as character no-undo.
define variable endDay as character no-undo.
 
startDay = string(today - 1,"9999-99-99").
endDay = string(today,"9999-99-99").
 
run CreateField in reportHandle
(bufferName,
"tr_effdate",
"Loaded",
"DATE",
"",
"",
true,
false,
true,
false,
false,
true,
true,
startDay,
{&ParameterOperator_Between},
{&ParameterValueType_Constant},
endDay,
{&ParameterValueType_Constant}).
 
Specifying Financials Lookups in Field Metadata
When writing data source programs, you can specify Financials lookups in the metadata as opposed to standard browse lookups. To do this, specify the following for the lookupName in the metadata: <lookup provider type>:<lookupID>:<lookup return field>:<lookup filter field>.
<lookup return field> and <lookup filter field> are optional. In the example above, the two fields are the same as the calling field in the browse whose lookup button is pressed.
Here is an example for the Financials lookup:
BaseLibrary.Lookup.BLFLookupProvider:BJournalSAO.SelectJournal:tcJournalCode:tJournal.JournalCode
Getting Report Code and Report Definition
Beginning in the QAD Enterprise Applications 2010.1 release, two new functions that can be called directly from proxy code to return the report code and report definition are available:
GetReportCode — Returns the report code.
GetReportDefinition — Returns the report definition. It only has a valid value when the report is run and does not have a value when the proxy code is accessed to get the metadata.
Displaying Hard-Coded Message Text
In the RunReport procedure of a report data source program, if you try to raise an error message using the following statement containing a hard-coded message, it does not stop the report from running and does not display the message:
 
{{&US_BBI}pxmsg.i &MSGTEXT=""Example Message"" &ERRORLEVEL=3}
Instead, you must use do the following:
 
DisplayTextMessage("this is a testing message",3)
Note that using MSGNUM for messages that are not hard-coded does work as expected:
 
{{&US_BBI}pxmsg.i &MSGNUM=28 &ERRORLEVEL=3}
Specifying Search Operator List
The SetFieldMetaParameter procedure can specify the search operator list. The first input parameter is the buffer name of the field, the second parameter is the field name, the third parameter is the name of the attribute to set (in this case, searchOperatorList), and the fourth parameter is the value to set the attribute to (the comma-separated list). The following example includes all the available search operators:
 
run SetFieldMetaParameter in ReportHandle(
bufferName,
"status",
"searchOperatorList",
"Equals,NotEquals,Contains,Range,GreaterThanEquals,GreaterThan,LessThan,IsNull,
IsNotNull").
In this example, only the search operators for “equals” and “contains” are included:
 
run SetFieldMetaParameter in ReportHandle(
bufferName,
"status",
"searchOperatorList",
"Equals,Contains").
Defining Search Field Lookups
Fields appearing in the report search panel can optionally have a lookup specified. This is done by specifying the LookupName attribute in the field metadata (see CreateField Parameters). Many possibilities that are supported are described below.
Non-Component Based (MFG/PRO) Browses
Any browse created by Browse Maintenance can be used as a search field lookup, where the LookupName attribute in the field metadata (see CreateField Parameters) is the program name of the lookup program (if any) that is invoked from the lookup icon; for example, gplu340.p.
Specifying Financials Lookups
When writing data source programs, you can specify Financials lookups in the metadata as opposed to standard browse lookups. To do this, specify the following for the lookupName in the metadata: <lookup provider type>:<lookupID>:<lookup return field>:<lookup filter field>.
<lookup return field> and <lookup filter field> are optional. In the example above, the two fields are the same as the calling field in the browse whose lookup button is pressed.
Here is an example for the Financials lookup:
BaseLibrary.Lookup.BLFLookupProvider:BJournalSAO.SelectJournal:tcJournalCode:tJournal.JournalCode
Passing Parameters to Lookups
The <lookupID> can also have parameters passed to it to dynamically change the behavior of the lookup. For example, a lookup of items may be defined to have a product line input parameter that would filter the item list according to the product line value passed in. The values that can be passed to lookups can either be hard-coded or obtained from values that the user has entered into any other search condition.
Parameters are currently only supported by the QAD.Browse.MfgProLookupProvider type (browses created by Browse Maintenance).
The syntax for passing parameters to lookups is as follows:
<lookupID>(paramName1,paramValue1,paramName2,paramValue2,...)
Literal paramValue1 values are supported, as well as values that are dynamically determined by a search condition value in the search panel. The latter case is invoked by prefixing the paramValue1 value with the @ character. For example, a browse may have a search field pt_mstr.pt_prod_line, and another search field pt_mstr.pt_part, and the lookup for pt_part might be restricted by what the user entered in the value to restrict the product line by, with the pt_part search lookup (for example, example.p) expecting c-brparm1 parameter to contain the product line to filter by. This is accomplished by using the following lookupID string:
example.p(c-brparm1,@pt_mstr.pt_prod_line)
Specifying Conditional Lookups
In some cases, you may want to have a search field lookup invoke a different browse depending on the user-selected value in a different search condition.
For example, a report may have a vendor source field that is a value list with two items: PO (Purchase Order) and DO (Distribution Order). If the user selects PO, the lookup on the supplier field should be a browse against suppliers. If the user selects DO, the lookup on the supplier field should be a browse against sites.
The syntax for specifying conditional lookups is as follows:
<FieldName>|<Value1>,<LoopkupTarget1>,<Value2>,<LoopkupTarget2>,...|<DefaultLookupTarget>
In the above, the search condition value of the condition on the field specified by <FieldName> is evaluated according to the map in the second section, which maps search values to lookup targets (browses) to invoke. If no match is found for the actual value of <FieldName> in the search panel, the default lookup target is used. If the type of search value is a ValueList or boolean, then the underlying values in the list (not the translated labels) should be specified in the <Value1> values.
Example: This example invokes lookup targets that are browses created by Browse Maintenance, with the choice of lookup depending on the value entered into the search condition for the so_nbr (string) field:
so_mstr.so_nbr|czs-001,QAD.Browse.MfgProLookupProvider:gplu396.p,
SO-002,QAD.Browse.MfgProLookupProvider:gplu242.p|QAD.Browse.MfgProLookupProvider:gplu340.p
This example invokes lookup targets that are browses defined in the CBF tool in Enterprise Edition, with the choice of lookup depending on the value entered into the search condition for the tPosting.PostingApproveStatus (value list) field:
tPosting.PostingApproveStatus|APPROVEDANDCORRECTED,BaseLibrary.Lookup.BLFLookupProvider:BLayerSAO.SelectLayer:tcLayerCode:tLayer.LayerCode:tLayer.LayerCode,APPROVED AND NOT PASSED,BaseLibrary.Lookup.BLFLookupProvider:BUserSAO.SelectUser:tcUsrLogin:tUsr.UsrLogin:tUsr.UsrLogin|BaseLibrary.Lookup.BLFLookupProvider:BJournalSAO.SelectJournal:tcJournalCode:tJournal.JournalCode
Example: This example invokes lookup targets that are browses defined in the CBF tool in Enterprise Edition, with the choice of lookup depending on the value entered into the search condition for the tPosting.PostingIsAutoReversal (bool) field:
tPosting.PostingIsAutoReversal|true,BaseLibrary.Lookup.BLFLookupProvider:BLayerSAO.SelectLayer:tcLayerCode:tLayer.LayerCode:tLayer.LayerCode,false,BaseLibrary.Lookup.BLFLookupProvider:BUserSAO.SelectUser:tcUsrLogin:tUsr.UsrLogin:tUsr.UsrLogin|BaseLibrary.Lookup.BLFLookupProvider:BJournalSAO.SelectJournal:tcJournalCode:tJournal.JournalCode
Example: This example illustrates how to specify a conditional lookup with one of the lookup targets having dynamic parameters passed to it. In addition to showing the lookup name string, this example also shows the entire code segment that would be used in a Progress data source program metadata section. This defines a lookup on product line that depends on the value picked by the user in ttitem.pt_status, and can have dynamic parameters passed in:
 
define variable prodLineLookup as character no-undo.
prodLineLookup = "ttitem.pt_status|AC,gplu396.p,BASE,gplu242.p,NWISS,wllu003.p(c-brparm1,@ttitem.pt_part)|gplu343.p".
run SetFieldMetaParameter in ReportHandle(
bufferName,
"pt_prod_line",
"lookupName",
prodLineLookup).