Home
What's New
Dev Tools
Services
Feedback
Site Map

---------------------------------------------------------- back to tips menu

DataWindow Code Samples

ItemChanged Code Sample

The following sample ItemChanged code could be used on a typical descendant window.

integer li_Return = 0 // default is that validation succeeded

CHOOSE CASE Lower(dwo.Name)
  CASE "quantity"
    // only perform validation if data was entered
    IF NOT IsNull(data) AND Len(data) > 0 THEN

      // check if quantity is in its valid range
      IF long(data) < 1 OR long(data) > 999 THEN
        MessageBox("Error", "Quantity must be between 1 and 999.")
        li_Return = 1
      END IF
    END IF

  CASE "group_code" // DDDW
    // only perform validation if data was entered
    IF NOT IsNull(data) AND Len(data) > 0 THEN

      // verify code is valid (i.e. it is in drop down)
      li_DddwResult = f_CheckDdddwValue(dwo.Name, data, "description", ls_Desc)

      // Entry not in DDDW -- tell user of error
      IF li_DddwResult < 0 THEN
         MessageBox("Error", "Invalid value specified in drop down.")
         li_Return = 1
      ELSE
        // entry empty or OK, update corresponding description on DW
        This.SetItem(1,"Description Field",ls_DddwDesc)
      END IF
    END IF

END CHOOSE

// set flag so ItemError know to suppress its default message
IF li_Return = 1 THEN
  ib_SuppressMsg = True
END IF

Return li_Return
ote: if this ItemChanged event were written under PFC, it would use the DW
function f_message() (instead of MessageBox) as suggested under the PFC tips

ItemError Code Sample

Sample ItemError Event

The sample ItemError code is appropriate for use in an ancestor DataWindow. The sample does the following error checking:

integer li_Return

string ls_ColType
n_cst_conversion lnv_conversion

ls_ColType = Lower(left(dwo.ColType,5))

// if problem found in ancestor ItemError, don't check error further
IF AncestorReturnValue <> 0 THEN
  li_Return = AncestorReturnValue
ELSE
  // if the error originated in ItemChanged a message will have been displayed there,
  //  so simply suppress the standard ItemError error message.
  IF ib_SuppressMsg THEN
    ib_SuppressMsg = False
    li_Return = 1
  // check if it is a missing "NilIsNull" property
  ELSEIF ls_ColType <> "char(" AND NOT IsNull(data) AND Len(data) = 0 THEN
    MessageBox("Error", "You cannot empty this field due to a software " + &
        "fault.~r~n To continue, you must supply a valid value.")
    // write missing NilIsNull property error to central error log ...
    li_Return = 1
  ELSE
    // Determine if the problem is a data type mismatch
    CHOOSE CASE ls_ColType
      CASE "datet"
        // datetime type mismatch
        IF IsNull(lnv_conversion.f_DateTime(data)) THEN
          // Many DB's only have datetime columns but the user might consider it a "date".
          // For that reason, use more generic message wording.
          MessageBox("Error","Value is not a valid Date or DateTime")
          li_Return = 1
        END IF

      CASE "date"
        // date type mismatch
        IF NOT IsDate(data) THEN
          MessageBox("Error","Value is not a valid Date")
          li_Return = 1
        END IF

      CASE "time"
        // time type mismatch
        IF NOT IsTime(data) THEN
           MessageBox("Error","Value is not a valid Time")
          li_Return = 1
        END IF

      CASE "decim", "long", "ulong", "numbe", "real"

        // if data type mismatch, determine cause ...
        IF NOT IsNumber(data) THEN
            MessageBox("Error","Value is not a valid Number")
            li_Return = 1
        END IF

    END CHOOSE

  END IF
END IF

Return li_Return
Note: if this ItemError event were written under PFC, it would use the DW
function f_message() (instead of MessageBox) as suggested under the PFC tips

DBError Code Sample

When a DataWindow update fails due to a database error, PowerBuilder invokes the DBError event. By default, DBError displays an error message with the full error text from the database. By coding the DBError event, special processing can be performed and a custom error message can be displayed for appropriate database error codes. The next coding sample shows handling for two error conditions: a duplicate row and a row that changed between retrieve and update. If you are using PFC, see note below.

integer li_Return
CHOOSE CASE SqlDbCode
  CASE 1 // 1 is Oracle for duplicate (2601 for Sybase, -193/-196 for SQL Anywhere)
    MessageBox("Error","Duplicate value on this Row")

    // set focus to enterable unique key column
    This.SetColumn("Product")
    li_Return = 1 // suppress default message
  CASE -3 // standard PB number for row changed between retrieve and update
    MessageBox("Error","Row Changed between since it was retrieved. " + &
    "Data must be re-retrieved and the changes re-applied.")
    li_Return = 1
  CASE ELSE
    li_Return = 0 // use the default message for any other errors
END CHOOSE
IF li_Return = 1 THEN
  // if row is visible (i.e. in Primary buffer), set focus to that row
  IF buffer = Primary! THEN
    This.ScrollToRow(row)
    This.f_SetFocus() // uses f_SetFocus() function shown above
  ELSEIF buffer = Filter! THEN
    // if bad row is filtered, make it visible (in primary buffer) first
    This.RowsMove(row, row, Filter!, This, 1, Primary!)
    This.ScrollToRow(1)
    This.f_SetFocus()
  END IF
END IF
Return li_Return

Note: DB Error handling for PFC has to be handled differently since there is ancestor logic in the PFC DataWindow DBError event. Unfortunately, the primitive PFC 5 DBError logic is not easily extended -- fixing the PFC 5 DBError logic requires some real effort. The PFC 6 DBError logic is improved but it still gives no simple hook where the descendant can opt to do its own handling for certain errors.


Copyright Woodger Computing Inc.