Tips and Tricks in Creating a Header/Detail Form

Purpose of Document

This document discusses the Header/Detail form based on test implementation, which can be categorized as below :

Table of Contents

For this example, primary key is made up of :-

Intended for developers who have Advanced knowledge of the EnterpriseOne Development tools, specifically Form Design Aid and Event Rules Design.

Properties of Header Detail Form

Below routine explains general routine for Header/Detail form :

Back To Top

Map Key Values in Header and Detail

EVENT: Add Record to DB - Before

BC Order Type (F4201)(DCTO) = FC Order Type
BC Order Company (Order Number) (F4201)(KCOO) = FC Order Company
BC Document (Order No, Invoice, etc.) (F4201)(DOCO) = FC Order Number

The primary key is mapped based on the Form Control (FC) Values. If possible, map Audit Information (USER, JOBN, UPMJ/TDAY, UPMT and PID). Without this mapping Header Detail form is not able to handle relationship between Header and Detail


EVENT: Update Record to DB - Before

BC Order Type (F4201)(DCTO) = FC Order Type
BC Order Company (Order Number) (F4201)(KCOO) = FC Order Company
BC Document (Order No, Invoice, etc.) (F4201)(DOCO) = FC Order Number

Map primary key before updating to BC Business View (which is medium between user interface and table)


EVENT: Row is Exited

GC Order Number = FC Order Number
GC Or Ty = FC Order Type
GC Order Co = FC Order Company

This is to build relationship between header and detail


CONTROL: GRID Grid

EVENT: Add Grid Rec to DB - Before

BC Document (Order No, Invoice, etc.) (F4211)(DOCO) = GC Order Number
BC Order Company (Order Number) (F4211)(KCOO) = GC Order Co
BC Order Type (F4211)(DCTO) = GC Or Ty
BC Line Number (F4211)(LNID) = GC Line Number

Primary Key for Detail Table is mapped based on GC (Grid Control). If needed assign Audit information (get/assign in Post Dialog is Initialized event) which is same with header


EVENT: Update Grid Rec to DB-Before

BC Document (Order No, Invoice, etc.) (F4211)(DOCO) = GC Order Number
BC Order Company (Order Number) (F4211)(KCOO) = GC Order Co
BC Order Type (F4211)(DCTO) = GC Or Ty
BC Line Number (F4211)(LNID) = GC Line Number

Back To Top

Auto Line Numbering

Below Event is to handle the increment of Line Number (LNID) in the Grid in both Add and Update Mode.

EVENT: Dialog is Initialized

VA frm_mnLineNumber_LNID = "0"

Add a form variable using DD Alias LNID and name it as 'frm_mnLineNumber_LNID'. This can be initialized either in events (Dialog is Initialized or Post Dialog is Initialized).


EVENT: Grid Record is Fetched

If BC Line Number (F4211)(LNID) is greater than VA frm_mnLineNumber_LNID
VA frm_mnLineNumber_LNID = BC Line Number (F4211)(LNID)
End If

This is to store latest line number in update mode by assigning BC value to form variable frm_mnLineNumber_LNID


EVENT: Row is Exited

If GC Line Number is less than or equal to VA frm_mnLineNumber_LNID
VA frm_mnLineNumber_LNID = [VA frm_mnLineNumber_LNID]+1
GC Line Number = VA frm_mnLineNumber_LNID
End If

Increment 1 based on biggest line number used and assign it into GC Line Number. This can be written at Row is Exited/Changed - Inline.

Back To Top

Computing FC Control Based on Grid Value entered to update it into the Header File.

To handle this, temporary columns are added and stored value before and after change.

EVENT: Write Grid Line-Before

GC Order Amount - Line = [GC Quantity Ordered]*[GC Unit Price]
GC OTOT - Before (Hidden) = [GC Quantity Ordered]*[GC Unit Price]
FC Order Gross Amount_edit = [FC Order Gross Amount_edit]+[GC OTOT - Before (Hidden)]

This is to show FC variable on Update Mode.


EVENT: Add Record to DB - Before

BC Amount - Order Gross (F4201)(OTOT) = FC Order Gross Amount_edit

Map computed FC value to BC (business view control).


EVENT: Update Record to DB - Before

BC Amount - Order Gross (F4201)(OTOT) = FC Order Gross Amount_edit

Map computed FC value on Update Mode to BC


EVENT: Row is Exited

GC Order Amount - Line = [GC Quantity Ordered]*[GC Unit Price]

Example of this computation can be performed Row is Exited/Changed - Async/Inline


EVENT: Row Exit & Changed - Asynch

If GC OTOT - Before (Hidden) is not equal to GC Order Amount - Line
FC Order Gross Amount_edit = ([FC Order Gross Amount_edit]+[GC Order Amount - Line])-[GC OTOT - Before (Hidden)]
End If
GC OTOT - Before (Hidden) = GC Order Amount - Line

