Powerbuilder DataWindow Script Techniques
How do I set a property for an entire column?
1 2 | Modify("shft_id.visible = 0") Modify("shft_desc.protect = 1") |
How many rows selected?
1 | Li_select_count = integer(dw_1.Describe("Evaluate('Sum(if(IsSelected (), 1, 0))', 0)")) |
How do I check the name of the DataWindow?
1 | adw_current.ClassName() = 'dw_handwork_finishing' |
Putting a Help button on a DataWindow dialog box
DataWindow dialog boxes, such as the ones which may come up for Sort( ) and Filter( ) after the Setxxx is passed a string variable with a Null value, can have a Help button appear. For details see 14-8 of the Mastering DataWindows 6.0 book.
How do I dynamically create and destroy bit maps in a datawindow?
You can dynamically create and destroy objects (such as text, bitmaps, and graphic objects) in a DataWindow object using CREATE and DESTROY requests as part of the Modify() function
This statement adds a bitmap named Logo to the header area for group level 1 in the DataWindow object:
1 2 3 | Dw_1.Modify("CREATE bitmap(band=header.1 " & + "x='1985' y='4' height='128' width='146' " & + "filename='C: \PICS\LOGO.BMP' name=logo ")) |
The following statement destroys a bitmap object named logo:
1 | Dw_Modify("DESTROY logo") |
Smart Filter (way cool)
Outside the datawindow, a sle exists. Whatever the user enters into this field will filter the datawindow . Any columns which do not include the entered string are excluded.
1. Create a computed column on the datawindow called c_key. This will contain a string of all the columns you wish to include in the filter. Any numbers or dates need to be converted to strings.
2. Do whatever you need to do to make this computed column not visible to the user
3.Add a single line edit with the following user event mapped to pbm_keyup
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | //////////////////////////////////////////////////////////////////////////// // // Event: sle_filter:ue_keyup (pbm_keyup) // ////////////////////////////////////////////////////////////////////////////// String ls_Filter, ls_text ls_text = Upper(This.Text) If ls_text = "" Then ls_Filter = "" Else ls_Filter = 'match (c_key, "' + ls_text + '")' End If dw_1.SetFilter(ls_Filter) dw_1.Filter() |
In a datawindow, how do I have the “Enter” key work like a tab?
You will need to declare a user event
ue_ReturnAsTab pbm_dwnprocessenter
In the ue_returnastab event code;
1 2 | Send(Handle(this),256,9,Long(0,0) Return 1 |
This is now part of the pfd_u_dw and the functionality is turned on by adding the following to the constructor event:
ib_enterastab = True
SetItem is too slow
When you have a need for speed:
Traditional method
1 2 3 4 5 | Dw_example.InsertRow(0) Dw_example.SetItem(1, "StringCol1", "Hello, There") Dw_example.SetItem(1, "NumberCol1", 100) Dw_example.SetItem(1, "NumberCol2", 200) Dw_example.SetItem(1, "StringCol2", "Hello, Again") |
Faster method
1 | Dw_example.ImportString("Hello, theres~t100~t200~tHello, Again") |
How do I make a datawindow read only?
1 | Dw_1.object.DataWindow.ReadOnly = 'yes' |
Can you create an html form for a datawindow and datastore?
Yes, by using the GenerateHtmlForm function.
How do I coordinate the update of multiple DataWindows?
Update( ) will accept two parameters, AcceptText and ResetFlags. The default is True, True
Accept text True means that the edit control is sent to the DataWindow. DataWindow validation is performed.
ResetFlag = False will not reset the status flags. This must be done with the ResetUpdate( ) function.
Example:
1 2 3 4 5 6 7 8 9 10 | IF dw_1.Update(True, False) = 1 THEN IF dw_2.Updte( ) = 1 THE COMMIT USING SQLCA Dw_2.ResetUpdate( ) ELSE ROLLBACK USING SQLCA END IF ELSE ROLLBACK USING SQLCA END IF |
When a data entry fills an entire field, how do I make the cursor skip to the next field?
<!–[if !supportLists]–>1. Auto Skip property of Edit Mask
When this box is checked on the Mask property sheet of the EditMask control, the user’s cursor will automatically skip to the next control in the tabbing order after entering all the characters allowed by the mask. If this box is not checked, the cursor will not skip automatically to the next control.
The AutoSkip property is a boolean value. This example enables automatic skipping to the next control.
em_1.AutoSkip = TRUE
2. The EditChanged Event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | Integer li_max_col_size, li_rc String ls_col_name, ls_nextcol, ls_coldata Choose Case dwo.Name Case "system_no" li_max_col_size = 3 ls_nextcol = "acct_code" Case "acct_code" li_max_col_size = 3 ls_nextcol = "application_name" Case "dev_year" li_max_col_size = 4 ls_nextcol = "last_application_upgrade_date" Case "app_fail_year" li_max_col_size = 4 ls_nextcol = "shared_data_desc" // CASE "last_application_upgrade_date" // li_max_col_size = Case Else Return 0 End Choose ls_col_name = dwo.Name GetItemString(row, ls_col_name) If Len(GetItemString(row, ls_col_name)) > 0 Then Return If Len(Data) >= li_max_col_size Then li_rc = This.AcceptText( ) If li_rc = 1 Then li_rc = This.SetColumn(ls_nextcol) If li_rc = -1 Then MessageBox("edit changed event”, “Unknown column ~"" + ls_nextcol + "~"") End If Else Return 0 End If End If |
I get the following Run Time Error: A PowerBuilder message box “Datawindow Error”, “Value Required For This Item”
I got this from doing a describe (Evaluate (‘LookUpDisplay(pos_cd)’,1)). In my case the datawindow column name in the Column Specification panel shows that the actual column name is different than the DB Name.
I have a hh:mm editmask on a a datetime field, when I update the time, it sets the Date part to “01/01/2000”
You need to find the correct date value through some other means, parse the new time from the data argument and glue the two together.
What is the difference between SELECT and PBSELECT
PBSELECT is generic database independent SQL which is stored in the DataWindow.The actual outer join SQL for native Sybase connection will differ from an ODBC Sybase connection.
About DataWindow properties
All DataWindow object properties are stored as strings, but you can represent the values in more than one way when assigning.For example, the following statements are equivelent
1 2 | Dw_1.Object.DataWindow.Border = ‘0’ Dw_1.Object.DataWindow..Border = 0 |
As is
1 2 | Dw_1.Object.DataWindow.ReadOnly = "yes" Dw_1.Object.DataWindow.ReadOnly = True |
How do I make a column not modify in script.
1 | dw_selected.Modify(ls_colname+".Update=No") |
How do I dynamically change a column’s tab order?
Modify
1 | <DW Control Name>.Modify("<Columnname>.TabSequence='<an integer>'") |
Dot notation
1 | <DW Control Name>.Object.<Columnname>.TabSequence='<an integer>' |
Evaluate( )
The evaluate( ) function is available for use with Describe( ).Evaluate( ) lets you evaluate DataWindow expressions within a script using data in the DataWindow.It has the following syntax:
Evaluate(‘Expression’, Rownumber)
The expression usually includes DataWindow painter functions that cannot be called in a script.The following example returns the display value for the dept_id column for the current row:
1 2 3 | String ls_rownum., ls_return Ls_rownum = String(dw_1.GetRow( )) Ls_return = dw_1.Describe("Evaluate('LookUpDisplay(dept_id)'," + ls_rownum + ")") |
LookupDisplay() is a common use of Evaluate()
1 2 3 4 5 6 | string ls_dept long ll_row ll_row = 3 // we want the displayed value of dept_id in row 3 ls_dept = dw_1.Describe("Evaluate('LookupDisplay(dept_id)', " + String(ll_row) + ")") |
Find( )
The following snippet does a case insensitive Find( )
1 2 3 4 5 6 | ll_row_cnt = ids_win_dw.rowcount( ) as_window_name = Lower(as_window_name) as_dw_name = Lower(as_dw_name) ls_findexp = "Lower(window_name) = '" + as_window_name + "' and Lower(datawindow_name) = '" + as_dw_name + "'" ll_row = ids_win_dw.Find(ls_findexp, 1, ll_row_Cnt) |
RowsDiscard()
1 | dwcontrol.RowsDiscard (startrow, endrow, buffer ) |
Sort()
1 2 | Dw_1.SetSort(“status A, salary D”) Dw_1.Sort( ) |
You can also sort by column number instead of column name.
1 | Dw_1.SetSort(‘#1 A, #4 D”) |
To sort a DataWindow object with groups, call GroupCalc( ) after you call Sort( ). GroupCalc forces the DataWindow engine to recalculate the breaks in the grouping levels after you have added or modified rows in a DataWindow.
To have a “Specify Sort Columns” dialog box appear, set a string variable to NULL, and pass it as the argument to SetSort( ).A subsequent Sort( ) will open the dialog box.
How do I change a column’s tab order is script?
1 | Dw_1.SetTabOrder(column, tabnumber) |
What if AcceptText() causes a validation error?
It will return a -1
Working with DDDWProperties
The following example returns the display value for the dept_id column for the current row:
1 2 3 4 | String ls_rownum., ls_return ls_rownum = String(dw_1.GetRow( )) ls_return = dw_1.Describe("Evaluate('LookUpDisplay(dept_id)'," + ls_rownum + ")") |
Another Example:
1 | astr_parms.s_worker_nm = dw_1.Describe(“Evaluate(LookUpDisplay(day2_off_wrkr_id)’, 1”) |
One more example
1 2 3 | s_res_nm = dw_res_grp.Describe("Evaluate('LookUpDisplay(res_grp_id) ', 1)" ) ls_pos_nm = dw_pos.Describe("Evaluate('LookUpDisplay(pos_rsrc_id) ', 1)" ) ls_pos_nm = ls_res_nm + " / " + ls_pos_nm |
In the ItemChanged event, I want to Reject the value of a column with a DDDW and allow the focus to change.But Return 2 does not seem to work.
Return 2 is changing the column item back to the original value, but the Display Item does not change.The DataWindow has rejected the value, but it is still displaying the changed value.Here is script which deals with this problem:
ItemChanged event:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Integer li_rc If data<> is_normal_trade_on_shift then li_rc = MessageBox("Warning", '~"' + istr_emp.trade_off_shift "shift normally trades with " + is_normal_trade_on_shift + " shift ", Information!, OkCancel!, 1) If li_rc = 2 then // reject the value, allow focus to change This.event Post ue_refresh_display() Return 2 End if End if Wf_EmployeeFilter(data) Wf_ShiftOrLocationChange() Return 0 |
Ue_Refresh Display event:
1 2 3 4 | String ls_shift ls_shift = this.GetItemString(1, "shft_cd") This.SetItem(1, "shft_cd", ls_shift) |
How do I dynamically change a dddw properties?
Peter Louis wrote an interesting user object for holding a simple datawindow with two colums, one for string, the other for a long.This function sets the dw and its associated dddw for either the String column or the long column.The column not being used is turned invisible.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | /////////////////////////////////////////////////////////////////// // // //Event/Function: of_set_datawindow / //Access: Public // //Arguments: al_data_type {Use the “Long” or “String” column} // as_dw (The name of the dddw) // as_data_col (The id column of the dddw) // as_display_col (The display column of the dddw) // ab_filter_required // as_err_msg // //Returns: true if successful. // //Description: sets the datawindow. // ////////////////////////////////////////////////////////////////////// Boolean lb_return = True String ls_result, ls_filter datawindowchild ldwc If al_data_type = icl_datatype_string Then is_column = "string" is_data_col = as_data_col dw_generic.Modify("long.visible = 0" ) ElseIf al_data_type = icl_datatype_long Then is_column = "long" is_data_col = as_data_col dw_generic.Modify("string.visible = 0" ) Else as_err_msg = "of_set_datawindow: The specified data type is not supported." lb_return = False End If If lb_return Then is_display_col = as_display_col is_dw_object = as_dw dw_generic.InsertRow(0) dw_generic.SetItem(1, "enabled", 1) // static style dw_generic.Modify(is_column + ".dddw.Required=No" ) dw_generic.Modify(is_column + ".dddw.AllowEdit=No" ) dw_generic.Modify(is_column + ".dddw.Line=10" ) dw_generic.Modify(is_column + ".dddw.ShowList=No" ) dw_generic.Modify(is_column + ".dddw.UseAsBorder=Yes" ) dw_generic.Modify(is_column + ".dddw.VScrollBar=Yes" ) ls_result = dw_generic.Modify(is_column + ".dddw.name = '" + is_dw_object + "'" ) If ls_result <> "" Then lb_return = False as_err_msg = "of_set_datawindow: Failed to set the dddw.name: " + ls_result End If End If If lb_return Then ls_result = dw_generic.Modify(is_column + ".dddw.datacolumn = '" + is_data_col + "'" ) If ls_result <> "" Then lb_return = False as_err_msg = "of_set_datawindow: Failed to set the dddw.datacolumn: " + ls_result End If End If If lb_return Then ls_result = dw_generic.Modify(is_column + ".dddw.displaycolumn = '" + is_display_col + "'" ) If ls_result <> "" Then lb_return = False as_err_msg = "of_set_datawindow: Failed to set the dddw.displaycolumn: " + ls_result End If End If If lb_return Then dw_generic.GetChild(is_column, ldwc) If Not IsValid(ldwc) Then lb_return = False as_err_msg = "of_set_datawindow: Failed to obtain the child datawindow." End If End If If lb_return Then If ldwc.SetTransObject(SQLCA) <> 1 Then lb_return = False as_err_msg = "of_set_datawindow: Failed to set the transaction object." End If End If If lb_return Then If ldwc.Retrieve() = -1 Then lb_return = False as_err_msg = "of_set_datawindow: Failed to retrieve the child datawindow." End If End If If lb_return Then If ab_filter_required Then ib_filter_required = True ls_filter = is_data_col + " <> " + is_data_col If ldwc.SetFilter(ls_filter) = -1 Then lb_return = False as_err_msg = "of_set_datawindow: Failed to set filter string." End If If lb_return Then If ldwc.Filter() = -1 Then lb_return = False as_err_msg = "of_set_datawindow: Failed to filter the dddw." End If End If End If End If Return lb_return |
Dot Notation
1 2 3 4 | ls_data = dw_bd_job.Object.bd_tp_cd.dddw.lines MessageBox("", ls_data) dw_bd_job.Object.bd_tp_cd.dddw.lines = 5 |
What are the DDDW properties?
- AllowEdit
- AutoHScroll
- Case
- DataColumn
- DisplayColumn
- HScrollBar
- HSplitScroll
- Limit
- Line
- Name
- NilIsNull
- PercentWidth
- Required
- ShowList
- UseAsBorder
RowsCopy
RowsCopy will copy the contents of one datawindow/datastore to another. The RowStatus flags for each row will be NewModified!
dwsource.RowsCopy(startrow, endrow, copybuffer, dwtarget, beforerow, targetbuffer )
Example:
1 | lds_newlog.RowsCopy(1, ll_row_cnt, Primary!, this, 1, Primary!) |
RowsMove
The rows moved to the target DataWindow have the status NewModified!
1 | dwsource.RowsMove ( startrow, endrow, movebuffer, dwtarget, beforerow, targetbuffer ) |
How do I dynamically change a group property?
ll_color = RGB(200, 200, 500)
dw_1.Modify(“DataWindow.Header.2.Color=” + String(ll_color))
dw_1.Modify(“DataWindow.Trailer.2.Height=500”)
How do I expand hidden rows in a group?
In this example, a DataWindow hides the detail rows and shows only the group summaries and headers.If a checkbox “Explode Details” is clicked, the following script is fired:
1 2 3 4 5 6 7 8 9 | integer li_height if this.Checked = TRUE then li_height = 64 else li_height = 0 end if dw_report.Object.DataWindow.Detail.Height = li_height |
How do I get the value of the items in a group trailer or header?
The clicked event gives the following arguments: x, y, row, and dwo.Because clicking on a trailer returns a row of 0, you can not directly do a GetItem().Instead, after you interrogate the dwo to determine that you are in the trailer, use the function GetBandAtPointer().Here are the results:
Band | Location of pointer | Associated row |
detail | In the body of the DataWindow object | The row at the pointer. If rows do not fill the body of the DataWindow object because of a group with a page break, then the first row of the next group. If the body isn’t filled because there are no more rows, then the last row |
header | In the header of the DataWindow object | The first row visible in the DataWindow body |
header.n | In the header of group level n | The first row of the group |
trailer.n | In the trailer of group level n | The last row of the group |
footer | In the footer of the DataWindow object | The last row visible in the DataWindow body |
summary | In the summary of the DataWindow object | The last row before the summary |
Returns a string that names the band in which the pointer is located, followed by a tab character and the number of the row associated with the band (see the table in Usage). Returns the empty string (“”) if an error occurs.
If you have the last row in a group, and you need to find the first row in the group, cycle through the rows with FindGroupChange().
What is FindGroupChange(long, integer)
long dwcontrol.FindGroupChange ( long row, integer level )
The first argument is the row you wish to start your search (use 0 to start at the very beginning).The second argument is the group number.The return value is the row where the group changes.
Here is an example from PB Help:
This statement searches for the first break in group 2 in dw_regions. The search begins in row 5:
dw_regions.FindGroupChange(5, 2)
Example of finding the range of rows for a group
If the user clicks on a group trailer band, the following script will call the function to calculate which rows that group begins and ends, and then expands them.Note: the detail band begins with a height of zero and a calculated column called EXPAND_LEVEL with the value of empty string.This column is hidden behind another column and has its autosize attribute set to TRUE.EXPAND_LEVEL begins with a height of zero.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | /////////////////////////////////////////////////////////////////////// // // Event: dw_Report:Clicked ////////////////////////////////////////////////////////////////////////////// Boolean lb_continue = True Double ld_indirect_hrs Integer li_band, li_pos_grp, li_pos_tab, li_group Long ll_range_begin, ll_range_end, ll_last_row_in_group, ll_row String ls_band, ls_group, ls_last_row_in_group w_frame lw_frame ls_band = This.GetBandAtPointer() //trailer.1[tab]5 If Mid(ls_band, 1, 7) <> "trailer" Then lb_continue = False End If If lb_continue Then li_pos_grp = Pos(ls_band, ".") If li_pos_grp > 1 Then li_pos_grp ++ Else lb_continue = False End If End If If lb_continue Then li_pos_tab = Pos(ls_band, "~t", li_pos_grp) // ~t = [tab] If li_pos_tab < 1 Then lb_continue = False End If End If If lb_continue Then ls_group = Trim(Mid(ls_band,li_pos_grp, li_pos_tab - li_pos_grp)) If IsNumber(ls_group) Then li_group = Integer(ls_group) Else lb_continue = False End If End If If lb_continue Then ls_last_row_in_group = Trim(Mid(ls_band, li_pos_tab + 1)) If IsNumber(ls_last_row_in_group) Then ll_last_row_in_group = Integer(ls_last_row_in_group) Else lb_continue = False End If End If If lb_continue Then If wf_GetGroupRange(ll_range_begin, ll_range_end, ll_last_row_in_group, li_group) <> SUCCESS Then lb_continue = False End If End If If lb_continue Then lw_frame = gnv_app.of_GetFrame() lw_frame.SetMicroHelp("Expanding Group...") This.SetRedraw(False) SetPointer(HourGlass!) For ll_row = ll_range_begin To ll_range_end ld_indirect_hrs = This.GetItemNumber(ll_row, "indirect_hrs") If ld_indirect_hrs > 0 Then dw_report.SetItem(ll_row, "EXPAND_LEVEL", "Y") End If Next This.SetRedraw(True) lw_frame.SetMicroHelp("Ready") End If |
This is called from the DataWindow clicked event if the user clicks on a group trailer:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | ////////////////////////////////////////////////////////////////////// // // // Function: wf_GetGroupRange // // Access: Protected // // Description: // // Arguments: long al_group_begin ref // long al_group_end ref // long al_last_row_in_group ref // integer ai_group // // Returns: integer ////////////////////////////////////////////////////////////////////////////// Integer li_rc = SUCCESS, li_indx Long ll_grp_end[], ll_next_grp al_group_begin = 0 al_group_end = 0 If li_rc = SUCCESS Then If dw_report.RowCount() < 1 Then li_rc = NO_ACTION End If End If If li_rc = SUCCESS Then If al_last_row_in_group > dw_report.RowCount() Then li_rc = FAILURE End If End If If li_rc = SUCCESS Then ll_next_grp = 1 Do While ll_next_grp < al_last_row_in_group li_indx ++ ll_next_grp = dw_report.FindGroupChange(ll_next_grp + 1, ai_group) If ll_next_grp > 0 Then ll_grp_end[li_indx] = ll_next_grp - 1 Else ll_grp_end[li_indx] = dw_report.RowCount() ll_next_grp = dw_report.RowCount() End If Loop al_group_end = ll_grp_end[li_indx] If li_indx = 1 Then al_group_begin = 1 Else al_group_begin = ll_grp_end[li_indx - 1] + 1 End If End If Return li_rc |
Looping through a group
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | ll_count = dw_rpt.RowCount() ll_first_row_in_group = 1 ll_last_row_in_group = 0 li_sum_row = 0 Do While ll_last_row_in_group < ll_count ll_next_group = dw_rpt.FindGroupChange(ll_last_row_in_group + 2, 1) // row, group If ll_next_group = 0 Then ll_next_group = ll_count ll_last_row_in_group = ll_count Else ll_last_row_in_group = ll_next_group - 1 End If li_group_cnt = 0 ld_shed_hrs = 0 ll_cutoffs = 0 ls_week = dw_rpt.GetItemString(dw_rpt.FindGroupChange(ll_first_row_in_group, 1), "c_week") ls_loc = dw_rpt.GetItemString(dw_rpt.FindGroupChange(ll_first_row_in_group, 1), "location_name") ls_res_grp = dw_rpt.GetItemString(dw_rpt.FindGroupChange(ll_first_row_in_group, 1), "v_resrc_nm") For ll_row = ll_first_row_in_group To ll_last_row_in_group ld_shed_hrs += dw_rpt.GetItemNumber(ll_row, "util_hrs") ll_cutoffs += dw_rpt.GetItemNumber(ll_row, "ctff_qty") li_group_cnt ++ Next li_sum_row ++ dw_util.InsertRow(0) dw_util.SetItem(li_sum_row, "week", ls_week) dw_util.SetItem(li_sum_row, "location", ls_loc) dw_util.SetItem(li_sum_row, "resource_group", ls_res_grp) dw_util.SetItem(li_sum_row, "sched_hrs", ld_shed_hrs) dw_util.SetItem(li_sum_row, "cutoffs", ll_cutoffs) If ld_shed_hrs > 0 Then dw_util.SetItem(li_sum_row, "rate", ll_cutoffs/ld_shed_hrs) End If dw_util.SetItem(li_sum_row, "util_pct", (ld_shed_hrs/24)/li_group_cnt) ll_first_row_in_group = ll_last_row_in_group + 1 Loop dw_util.SaveAs("", Excel5!, True) |
My Groups seem to be working fine, except they are not sorted.
This was a killer problem I faced in Dec ’99 at QG.I wanted to have my groups appear in YEAR, Month order, but they were sometimes jumbled.My SQL needed an order by clause.Note, when you create or edit a group (Rows>Create Group) there is a sort by tab.Beware: when you drag the columns you want to sort by, you may actually drop the SUM(<col> FOR GROUP 1).
GetSelectedRow(long)
Reports the number of the next highlighted row after a specified row in a DataWindow control or DataStore object.Argument is the row after which you want to search for the next selected row. Specify 0 to begin searching at the first row
Returns the number of the first row that is selected after row indwcontrol. Returns 0 if no row is selected after the specified row.
1 | Li_row = dw_employee.GetSelectedRow(0) |
Print Events
- PrintStart
- PrintPage
- PrintEnd
In the PrintPage event, a RETURN 1 will skip the next page to be printed.
How do I get a report to print landscape?
1 | Dw_1.Object.DataWindow.Print.Orientation = 1 //Landscape |
How do I print only a range of pages?
1 | Dw_1.Object.DataWindow.Print.Page.Range = "5-10" |
How do I print several DataWindows in the same print job?
Open a print job and use PrintDataWindow( ) function for each DataWindow.
1 2 3 4 5 6 7 8 | Long li_jobnum Ll_jobnum = PrintOpen( ) If Ll_jobnum > 0 Then PrintDataWindow(Ll_jobnum, dw_1) PrintDataWindow(Ll_jobnum, dw_2) PrintClose( ) End If |
How do I cancel a print job?
How job was started | Function to use |
Dw_1.Print | PrintCancel( ) |
PrintOpen( ) | PrintCancel(jobnumber) |
Some of my text is in red (or some other color other than black) on the display, but this red text does not appear when I print the report.
Check the column background.If it is Transparent, change it to white.
Disabling a button on a datawindow
Datawindow buttons do not have a Disabled property. So showing them as “disabled” is not clear cut.Here is one way
In the datawindow painter, create a static text control of the same size as the button
- Set the border to outline
- Set its text to ”…”
- Text should be bold and colored dark gray
- Move it directly underneath the button
Now hide the button in script to disable it
1 | dw_ff.Object.b_seeded.Visible = ab_switch |
How do I copy a DataWindow value to a variable?
1 | li_seq = dw_1.GetItemNumber(li_row, "SEQ_NO") |
Also GetItemString and GetItemDate( ) GetItemDateTime( ), GetItemDecimal( ), GetItemTime( ) for other datatypes.
OR
1 | Li_seq = dw_1.object.seq_no[li_row] |
How do I update the datawindow with some value stored in a variable?
1 | dw_1.SetItem(li_row, "SEQ_NO", ii_seq_no) |
Note, the variable must be of the same data type as the column in the database.Returns 1 for success-1 for error.
Extracting result set from a datawindow
The ‘datawindow.data’ attribute of a DataWindow represents the result set from the retrieve. By using the Describe() function you will get a string value containing the rows and columns of the results. Within the string the newline character (~n) separates each row, and the tab character (~t) separates each column within the row.
Very long strings inserted into a column are being truncated.
I was inserting a comment string into a computed field.Very long comments were being truncated.Discovered that the length of the column (Datawindow painter, Column specification tab) was set to 1 and PB was truncating after 512 characters.Need to up the column length to 32767.
How do I get a value from the footer or summary band?
Just treat it as a column on every row.Note, there must be at least one row.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | //////////////////////////////////////////////////////////////////////////// // // // Function: wf_GetTotHrs // // Access: Protected // // Description: used by st_total_hrs to get the total hours of the passed dw. // // Arguments: u_dw_lm adw // // Returns: decimal ////////////////////////////////////////////////////////////////////////////// Decimal ld_hrs Integer li_rc = SUCCESS String ls_msg If li_rc = SUCCESS Then If adw <> idw_hw_press And adw <> idw_hw_press And adw <> idw_hw_press Then li_rc = FAILURE ls_msg = “Invalid datawindow passed End If End If If li_rc = SUCCESS Then If adw.RowCount() < 1 Then li_rc = NO_ACTION End If End If If li_rc = SUCCESS Then ld_hrs = adw.Object.hrs_worked_tot[1] End If If li_rc = FAILURE Then MessageBox("wf_GetTotHrs()", ls_msg) End If Return ld_hrs |
How do I set data?
1 | dw_1.object.shft_sched_id[1]= ll_shift_sched_id |
How do I set a column for all the rows to the same value?
If I want to set all row’s STRM_ID column to the value 1234. lsa_default is array with the same size as the number of rows. Eche array element has a value of 1234.
1 | dw_1.Object.strm_id.Primary = lsa_default |
How do I update the static text in the header of a datawindow?
1 | dw_report.Object.t_comail.Text = ls_comail_id |
How do I get data?
1 | Li_seq = dw_1.object.seq_no[li_row] |
The Object property of the DataWindow control lets you specify expressions that refer directly to the data of the DataWindow object in the control. This direct data manipulation allows you to access small and large amounts of data in a single statement, without calling methods.
There are several variations of data expression syntax, divided into three groups. This section summarizes these syntaxes. The syntaxes are described in detail later in this chapter.
Data in columns or computed fields when you know the name
One or all items(if rownum is absent, include either buffer or datasource)
dwcontrol.Object.columnname {.buffer } {.datasource } { [ rownum ] }
Returns a single value (for a specific row number) or an array of values (whenrownum is omitted) from the column.
Selected items
dwcontrol.Object.columnname {.Primary }{.datasource }.Selected
Returns an array of values from the column with an array element for each selected row.
Populating an array witha column’s valuesfor all rows
From a script written by Dan M.
1 2 3 | string lsa_mult_cycl_nbr[] lsa_mult_cycl_nbr = ids_get_mult_cycl_nbr.Object.mult_cycl_nbr.Primary ids_get_multi_mail_pstl_cl_tp.Retrieve(lsa_mult_cycl_nbr) |
Range of items
dwcontrol.Object.columnname {.buffer } {.datasource } [ startrownum,endrownum ]
Returns an array of values from the column with an array element for each row in the range.
Data in numbered columns
Single items
dwcontrol.Object.Data {.buffer } {.datasource } [ rownum, colnum ]
Returns a single item whose data type is the data type of the column.
Blocks of datainvolving a range of rows and columns
dwcontrol.Object.Data {.buffer } {.datasource } [ startrownum, startcolnum, endrownum, endcolnum ]
Returns an array of structures or user objects. The structure elements match the columns in the range. There is one array element for each row in the range.
Whole rows
Single row or all rows
dwcontrol.Object.Data {.buffer } {.datasource } { [ rownum ] }
Returns one structure or user object (for a single row) or an array of them (for all rows). The structure elements match the columns in the DataWindow object.
Selected rows
dwcontrol.Object.Data {.Primary } {.datasource } .Selected
Returns an array of structures or user objects. The structure elements match the columns in the DataWindow object. There is one array element for each selected row.
How do I make a DataWindow Read Only?
To use a DataWindow for reporting purposes only, set its ReadOnly attribute so users can not place focus on its columns.
1 | Dw_1.Object.DataWindow.ReadOnly='yes' |
Modify and Describe
Allows for the dynamic modification and access to the attributes of a datawindow or datastore.Direct access can often accomplish the same thing in a much more readable manner.
Modify and Describe lend themselves more to generic coding techniques as dot notation requires the programmer to hard code the column name.Modify( )and Describe( ) can use the column number.Some things cannot be accessed using dot notation.
For more information, look at the “PowerScript >Techniques” and the “DataBase Painter > Datawindow Expressions “sections.
Format
1 | Dw_1.Modify("object.Attribute=value") |
Examples
1 2 3 | Dw_1.Modify("DataWindow.ReadOnly=Yes") Dw_1.Modify("DataWindow.QueryMode=Yes") Dw_1.Modify("cust_id.Visible=0") |
Direct Access (Dot Notation)
1 2 | Dw_1.object.DataWindow.readonly = 'yes' Dw_1.object.cust_id.visible = 0 |
Tips on Building Modify and Describe Expressions
- DwSyntax Utility
- Examine Datawindow Export code and look for how similar expressions are built.
ItemError Event Return codes
Return Code | Action |
0 | Reject the data value and display an error message |
1 | Reject the datavalue and do not display a message |
2 | Accept the data value |
3 | Reject the data value but let the focus change |
How do I find the data in the underlying data(not the edit control)
1 | String(dwo.primary[row]) |
If I am outside the ItemError Event, how would I find the column data for a particular row?
1 | Dw_1.object.emp_id(dw_1.GetRow()) |
How do I get rid of multiple error messages?
If you code a validation script in the ItemChanged event that displays a MessageBox for invalid values, the default ItemError message box also appears.To prevent he user from seeing two error messages, Return 1.
If you are using the PFC, set the variable ib_itemerror_msg = FALSE.This will not display the default error message.
ItemChanged Event Return codes
Return Code | Action |
0 | Accept the data value |
1 | Reject the data value |
2 | Reject the data value but let the focus change |
Sample ItemChanged Event
1 2 3 4 5 6 7 | Choose Case dwo.Name Case "cust_id" If Upper(Data) = "NEW" Then SetItem( row, String(dwo.Name), of_GetNewCustID()) Return 2 End If End Choose |
In the ItemChanged event, how come changes to the data argument have no impact on what is saved in the column
Because DATA is a copy of what exists in the edit control, changing it does not change the edit control.
Okay, in the ItemChanged event, how do I force a new value using SetItem() into the primary buffer?
If you force a new item into the primary buffer for the affected column, the edit control overwrites this at the conclusion of the ItemChanged event.You need to post to a method which does the SetItem.
Retrieve()
- RetrieveStart
- Return 1 to stop retrieval
- Return 2 to retrieve without reset
- If there are already rows in the datawindow
- RowFocusChanging (newrow = 0)
- Resize (if a scrollbar I showing
- SQL Preview (Select statement)
- RetrieveRow (For each row retrieved)
- Return 1 stops retrieval
- Resize (after a page if there is a vertical scroll bar)
- RowFocusChanging( if row # is not 1)
- RetrieveEnd
Update()
- UpdateStart
- Return 1 to cancel the update
- SQLPreview for each changed row
- Deletes first
- Update & Inserts by row number
- Return 1: Cancel current action
- Return 2: Skip this SQL Statement
Mouse Scroll Wheel (other event)
The user can hold down control and then use the mouse scroll wheel to zoom in or out.This can be disabled with the code below.If you want to disable the scroll wheel all together, you would just remove “AND KeyDown(KeyControl!) ” from the code.
1 2 3 4 5 6 7 | // dw's "other" event Constant Integer LCI_MOUSEWHEEL = 522 If Message.Number = LCI_MOUSEWHEEL And KeyDown (KeyControl!) Then Message.Processed = True Return 1 End If |
How do I append data to a datawindow
In the RetrieveStart event the return code must be 2
Return 2
Return Codes
0 – (Default) Continue.
1 – Do not perform the retrieval.
2 – Do not reset the rows and buffers before retrieving the data from the database.
When does the Error event fire?
TheErrorEvent occurs at execution time as the result of syntax errors in DataWindow property expressions and DataWindow data expressions.If you refer to a nonexistent object, misspell a property name or reference nonexistent data theErrorevent fires.
1 | Dw_1.Object.emp_id.Visible='0' |
In the above example, the compiler examines only up to “dw_1.Object.”Column names and property names are not verified until execution. So if the column “emp_id” does not exist on the datawindow, the Error event is triggered.
Event arguments
- ErrorNumber – unsigned integer
- ErrorText – string
- ErrorWindowMenu – string
- ErrorObject – string
- ErrorScript – string
- ErrorLine – unsigned integer
- Action – ExceptionAction
Valid Action values are ExceptionFail!, ExceptionIgnore!, and ExceptionSubstituteValue!.
If the Action argument is ExceptionFail!, the SystemErrorevent fires.
Example script for changing the return value
Suppose the following code triggers theErrorevent:
1 2 | Is_dwvalue = "5" // instance variable ls_border = dw_1.Object.emp_id.Border |
The following code is in the Error event:
1 2 | Action = ExceptionSubstituteValue! ReturnValue = is_dwvalue |
The DBError event fires in a DataWindow when a database error occurs as a result of an Update( ).
How do I stop the default error window from showing
By default, a modal message window displays the database error code and error message.Change the Return value to 1.
Return 1
Event Arguments
The DBError event contains useful information about the database error
- SQLDBCode DBMS- specific error code
- SQLErrText DBMS – specific error message
- SQLSyntax – SQL statement sent to the DBMS
- Buffer – DataWindow buffer where the error row is located
- Row – Row number of the error row within the buffer
How come the ButtonClicked event doesn’t even fire when I click on a datawindow button?
Here is the situation I found. My datawindow was very wide and I had a button at the end of the row with a hscroll bar.After this button is pressed , the datawindow’s Clicked event first fired and the following script ran:
1 2 3 | If row > 0 Then This.ScrollToRow(row) End If |
This adjusts the horizontal position of the datawindow.And, the ButtonClicked event never fires.To solve this problem, move the buttonclicked script to the Clicked event.
1 2 3 4 5 6 7 8 | If IsValid(dwo) Then Choose Case dwo.Name Case "employee_specific_shortcut" Event Post ue_open_employee_specific() Case "b_bk_issue" Post wf_displaySupJobNbr(row) End Choose End If |
Listing of Datawindow ControlEvents
- ButtonClicked When the user clicks a button.
- ButtonClicking When the user clicks a button. This event occurs before the ButtonClicked event.
- Clicked When the user clicks a noneditable field or between fields in the DataWindow control.Return codes:0 – (Default) Continue processing.1 – Stop processing.
- Constructor Immediately before the Open event occurs in the window.
- DBError When a database error occurs in the DataWindow control.Return codes:0 – (Default) Display the error message.1 – Do not display the error message.
- Destructor Immediately after the Close event occurs in the window.
- DoubleClicked When the user double-clicks a noneditable field or between fields in the DataWindow control.For a RichText presentation style DataWindow, when the user double-clicks in the text.
- DragDrop When a dragged control is dropped on the DataWindow control.
- DragEnter When a dragged control enters the DataWindow control.
- DragLeave When a dragged control leaves the DataWindow control.
- DragWithin When a dragged control is within the DataWindow control.
- EditChanged When a user types in an edit control in the DataWindow control.
- Error When an error is found in a data or property expression for a DataWindow object.
- GetFocus Just before the DataWindow control receives focus (before it is selected and becomes active).
- Help When the user presses the F1 key or drags the context help button (question mark) from the title bar to a menu item or control.
- ItemChanged When a field in the DataWindow has been modified and loses focus (for example, the user presses enter, the tab key, or an arrow key or clicks the mouse on another field within the DataWindow).Return codes:0 – (Default) Accept the data value.1 – Reject the data value and don’t allow focus to change.2 – Reject the data value but allow focus to change.
- ItemError When a field has been modified, the field loses focus (for example, the user presses enter, tab, or an arrow key or clicks the mouse on another field), and the field does not pass the validation rules for its column.Return codes:0 – (Default) Reject the data value and show an error message box.1 – Reject the data value with no message box.2 – Accept the data value.3 – Reject the data value but allow focus to change.If the Return code is 0 or 1 (rejects the data), the field with the incorrect data regains the focus.
- ItemFocusChanged When the current item in the control changes.
- LoseFocus When the DataWindow control loses focus (becomes inactive).
- Other When a Windows message occurs that is not a PowerBuilder event.
- PrintEnd When the printing of the DataWindow ends.
- PrintPage Before each page of the DataWindow is formatted for printing.Return codes:0 – Do not skip a page.1 – Skip a page.
- PrintStart When the printing of the DataWindow starts.
- RButtonDown When the right mouse button is pressed on the control.For a RichText presentation style DataWindow, if PopUp Menu has been turned on, this event will not be triggered when the right mouse button is pressed.
- Resize When the user or a script resizes a DataWindow control.
- RetrieveEnd When the retrieval for the DataWindow is complete.
- RetrieveRow After a row has been retrieved.Return codes:0 – (Default) Continue.1 – Stop the retrieval.
- RetrieveStart When the retrieval for the DataWindow is about to begin.Return codes:0 – (Default) Continue.1 – Do not perform the retrieval.2 – Do not reset the rows and buffers before retrieving the data from the database.
- RowFocusChanged After the current row changes in the DataWindow.
- RowFocusChanging When the current row is about the change in the DataWindow. This event occurs before the RowFocusChanged event.
- ScrollHorizontal When the user scrolls right or left in the DataWindow control with the tab or arrow keys or the scrollbar.
- ScrollVertical When the user scrolls up or down in the DataWindow control with the tab or arrow keys or the scrollbar.
- SQLPreview After a Retrieve, Update, or ReselectRow function call and immediately before the SQL statement is submitted to the DBMS.The following return codes specify the action that takes place when the event occurs after an Update function call only:0 – (Default) Continue.1 – Stop.2 – Skip this request and execute the next request.
- UpdateEnd When all the updates from the DataWindow to the database are complete.
- UpdateStart After an Update function call and just before changes in the DataWindow are sent to the database.Return codes:0 – (Default) Continue.1 – Do not perform the update.
How do I put a DataWindow into query mode?
1 | Dw_1.Object.DataWindow.QueryMode = "yes" |
How do I clear the query criteria?
Criteria entered by users are retained in the DataWindow so they can refine the query.If you want to clear user-entered query criteria:
1 | Dw_1.Object.DataWindow.QueryClear = 'yes' |
What does the QuerySort property do?
Turning query sort mode forces the DataWindow into query mode at the same time.The first row of the DataWindow is dedicated to entering sort criteria, all subsequent rows are dedicated to entering WHERE criteria.
What does a column’s Criteria.Override_edit do?
If this property is set to ‘yes, the edit style overrides anyu other style that was specified such as radio button or dropdown listbox.The user is free to type in any value without restriction.
This property can be set in the DataWindow property or in powerscript:
1 | Dw_1.Objedt.Salary.Criteria.Override_edit = 'yes' |
What does a column’s Criteria.Required do?
If this property is set, a user in query mode may only enter equality criteria in this column.
This property can be set in the DataWindow property or in powerscript:
1 | Dw_1.Objedt.Salary.Criteria.Required = 'yes' |
How do I retrieve the data?
Setting the DataWindow’s query mode criteria to ‘no’ will disable query mode and store the user’s specification for the next Retrieve( )
Prompt for Criteria
When a retrieve is performed, a dialog box appears and prompts the user to supply Retrieval Criteria.
This is set for each column you wish to prompt for criteria.
1 2 | Dw_1.Object.Emp_lname.Criteria.Dialog = 'yes' Dw_1.Object.city.Criteria.Dialog = 'yes' |
Query mode should be off as this could cause conflicting WHERE clause criteria.
If you wan users to specify sort criteria as part of the select, use QuerySort mode
If you want to limit the columns a user can specify criteria, use Prompt for Criteria
Prompt for criteria forces you to use any edit style set in the datawindow painter, query mode allows you to override this.
Levels of Validation
1.Data type correct (failure triggers ItemError event)
2.Pass validation rule (failure triggers ItemError event)
3.Value changed
4.ItemChanged Event
Validation property tab
Triggered by ENTER, TAB, UP ARROW, or DOWN ARROW key or clicks another Datawindow column.An Update( ) or AcceptText( ) function will also cause current input to be validated.
User constructs a Validation Expression and message text.External global functions may be called.
Edit Control data is fetched with GetText( )
Script may read and modify validation rules using GetValidate(“<column name>”) and SetValidate(“<column name>”).
Coding a validation script in the ItemChanged event that displays a message box for invalid values, the ItemError message box also appears.To prevent the user from seeing two error messages, consider handling the message in one place, such as the ItemError event.
To change the message title from “DataWindow Error” to something else, use:
1 | GetApplication( ).dwMessageTitle = "Data Error" |
To change the message title for a specific DataWindow, use:
1 | Dw_1.Object.DataWindow.Message.Title = dw_1.name + "Data Error" |
Get From The Internet
Good Luck!