Check if column/row has REALLY been modified

Share this topic:



Link to this posting

Postby Ursego » 03 Apr 2013, 15:15

uf_col_modified()

Reports if the column's value has been modified since the retrieval or last save.

Checking of the field's DWItemStatus doesn't work: if the value was changed, but later the original value has been restored (so, the column is not REALLY modified), the status is still DataModified! - it has not jumped back to NotModified!. :twisted: . So, the only reliable way to get the answer is to compare the current and the original values (keeping in mind that one of them, or both, can be NULL). And that is exactly what the proposed function does. It makes scripts shorter by exempting developers from:

1. Declaration and populating of two variables (to keep the compared values).
2. Processing of NULLs. "No change" is reported if both the values are NULLs, and "change occurred" if only one of them is NULL.

Code: Select all
/**********************************************************************************************************************
Acc:   public
-----------------------------------------------------------------------------------------------------------------------
Dscr:   Checks if the column's value has been modified since the retrieval or last save.
      Use adw function instead of checking the columns DWItemStatus (that status remains DataModified! if user changed
      the value and after that returned the original one).
      
      This function makes scripts shorter beacuse it exempts them from:
         1. Declaration and populating of variables for the original and current values.
         2. Processing of NULLs (the value is reported as not modified if both the values, the old and the new,
                  are NULLs, and modified if only one of them is NULL).
      
      If the script deals only with the current record of the Primary! buffer (for example, in a FORM DW, or in
      a multi-rows DW with no filtering and deletion) then you can use the overloaded version with 2 arguments.
-----------------------------------------------------------------------------------------------------------------------
Arg:   DataWindow   adw
      long         al_row
      string      as_col
      DWBuffer      a_buf
-----------------------------------------------------------------------------------------------------------------------
Ret:   boolean (true - has been changed, false - has NOT been changed)
-----------------------------------------------------------------------------------------------------------------------
Thr:   n_ex - http://forum.powerbuilder.us/viewtopic.php?f=2&t=1
**********************************************************************************************************************/
long      ll_row_count
string   ls_col_type
string   ls_old
string   ls_new

choose case a_buf
case Primary!
   ll_row_count = adw.RowCount()
case Filter!
   ll_row_count = adw.FilteredCount()
case Delete!
   ll_row_count = adw.DeletedCount()
end choose

// Validate parameters:
choose case true
case IsNull(al_row)
   f_throw(PopulateError(1, "Arg al_row is null."))
case adw.DataObject = ''
   f_throw(PopulateError(2, "DW doesn't have DataObject."))
case adw.Describe(as_col + '.Name') <> as_col // no such column in the DW
   f_throw(PopulateError(3, "DW doesn't have column '" + as_col + "'."))
case al_row < 0
   f_throw(PopulateError(4, "Arg al_row is negative (" + String(al_row) + ")."))
case al_row > ll_row_count
   f_throw(PopulateError(5, "Arg al_row (" + String(al_row) + ") is greater than the number of rows in DW (" + String(ll_row_count) + ")."))
end choose

// Obtain old (original) and new (current) values:
ls_col_type = Lower(Left(adw.Describe(as_col + ".coltype"), 5))
choose case ls_col_type
case "numbe", "long", "ulong", "real", "int", "decim"
   ls_old = String(adw.GetItemNumber(al_row, as_col, a_buf, true))
   ls_new = String(adw.GetItemNumber(al_row, as_col, a_buf, false))
case "char(", "char"
   ls_old = adw.GetItemString(al_row, as_col, a_buf, true)
   ls_new = adw.GetItemString(al_row, as_col, a_buf, false)
case "datet", "times"
   ls_old = String(adw.GetItemDateTime(al_row, as_col, a_buf, true))
   ls_new = String(adw.GetItemDateTime(al_row, as_col, a_buf, false))
case "date"
   ls_old = String(adw.GetItemDate(al_row, as_col, a_buf, true))
   ls_new = String(adw.GetItemDate(al_row, as_col, a_buf, false))
case "time"
   ls_old = String(adw.GetItemTime(al_row, as_col, a_buf, true))
   ls_new = String(adw.GetItemTime(al_row, as_col, a_buf, false))
end choose

// Define if the value has been changed:
if IsNull(ls_old) and IsNull(ls_new) then return false
if IsNull(ls_old) and not IsNull(ls_new) then return true
if not IsNull(ls_old) and IsNull(ls_new) then return true

return (ls_new <> ls_old)

If the script deals only with the current record of the Primary! buffer (for example, in a FORM DW, or in a multi-rows DW with no filtering and deletion) then you can create an overloaded version (with only 2 arguments - adw and as_col_name) having the following script:

Code: Select all
return uf_col_modified(adw, as_col, adw.GetRow(), Primary!)


uf_row_modified()

Reports if at least one field in the passed row has been modified. For that, it calls uf_col_modified() in a loop, for each column:

Code: Select all
/**********************************************************************************************************************
Dscr:   Reports if at least one field in the pased row has been updated.
      Field is treated as updated if its value has been changed since row is retrieved or inserted.
      If value was changed and later the original value was restored then it's not updated.
-----------------------------------------------------------------------------------------------------------------------
Arg:   adw            DataWindow
      al_row         long
      DWBuffer         a_buf
-----------------------------------------------------------------------------------------------------------------------
Ret:   boolean
-----------------------------------------------------------------------------------------------------------------------
Thr:   n_ex - http://forum.powerbuilder.us/viewtopic.php?f=2&t=1
**********************************************************************************************************************/
int      i
int      li_col_count
string   as_col

li_col_count = Integer(adw.Describe("datawindow.column.count"))
for i = 1 to li_col_count
   as_col = adw.Describe("#"+ String(i) + ".Name")
   if uf_col_modified(adw, as_col, al_row, a_buf) then
      return true
   end if
next

return false


The code of an overload to check the current row in the Primary! buffer:

Code: Select all
return uf_row_modified(adw, adw.GetRow(), Primary!)
User avatar
Ursego
Site Admin
 
Posts: 111
Joined: 19 Feb 2013, 20:33

Return to Tips and Tricks

Who is online

Users browsing this forum: No registered users and 1 guest


Check if column/row has REALLY been modified

Share this topic:


If you think that this site is not too bad, please LIKE it in Facebook. Thanks!





cron
free counters

eXTReMe Tracker