Here is another way of achieving this. This takes 2 .42f form files, reads them both, and inserts one of them as a folder page into the other form file. I've hard-coded it a bit and there is a number of changes I'd make before putting it in production but hopefully gives you an idea of the potential.
-- customer2.4gl
MAIN
DEFER INTERRUPT
OPTIONS INPUT WRAP
OPTIONS FIELD ORDER FORM
MENU ""
COMMAND "Maintenance"
CALL do_maintenance()
COMMAND "Sales Report by Customer and Product"
CALL do_report1()
ON ACTION close
EXIT MENU
END MENU
END MAIN
FUNCTION do_maintenance()
DEFINE customer_code CHAR(10)
DEFINE customer_name CHAR(30)
DEFINE customer_address1 CHAR(30)
DEFINE customer_address2 CHAR(30)
DEFINE customer_address3 CHAR(30)
DEFINE customer_address4 CHAR(30)
OPEN WINDOW maint WITH FORM "customer2_maint"
INPUT BY NAME customer_code, customer_name, customer_address1, customer_address2, customer_address3, customer_address4
ON ACTION accept
EXIT INPUT
ON ACTION cancel
EXIT INPUT
END INPUT
CLOSE WINDOW maint
END FUNCTION
FUNCTION do_report1()
DEFINE customer_sql, product_sql STRING
OPEN WINDOW report1 WITH FORM build_report_formfile("customer2_report1", "customer2_maint")
DIALOG
CONSTRUCT BY NAME customer_sql ON customer_code, customer_name, customer_address1, customer_address2, customer_address3, customer_address4
END CONSTRUCT
CONSTRUCT BY NAME product_sql ON product_code
END CONSTRUCT
ON ACTION accept
EXIT DIALOG
ON ACTION cancel
EXIT DIALOG
END DIALOG
DISPLAY SFMT("%1 AND %2", customer_sql, product_sql)
CLOSE WINDOW report1
END FUNCTION
# include file2 as a folderpage in file1
FUNCTION build_report_formfile(file1, file2)
DEFINE file1, file2 STRING
DEFINE dom1, dom2 om.domdocument
DEFINE root1, root2, folder1, page1, form2, grid1, recordview1, recordview2, link1, link2 om.DomNode
DEFINE folder_list1, form_list2, recordview_list1, recordview_list2 om.nodelist
DEFINE filename STRING
DEFINE i INTEGER
LET dom1 = om.DomDocument.createfromxmlfile(SFMT("%1.42f", file1))
LET dom2 = om.DomDocument.createfromxmlfile(SFMT("%1.42f", file2))
LET root1 = dom1.getdocumentelement()
LET root2 = dom2.getdocumentelement()
LET folder_list1 = root1.selectbytagname("Folder")
IF folder_list1.getlength() > 0 THEN
LET folder1 = folder_list1.item(1)
ELSE
-- Handle errors better
DISPLAY "1"
EXIT PROGRAM 1
END IF
LET page1 = folder1.createchild("Page")
CALL page1.setAttribute("text", "Customer")
LET grid1 = page1.createChild("Grid")
LET form_list2 = root2.selectbytagname("Form")
IF form_list2.getlength() > 0 THEN
LET form2 = form_list2.item(1)
ELSE
-- Handle errors better
DISPLAY "2"
EXIT PROGRAM 2
END IF
LET recordview_list1 = root1.selectByTagName("RecordView")
IF recordview_list1.getlength() != 1 THEN
-- Handle errors better
DISPLAY "3"
EXIT PROGRAM 3
ELSE
LET recordview1 = recordview_list1.item(1)
END IF
LET recordview_list2 = root2.selectByTagName("RecordView")
IF recordview_list2.getlength() != 1 THEN
-- Handle errors better
DISPLAY "4"
EXIT PROGRAM 4
ELSE
LET recordview2 = recordview_list2.item(1)
END IF
-- Copy each link
FOR i = 1 TO recordview2.getchildcount()
LET link1 = recordview1.createchild("Link")
LET link2 = recordview2.getchildbyindex(i)
CALL copy_node(link2, link1,1)
END FOR
-- Copy the form layout contents
CALL copy_node(form2.getChildByIndex(1), grid1,1)
LET filename = SFMT("my_generated_formfile.42f",FGL_GETPID())
CALL root1.writeXml(filename)
RETURN filename
END FUNCTION
-- copy attributes and children of node n1 to node n2
-- displacement is to add them at the end of the existing fields defined in the form
FUNCTION copy_node(n1, n2, displacement)
DEFINE n1, n2, c1, c2 om.DomNode
DEFINE displacement INTEGER
DEFINE i INTEGER
FOR i = 1 TO n1.getattributescount()
CASE n1.getattributename(i)
WHEN "fieldId"
CALL n2.setAttribute(n1.getattributename(i), (n1.getattributevalue(i)+displacement) USING "<<&")
WHEN "fieldIdRef"
CALL n2.setAttribute(n1.getattributename(i), (n1.getattributevalue(i)+displacement) USING "<<&")
WHEN "tabIndex"
CALL n2.setAttribute(n1.getattributename(i), (n1.getattributevalue(i)+displacement) USING "<<&")
OTHERWISE
CALL n2.setAttribute(n1.getattributename(i), n1.getattributevalue(i))
END CASE
END FOR
FOR i = 1 TO n1.getchildcount()
LET c1 = n1.getchildbyindex(i)
LET c2 = n2.createChild(c1.getTagName())
CALL copy_node(c1, c2, displacement)
END FOR
END FUNCTION
-- customer2_maint.per
LAYOUT
GRID
{
Customer Code [cu01 ] Customer Name [cu02 ]
Customer Address [cu03 ]
[cu04 ]
[cu05 ]
[cu06 ]
}
END
END
ATTRIBUTES
cu01 = formonly.customer_code;
cu02 = formonly.customer_name;
cu03 = formonly.customer_address1;
cu04 = formonly.customer_address2;
cu05 = formonly.customer_address3;
cu06 = formonly.customer_address4;
-- customer2_report1.per
LAYOUT (TEXT="Customer Sales by Product Report")
FOLDER
PAGE (TEXT="Product")
GRID
{
Product [sa01 ]
}
END
END
END
END
ATTRIBUTES
sa01 = formonly.product_code;