1. James Medick
  2. PowerBuilder
  3. Sunday, 23 February 2020 20:00 PM UTC

I've build 3 dddws in a detail window, only one row in the detail window.  the dddws are dependent, thrid on the second, second on the first.  I use GetChild and send variables to the SQL to get the appropriate result set.  This works, but when the change occurs through itemchanged, the key displays initially instead of the display for the dddw.  If I click on the dddw, the display values are there and I can choose one, but until I do so only the key values display.

I think I've seen this somewhere before but can't seem to find out where.

James Medick Accepted Answer Pending Moderation
  1. Wednesday, 26 February 2020 20:43 PM UTC
  2. PowerBuilder
  3. # 1

Thanks Chris,

I tried changing the focus as suggested but it didn't work.  I find that I just can't get the ItemChanged event to give me the latest value with a GetItemXXX.  It always returns the previous, original value as the buffer hasn't been updated.

Doing two linked dddws is a snap since the <Data> variable holds the value of the key chosen from the first dddw and can be used to retrieve the correct data for the second dddw.  Of course, you know all this.

Its trying to get the value from the 2nd dddw to use for the 3rd that's the problem.  Posting an event or changing column focus doesn't work regardless of Retrieve or Filter.

Is there no way to get the key from the 2nd dddw?  I've got about 3 days into this and am stymied.

Comment
  1. Chris Pollach @Appeon
  2. Wednesday, 26 February 2020 20:57 PM UTC
Hi James;

If you want to create a simple test case PB App and then attach it to this forum post ... I'll see if I can then "tweak" it for you to make the DDDW's work the way it does for me in my framework. ;-)

Regards ... Chris
  1. Helpful
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Monday, 24 February 2020 19:21 PM UTC
  2. PowerBuilder
  3. # 2

Hi James;

  FYI ... The other way to approach the issue is not using the ItemChanged event but the DDDW Closed event (which I normally use).

  Here is how this approach works.

1) Declare a User event on the DC and map this to "pbm_dwCloseddropdown" event ID.

2) On the UE from Step #1, code for example ...

String  ls_column
Long    ll_row

ls_column = THIS.GetColumnname ( )
ll_row       = THIS.GetRow ( )
ls_column = THIS.describe ( "evaluate('lookupdisplay(" + ls_column + ")'," + String (ll_row) + ")" )
THIS.Title = "DDDW Closed - "    + ls_column

  The result will be ...

Food for thought. Also, now you're Apps will always know when the DDDW collapsed.  ;-)

Regards ... Chris

Comment
  1. Chris Pollach @Appeon
  2. Monday, 24 February 2020 20:48 PM UTC
Hi James;

The UE should be against the DataWindow Control. Preferably (IMHO) on an Ancestor thereof.

Only DW Controls fire this event for their DDDW children. Tab controls have no idea what a DDDW is.

HTH

Regards ... Chris
  1. Helpful
  1. James Medick
  2. Tuesday, 25 February 2020 15:59 PM UTC
Hi Chris,



