I will explain how to create a custom KFF. Here I’m using XXCUST_KFF_DEMO table to capture the KFF code combinations.

Following steps needs to perform to create custom KFF.

1) Register the XXCUST_KFF_DEMO table.

Click here to see the code.

Verify the table has created successfully.

Navigation: Application Developer > Application > Database > Table

2) Register the Key Flexfield.

Navigation : Application Developer > Flexfield > Key Flexfields

3) Define the structure and segments.

Navigation:  Application Developer > Flexfield > Key Flexfield Segments

Click on Segments button.

Save the created Information.Check the Allow Dynamic Inserts check box if you want to create the combination from the KFF display window. Once you complete all the changes, check the Freeze Flexfield Definition check box.

4) Create a sequence XXCUST_KFF_DEMO_S.
CREATE SEQUENCE XXCUST_KFF_DEMO_S INCREMENT BY 1 START WITH 1 MAXVALUE 999999999 CYCLE NOCACHE;
5) create KFF item through OAF Page.

Here I am using a page based on table XXCUST_KFF_TRN.

CREATE TABLE xxcust_kff_trn
(
	NAME			     VARCHAR2(100),
	CCID			     NUMBER,
	CREATED_BY		     NUMBER,
	CREATION_DATE		     DATE,
	LAST_UPDATE_DATE             DATE,         
	LAST_UPDATED_BY              NUMBER,   
	LAST_UPDATE_LOGIN            NUMBER
);

You can see the output below.

 

Learn how to use Custom Flexfields in Oracle Forms here.

Issue:
When we are using view object (VO) in OA Framework it’s possible that you will run in to the problem java.sql.SQLException: Invalid column type, especially if it’s an LOV VO. When you click on the LOV torch for the first time it is working fine. But whenever when we click on the GO button in the LOV Region it gives an error.

Solution:
What we need to is, change the Binding Style from Oracle Named to Oracle Positional in the View Object declaration. The framework is adding a where clause to the query using bind variables that are typed :n, this is why you need to set Oracle Positional. Now save it run again, then it will solve this issue.

VO Binding Style

How to Find Duplicate Row in OAF Page?

In this article, I have explained how to stop user to enter duplicate rows in OAF Page table region or advanced table region. This validation helps the users not to enter any duplicate record into system. Below method should be created in AM (Application Module) and it can be referred from CO.

Below method is used to compare rows from same VO Object with different VO instance. (mainVO and Subvo).

public void XXDuplicateVendorCharges() {

  OAViewObject mainVO =
  getXXVendorChargesEOVO1();
  OAViewObject Subvo =
  getXXVendorChargesEOVO1();

  for (Row row = mainVO.first(); row != null; row = mainVO.next()) {
    Number mainVOVendorChargesId = (Number)row.getAttribute("VendorChargesId");
    String mainChrgType = (String)row.getAttribute("VendorChargeType");

    for (Row row1 = Subvo.first(); row1 != null;
      row1 = Subvo.next()) {
      Number SubvoVendorChargesId = (Number)row1.getAttribute("VendorChargesId");
      String SubChrgType = (String)row1.getAttribute("VendorChargeType");

      if (!(mainVOVendorChargesId.equals(SubvoVendorChargesId))) {
        if ((mainChrgType).equals(SubChrgType)) {
          //Subvo.remove(); //remove the Child VO
          //getTransaction().commit(); // This performs the actual delete.
          throw new OAException("Duplicate row exists in Vendor Charges, select only unique Vendor Charge Type.",
                                        OAException.ERROR);
        }
      }
    } //SubVO
  } //MainVO
  mainVO.first();
  Subvo.clearCache();
}

Another Method to check duplicate from DB Object like below.

public void XXDuplicateVendorCharges() {

    OAViewObject VendorHdrVO = getXXVendorHeaderEOVO1();
    Row VendorHdrRow = VendorHdrVO.getCurrentRow();

    try {
        if (VendorHdrRow != null) {
            VendorHdrId = (Number)VendorHdrVO.getAttribute("VendorHdrId");
        }
    } catch (Exception exec) {
        throw new OAException("Error: " + exec, OAException.ERROR);
    }

    OAViewObject mainVO =  getXXVendorChargesEOVO1(); 
    XXVendorChargesEOVOImpl Subvo = 
        (XXVendorChargesEOVOImpl)this.findViewObject("getXXVendorChargesEOVO2"); //Child VO for duplicate checking
        
    if (Subvo == null) {
        Subvo = (XXVendorChargesEOVOImpl)this.createViewObject("getXXVendorChargesEOVO2", 
                                                                   "xxerp.oracle.apps.po.customapp.server.XXVendorChargesEOVO");
    }
    Subvo.clearCache();

    if (!(Subvo.isPreparedForExecution())) {
        Subvo.setWhereClause(null);
        Subvo.setWhereClause("VENDOR_HDR_ID= " + "'" + VendorHdrId + "'");
        Subvo.executeQuery();
    }


    for (Row row = mainVO.first(); row != null; row = mainVO.next()) {
        Number mainVOVendorChargesId = 
            (Number)row.getAttribute("VendorChargesId");
        String mainChrgType = (String)row.getAttribute("VendorChargeType");
       
        for (Row row1 = clonevo.first(); row1 != null; 
             row1 = Subvo.next()) {
            Number SubvoVendorChargesId = 
                (Number)row1.getAttribute("VendorChargesId");
            String SubChrgType = (String)row1.getAttribute("VendorChargeType");

            if (!(mainVOVendorChargesId.equals(SubvoVendorChargesId))) {
                if ((mainChrgType).equals(SubChrgType)) {
                    //Subvo.remove(); //remove the Child VO
                    //getTransaction().commit(); // This performs the actual delete.
                    throw new OAException("Duplicate row exists in Vendor Charges, select only unique Vendor Charge Type.", 
                                          OAException.ERROR);
                }
            }
        } //Subvo
    } //MainVO
    mainVO.first();
    Subvo.remove();
}