This routine is one of simple way to check value changed. Make it sure after computing a new FC Value to save off temp value.


CONTROL: HYPITEM &Delete

EVENT: Button Clicked

FC Order Gross Amount_edit = [FC Order Gross Amount_edit]-[GC Order Amount - Line]

In case Delete button against a single row is clicked, the value has to be subtracted

Back To Top

To Avoid Addition of Empty Grid Row

In Header/Detail form, if you do not handle GC (Grid Column) or GB (Grid Buffer) in toggling mouse cursor up and down, it may add addtional grid row. The problem of this coding is that detail information can be created without having actual data.

To prevent this, review code which computes/assigns GC/GB variable and put this assignment only when mandatory grid column has a valid value.

For example,

EVENT: Row is Exited
If GC 2nd Item Number is not equal to <Blank>
GC Order Amount - Line = [GC Quantity Ordered]*[GC Unit Price]
End If

Back To Top

How to differentiate rows from business view and newly added row

For example, many cases user may click Select to add additional rows to existing data (for instance, a certain sales order has 3 detail lines then user want to append additional line 4). In general, SV Form_Mode is determined by the button clicked made (Select for Update Mode, Add for Add mode, Delete for Delete mode and Copy for Copy Mode. So SV Form_Mode is not sufficient to make your application to differentiate as-is row with newly added row. To meet this requirement, commonly you can make use of form level event rule.
1. Add a column using Data Dictionary Item (e.g., EV01) so now you can make use of GC variable (which to be hidden)
2. Assign GC at Form Level events (e.g.,“Grid Record is Fetched” (based on BC) , “Write Grid Line-Before” (based on GC) or “Last Record Has Been Read” (based on GC)"
For example,
EVENT: Grid Record is Fetched

If BC Line Number (F4211)(LNID) is not equal to <Zero> /* Existing lines F4211.LNID is always greater than zero because it is primary key */
GC Flag(hidden) = "Y" /* Assign any flag, you want to make use during Grid handling */
Else
GC Flag(hidden) = " "
End If
3. Then in Grid level event you can make use of GC Flag(hidden) based on your business requirement

Back To Top

How to set/update the maximum value in a Grid Column to Header Table

To save off the maiumum value of a specific grid column into a specific header table column. In example below, it is the maximum value of Unit Cost.

EVENT: Add Record to DB - Before

VA frm_MAX_UNCS = "0" /* Initialize temp value */
VA frm_MaxRow = "0" /* Initialize MaxGridRow - this form level varilable is created based on DD Alias SEQ */
VA frm_CurrentRow = "1" /* Initialize CurrentGridRow - this form level varialble is created based on DD Alias SEQ */
Get Max Grid Rows(FC Grid, VA frm_MaxRow) /* Call System Function to get Max Grid Row. The value will be actual number of rows + 1 in the Header/Detail form */
While VA frm_CurrentRow is less than VA frm_MaxRow /* Note that relation key word is "is less than" not "is equal to or less than" not to handle the last row */
Get Grid Row(FC Grid, VA frm_CurrentRow) /* Call System Function to get current row, pointer */
If GC Unit Cost is greater than or equal to VA frm_MAX_UNCS /* To store the biggest number */
VA frm_MAX_UNCS = GC Unit Cost
End If
VA frm_CurrentRow = [VA frm_CurrentRow]+1 /* Increase current row number otherwise, it falls into infinite looping because WHILE test will be always success */
End While

BC UnitCost (HeaderTable)(UNCS) = VA frm_MAX_UNCS /* assign temporary value to Business View column */

EVENT: Update Record to DB - Before

Repeat same action as for EVENT: Add Record to DB - Before.

Back To Top

How to limit maximum two grid rows to add/update data?

One of possible implementation is making use of system function for Grid Get Max Grid Rows(FC Grid, return value),

Try,

  1. Add two form controls (one to count total number of rows using MATH01 (say FC mnNoOfRows_RCK7), and the other one for Push Button to compute max row numbers)
  2. Button clicked event of Push Button (to be hidden),

2-1. Call system function Get Max Grid Rows(FC Grid, FC mnNoOfRows_RCK7)

2-2. Subtract it by 1 because additional row is to be added automatically for both Headerless/Detail form and Header/Detail Form: FC mnNoOfRows_RCK7 = FC mnNoOfRows_RCK7 - 1

2-3. Validate FC mnNoOfRows_RCK7 and set error if it is greater than 2

3. Press Button when there is modification regardless Form Mode (e.g., Row Exit & Changed - Inline event) using system fuction "Press Button(FC Push Button)

4. Recalculate max row when user delete any rows at the event of Button Clicked against Hyper Button Delete by calling Press Button(FC Push Button)

Back To Top