The UE is on the tabpage_1 datawindow but does not fire. Apparently, this is a known bug in PB? (*Phenomenon: The DW Control can be assigned two DDDW events (drop & close) by utilizing the User Event feature and mapping them to the pbm_dwndropdown and pbm_dwclosedropdown respectively Windows message ID's. The "Drop" event fires correctly on a mouse click or ALT+TAB. However when the DDDW collapses (closes), the pbm_dwclosedropdown event does NOT fire.)

  1. Helpful
  1. Chris Pollach @Appeon
  2. Tuesday, 25 February 2020 17:28 PM UTC
Hi James;

That UE works OK for me. However, I just noticed that my framework compensates for this event not firing all the time via generic ancestor code to "tweak" the focus - whcih then fires the DDDW Closed UE.



Please try something like this on your DWO's ItemChanged Event ...



String ls_name

ls_name = String ( DWO.name )

IF ls_name = "manager_id" THEN

THIS.SetRedraw ( FALSE)

THIS.SetColumn ( "emp_fname" )

THIS.Setcolumn ( ls_name )

THIS.SetRedraw ( TRUE )

END IF



Note: Replacing the column name "emp_fname" with another column in your DWO and where "manager_id" is the name of the parent column to the DDDW.



Regards ... Chris
  1. Helpful
There are no comments made yet.
James Medick Accepted Answer Pending Moderation
  1. Monday, 24 February 2020 16:14 PM UTC
  2. PowerBuilder
  3. # 3

I've tried all the various permutations I can think of.    Whichever column is changed by the ItemChanged code, the correct key is chosen but the display value will never show until the user actually clicks on the DDDW column.

  • I'm using a retrieve method, sending a variable to the SQL for the DDDWs. 
  • I've tried the get/set on the key value after the retrieve in the ItemChanged event, no luck. I also tried setting focus on the column but again, no luck. 
  • Doing a describe / evaluate on the column results in returning the key value, not the display value.

It appears that the code to swap the display for the key value in the DDDW only fires when someone clicks on the column.  Makes sense, but not here.

I'm wondering whether filtering would work rather than retrieving.  It seems like it could be a lot to filter at some point, but I could try it.

Comment
  1. Michael Kramer
  2. Monday, 24 February 2020 17:35 PM UTC
Now 6:30 PM in Amsterdam. I will try to see what I can do in code tomorrow. - unless someone else already replied with a solution.
  1. Helpful
There are no comments made yet.
James Medick Accepted Answer Pending Moderation
  1. Sunday, 23 February 2020 23:18 PM UTC
  2. PowerBuilder
  3. # 4

Thanks Michael.

The code I have works except for...

Of the 3 dddw, Vendor, Make, Model, changing vendor will change the available makes (selecting for that vendor), and changing the Make will similarly change the list of available Models for that Make - Vendor.  I get the right result, but the display value of the dddws shows the key initially.  When I click on the key (number), then the appropriate text displays in the dddw.  I'm doing this from the ItemChanged event in a Tabpage.

I tried posting an event from the itemchanged but PB doesn't like it.  The Boolean result is 'False' and the event won't trigger.  The same posting code works if I put it in a different object, like the window.

So the data is correct but the display lags for some reason.

Comment
  1. Michael Kramer
  2. Monday, 24 February 2020 06:00 AM UTC


Ah, gotcha! - - That behavior is wellknown.

Q1 > Do you Filter or Retrieve to change content of the DDDW?

Q2 > (I haven't tried this myself recently so I don't remember if it solves the issue): Have you tried - AFTER DDDW content was refreshed/filtered/retrieved - to do GetItem/SetItem of the existing key value?

If that doesn't work, I will dig a little further since it is straightforward to reproduce! - unless someone else beats me returning with fix.

Vendor>Make>Model - Vehicles? I developed/architected apps for Danish Road Safety & Transport Agency for more than a decade. Among them a type approval app where we had Vendor>Make>Model DDDWs - and a lot more tech data on vehicle construction.
  1. Helpful
There are no comments made yet.
Michael Kramer Accepted Answer Pending Moderation
  1. Sunday, 23 February 2020 21:32 PM UTC
  2. PowerBuilder
  3. # 5

Hey James,

Chris refers to how you can obtain DISPLAY value related to CURRENT DATA value in an item = <row, column>.
NOTE: In ItemChanged that code would obtain display value for OLD data value. Reason why ItemChanged has triggered is that the OLD value is most probably replaced by a NEW value - and your code probably wants to work on the NEW value. ==> So, it's complicated!

During ItemChanged new value hasn't reached the DW buffer yet, so any GetItemXxx stuff still refer to former value in current item = current <row, column>.

When some function (same for event) reads data from DW buffers it only works within ItemChanged if you do explicit SetItem before calling that function.

When you have AllowEdit = true you have to handle case where user entered DISPLAY value instead of DATA value. Typically, use dddw.Find to check for data value. If not found, do dddw.Find to check for display value on the display column. That is the order that DW engine's internal logic uses.

This kind of logic you probably want to write generic and encapsulate in ancestor class because it quickly becomes complex and repetitious. Remember display value's datatype may differ from data value's datatype -and- data parameter itself in ItemChanged is string whereas data column in buffer quite often is numeric!

 

 

I found the easiest way to resolve this is to POST whatever consequential action from ItemChanged to ensure data arrived safely in DW buffer before acting on it. Quite often that POST solves the issue. Other times, you have to handle all validation + conversions in-flight ==> complex data/display lookup + datatype conversions.

NOTE: PFC's logic for DDDW handling during ItemChanged has most of the code you probably need. So may the framework your app is already using. Even if your app uses different framework the PFC framework's DDDW handling may inspire you.

HTH /Michael

Comment
There are no comments made yet.
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Sunday, 23 February 2020 20:35 PM UTC
  2. PowerBuilder
  3. # 6

Hi James;

  On the ItemChanged event, use the following ...

ls_display = dw_1.describe("evaluate(l'ookupdisplay(column)',row)")

HTH

Regards ... Chris

Comment
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.