I recently figured out that I never published my last updates on this utility.

I removed all references to PBNI to make it easier to integrate in a PowerBuilder project.
The native treeview is replaced by a treedatawindow to make filter faster, and filter is split into two SLE inputs so we can filter on object names and attributes separately.
I realized that it was possible to optimize the window loading significantly: the “w_genidwdm_dwdebugger.of_cache_attributes()
” function is loading all attributes for all objects. That’s fine because we may need to filter them, but the way I load these attributes was not optimum. It was aksing for all attributes and parsing them every time, but the attributes list is the same for a given object type!
string ls_data
string ls_controls, ls_control, ls_properties, ls_property, ls_type
ls_controls = trim(idw_obj.describe( "datawindow.objects" ),true) + "~tdatawindow~t"
long ll_pos_start = 1, ll_pos_end, ll_prop_start, ll_prop_end, ll_col_id
long row= 1
do
ll_pos_end = pos( ls_controls, "~t", ll_pos_start + 1 )
if ll_pos_end <> 0 then
ls_control = mid( ls_controls, ll_pos_start, ll_pos_end - ll_pos_start )
ll_pos_start = ll_pos_end + 1
ls_properties = trim(idw_obj.describe(ls_control+".attributes"),true)+"~t"
ll_prop_start = 1
ll_col_id = 0
if ls_control = 'datawindow' then
ls_type = 'datawindow'
else
ls_type = idw_obj.describe(ls_control+".type")
if ls_type = 'column' then
ll_col_id = long( idw_obj.describe( ls_control+".id" ) )
end if
end if
do
ll_prop_end = pos( ls_properties, "~t", ll_prop_start + 1 )
if ll_prop_end <> 0 then
ls_property = mid( ls_properties, ll_prop_start, ll_prop_end - ll_prop_start )
ll_prop_start = ll_prop_end + 1
ls_data += ls_type + "~t" + ls_control + "~t" + ls_property + "~t" + string(ll_col_id) + "~t"+string(row)+"~r~n"
row ++
end if
loop while ll_prop_end > 0
end if
loop while ll_pos_end > 0
dw_attributes.importstring( Text!, ls_data)
So, it is possible to get attributes once and reuse them to speed up the loading phase.
string ls_data
string ls_controls, ls_control, ls_properties, ls_property, ls_type
ls_controls = trim(idw_obj.describe( "datawindow.objects" ),true) + "~tdatawindow~t"
long ll_pos_start = 1, ll_pos_end, ll_prop_start, ll_prop_end, ll_col_id
long row= 1, ll_cache_begin, ll_cache_end, ll_rows = 0, i
//used to fast insert attributes
string ls_types[], ls_control_names[], ls_empty[], ls_cache_types[]
long ll_uids[], ll_column_ids[], ll_empty[], ll_cache_begins[], ll_cache_ends[]
do
ll_pos_end = pos( ls_controls, "~t", ll_pos_start + 1 )
if ll_pos_end <> 0 then
ls_control = mid( ls_controls, ll_pos_start, ll_pos_end - ll_pos_start )
ll_pos_start = ll_pos_end + 1
ll_prop_start = 1
ll_col_id = 0
if ls_control = 'datawindow' then
ls_type = 'datawindow'
else
ls_type = idw_obj.describe(ls_control+".type")
if ls_type = 'column' then
ll_col_id = long( idw_obj.describe( ls_control+".id" ) )
end if
end if
for i = 1 to upperbound(ls_cache_types[])
if ls_cache_types[i] = ls_type then
ll_cache_begin = ll_cache_begins[i]
ll_cache_end = ll_cache_ends[i]
exit
end if
next
if ll_cache_begin > 0 then
dw_attributes.rowscopy( ll_cache_begin, ll_cache_end, primary!, dw_attributes, ll_rows + 1, primary!)
ls_control_names[] = ls_empty[]
ls_types[] = ls_empty[]
ll_column_ids[] = ll_empty[]
ll_uids[] = ll_empty[]
for i = 1 to ll_cache_end - ll_cache_begin + 1
ls_control_names[i] = ls_control
ls_types[i] = ls_type
ll_column_ids[i] = ll_col_id
ll_uids[i] = ll_rows + i
next
ll_cache_end += ll_rows + 1 - ll_cache_begin
ll_cache_begin = ll_rows + 1
dw_attributes.object.control_name[ll_cache_begin, ll_cache_end] = ls_control_names[]
dw_attributes.object.control_type[ll_cache_begin, ll_cache_end] = ls_types[]
dw_attributes.object.column_id[ll_cache_begin, ll_cache_end] = ll_column_ids[]
dw_attributes.object.uid[ll_cache_begin, ll_cache_end] = ll_uids[]
ll_rows = dw_attributes.rowcount( )
else
ls_properties = trim(idw_obj.describe(ls_control+".attributes"),true)+"~t"
ll_cache_begin = ll_rows + 1
do
ll_prop_end = pos( ls_properties, "~t", ll_prop_start + 1 )
if ll_prop_end <> 0 then
ls_property = mid( ls_properties, ll_prop_start, ll_prop_end - ll_prop_start )
ll_prop_start = ll_prop_end + 1
ls_data += ls_type + "~t" + ls_control + "~t" + ls_property + "~t" + string(ll_col_id) + "~t"+string(row)+"~r~n"
row ++
end if
loop while ll_prop_end > 0
dw_attributes.importstring( Text!, ls_data)
ll_rows = dw_attributes.rowcount( )
ll_cache_end = ll_rows
ls_cache_types[upperbound(ls_cache_types[])+1] = ls_type
ll_cache_begins[upperbound(ll_cache_begins[])+1] = ll_cache_begin
ll_cache_ends[upperbound(ll_cache_ends[])+1] = ll_cache_end
ls_data = ""
end if
end if
loop while ll_pos_end > 0
The previous code takes about 183 ms to cache the sample dataobject and the new code takes 15 ms, it is now more than 10 times faster. It looks like to be only 160ms but when working a huge dataobject it makes a big difference!
The new version improves controls and attributes filtering but there are missing features:

context menu, show/hide control by types
Also optimizing the auto_resizer object to use less classdefinition
call.
So working on that context menu before releasing the first public release.
Stay tuned!
Thanks, I have recently been looking for info about this topic for ages and yours is the best I’ve discovered so far. However, what about the bottom line? Are you sure in regards to the source?
About “stay tuned” ? 😉
thanks this information sangat bermanfaat
Nice post,thanks for sharing
Good article, thanks for sharing, please visit
thanks for info
Visit Us
Thanks for sharing
Visit our website <a href="https://ittelkom-jkt.ac.id/http://akademitelkom.ac.id/ "
Mantap informasinya gan! terimakasih