Home | Forums | Contact | Search | Syndication  
 
 [login] [create account]   Tuesday, November 26, 2024 
 
slxdeveloper.com Community Forums  
   
The Forums on slxdeveloper.com are now retired. The forum archive will remain available for the time being. Thank you for your participation on slxdeveloper.com!
 Architect Forums - SalesLogix Scripting & Customization
Forum to discuss writing script in Architect plugins for SalesLogix & general SalesLogix customization topics (for Windows client only). View the code of conduct for posting guidelines.
Forums RSS Feed


 Back to Forum List | Back to SalesLogix Scripting & Customization | New ThreadView:  Search:  
 Author  Thread: Sortable Datagrid when columns are added at runtime
Rick Smith
Posts: 96
 
Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 04 Apr 06 10:47 AM
fiogf49gjkf0d
There was some unfinished discussion in the Article section regarding sortable datagrids
http://www.slxdeveloper.com/page.aspx?action=viewarticle&articleid=26

I also found that if I add a datagrid but do not set the SQL property at design time, I cannot check the Sortable box in the datagrid properties.
Then, whether before or after adding columns at runtime, I add the a line in the code:
myDatagrid.Sortable = True
there is no error, but neither does the datagrid become sortable!
My workaround - in design time, I set the datagrid's SQL property to be, for example, SELECT CONTACTID FROM CONTACT WHERE CONTACTID = 'bogus'. Of course nothing is returned. This allows me to check the Sortable property, and then when columns are added at runtime, they are indeed sortable.
If anyone has a more elegant solution I'd be glad to know it.
[Reply][Quote]
Ryan Farley
Posts: 2265
slxdeveloper.com Site Administrator
Top 10 forum poster: 2265 posts
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 05 Apr 06 11:34 AM

mirtazapine weight gain

mirtazapine and alcohol marcelosincic.com.br
fiogf49gjkf0d
Rick,

Your workaround is the same approach I take. However I find that more often, instead of loading up the columns at runtime, I'll just do the standard design-time setup of the grid, then at runtime, just modify the SQL to append my where clause. Then, as long as you don't modify the fields names in the query, you don't need to setup the columns again, only a refresh. Of course that only works if you actually have fields defined in the tables that you want in the grid (ie: not dynamic values calculated at runtime). In this case, I'll still just add something similar to the grid at design-time, then alias my dynamic value from my SQL as that same field name. It will get matched up to the existing column and all you'll need to do is refresh.
[Reply][Quote]
Rick Smith
Posts: 96
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 05 Apr 06 11:46 AM
fiogf49gjkf0d
Hi Ryan,
This is how I had built it at first, but the SQL for the datagrid didn't have any WHERE clause, and it was using the CONTACT table. I realized that it was trying to load the entire contents of the CONTACT table into the datagrid before my code executed and applied the appropriate WHERE parameters. So... yes, fine to set the SQL with the appropriate columns at design time as long as you include a WHERE clause such as CONTACTID='bogus' that prevents a long-running query!
I did also subsequently add some calculated columns so it was easy to use your code for dynamically adding columns to the grid at runtime.

Question: Do you think there is a performance penalty for adding columns at runtime vs. having the SQL in the datagrid define the columns at design time?
[Reply][Quote]
Ryan Farley
Posts: 2265
slxdeveloper.com Site Administrator
Top 10 forum poster: 2265 posts
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 05 Apr 06 12:08 PM

where can i get the abortion pill Philippines

abortion pill price ph click here how much is the abortion pill ph

viagra cena bez receptu

viagra na prodej click here
fiogf49gjkf0d
When you create the columns dynamically there is a small performance hit. On many grids you can actually see some flickering as the new columns are created. But that is not usually such a big deal. It's not a huge hit, but there is one. If possible, I always go the route of setting up the grid design-time and then just appending where conditions at runtime with a refresh. When that is not possible I go the route of just setting up the entire grid at runtime.
[Reply][Quote]
Jeremy Brayton
Posts: 491
Top 10 forum poster: 491 posts
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 05 Apr 06 2:07 PM
fiogf49gjkf0d
There's always using a ListView set to details mode with checkboxes to mimic a multi-select datagrid. I did this in 6.1 to allow selecting of attachments and I've yet to convert the code to a datagrid because a) I like it, b) I'm really really lazy, and c) it just works.

The major problems with using a ListView is all of the data has to be in string form and it does not handle NULLs, you have to specifically deal with them. There are a couple of other caveats as well but you're given the lovely ListViewColumnSort properties where you can use your own sorting algorithm and I do believe you don't load the entire dataset into memory. Though the entire dataset IS loaded into the ListView.

Some companies have large number of attachments and I have yet to do something like "select top 10 order by date". If there was a performance problem due to the sheer size of the data, I would have heard about it long ago. My users are severely vocal about perceived performance issues.

If you're interested in the technique let me know. I plan on submitting an article on manipulating the ListView but I've been severely pressed for time lately.
[Reply][Quote]
Alex Green
Posts: 2
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 27 Jan 10 10:23 AM
Hi all,

I know this is an old thread, but I am having the exact same problem when trying to sort a datagrid created in this method.

The datagrid is populated from a Recordset that I populate after parsing an xml response. When any of the columns is clicked to sort, then the datagrid just empties of all data.

I have followed what is noted above, but my datagrid is failing to populate. When I set the sortable property back to false, all works fine again!

Any ideas on what could be wrong?

Thanks

Edit: I have since found this post describing the exact same problem http://www.slxdeveloper.com/forum.aspx?forumid=2000&postid=3191
I have followed the exact instruction (new grid,simple sql,grid refresh) still same problem.
[Reply][Quote]
RJ Samp
Posts: 973
Top 10 forum poster: 973 posts
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 28 Jan 10 7:26 AM
Caption header click sorts are performed:
on the server
with the SQL in the grid
with an appended ORDER BY
through the Grid connection (which may mean SLX seccodeid joins!).

you filled the grid via an XML data feed, but that's not how the grid control sorts.

Let me know if you need a solution (trap the user event and then do an RS.sort).
[Reply][Quote]
Vaughn Poulson
Posts: 32
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 28 Jan 10 8:50 AM
You need to make sure you have the KeyField property of the data grid set.

i.e.

dgProducts.Sortable = True
dgProducts.KeyField = "OppProductId"
[Reply][Quote]
Alex Green
Posts: 2
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 28 Jan 10 8:52 AM
I figure I have to trap the user event using a function to be triggered using the OnColumnSorting event?

Any help that can be offered would be most appreciated!

Let me know if you need to see my block of code I have so far.
[Reply][Quote]
RJ Samp
Posts: 973
Top 10 forum poster: 973 posts
 
Re: Sortable Datagrid when columns are added at runtimeYour last visit to this thread was on 1/1/1970 12:00:00 AM
Posted: 28 Jan 10 10:23 AM
OnColumnSorting event is ex post facto.....the sort has already been done.....

SLX Faster Column Header/Caption grid sorts

Using the SLX ActiveX grid control, severe performance issues were encountered when a user clicked on a grid column header to sort the grid…..with x,000 rows in the grid.

How SLX sorts the grid:
1. Executed on the SQL Server as a SQL Select statement with an appended ORDER BY clause based on the column clicked upon and the sort glyph in the column caption header.
2. The SQL Select statement comes from the GRID.SQL.TEXT property.
3. It used the Grid’s .ConnectionString property to fetch the data into the grid’s recordset, sorted. If the connection is the SLX OLE DB Provider, then ACCOUNTID based SECCODE checks will be made for non ADMIN user row and field accessibility/visibility.
Note that this is on data that already has been provided to the user (it is IN the data grid after all) and already has been checked for user access (when the grid was loaded!). It is this duplicate round trip and duplicate SECCODE access checking that slows a simple sort down to a crawl for large recordsets.
Why do the rows disappear when the user clicks on a column header to sort?
If you are using a RecordSet to fill/refresh the data grid:
SET datagrid.Recordset = MyRS
The SQL used for the grid sort is whatever is in grid.sql.text NOT what was in MyRS.The SQL may be wrong (or not even used by you). This is why grid sort’s on extra column’s of data built by hand data grids return no rows, it’s running the bogus SQL in the grid.SQL.TEXT (SELECT CONTACTID FROM CONTACT WHERE 1 =2 “, not your XML or recordset data that you’ve so carefully crafted.

Grid.Sortable
Yes it must be set to True, otherwise not all of the data is in the grid and user selection’s of multiple grid rows is bogus.
No, it can’t be set at design time unless you have the SQL property filled in at design Time.
Yes you can set it at run time to True [grid.sortable = True] without any ‘speed’ penalty.


Grid Refreshssss.
Since 7.20 the following Grid Property changes automatically included a call to method grid.REFRESH. If you are doing this twice that’s two trips to the server, and possibly two trips to the SECCODE check timeout corner (which may be further exacerbated if you are trying to show an Account’s Parent Account….).
.BindID
.ConnectionString
.RecordSet
.SQL.TEXT

Got it? If you set any of those 4 property’s to a different value, the grid does a .REFRESH.

So
Grid.SQL.TEXT = “SELECT * FROM ADDRESS WHERE…)
Grid.REFRESH
Executes a .Refresh TWICE (two round trips to the Server, and two SECCODE table checks) and tick’s off the Users….

Enough of the primer, let’s get down to business!


Speeding up Grid Sorts.

Eoghan Byrt, Discovery Education, Evanston, IL came up with a solution to the sort issue in a 40 hour marathon of trial and error research into the very dark abyss’ of the grid control quirks.

The short answer:

1. Trap the user’s mouse click on the caption header in the grid’s mouse down event handler.
2. Sort the grid using an ADO RecordSet sort locally on the machine where the grid data is already in memory: RS.SORT “Field1 Asc, Field2 Desc….”
Refresh the grid with the sorted recordset:
SET gridcontrol.recordset = RS

The Long Answer:

1. add a Mouse down event handler to your grid on the local form (if you thought of going after the OnColumnSorting event you’d be too late, the column has already been sorted….):


'**************************************************************
' Name: dgRIGHTMouseDown
' Purpose: handle user mouse clicks on the data grid
' Assumptions: global variable rGridRS is the record set used to populate the grid.
' Effects: traps user caption header initiated grid sorts.
' Inputs: Sender is the grid control itself.
' Button is 0 for Left Mouse Button, 1 for Right Mouse Button.
' X,Y are the cell and row coordinates for the mouse down click.
' global variable rGridRS is the record set used to populate the grid.
' Returns: None.
' Dev Notes:
' ** For Developer Reference **
' Sender.GetHitInfo(X,Y).HitTYpe apparent values:
' 1 : ColumnHeader - A Column Header in the DataGrid control.
' 8 : None - The background area, visible when the control contains no table, few rows, or when a table is scrolled to its bottom.
' N/A : ColumnResize - The column border, which is the line between column headers. It can be dragged to resize a column's width.
' 7: Cell - A cell in the DataGrid control.
' ? : Caption - The caption of the DataGrid control.
' ? : ParentRows - The parent row section of the System.Windows.Forms.DataGrid control. The parent row displays information from or about the parent table of the currently displayed child table, such as the name of the parent table, column names and values of the parent record.
' ? : RowHeader - A row header in the System.Windows.Forms.DataGrid control.
' ? : RowResize - The row border, which is the line between grid row headers. It can be dragged to resize a row's height.
'**************************************************************
Sub dgRIGHTMouseDown (Sender, Button, X, Y)
Dim sortColIndex
DIM sortColHitType
' Due to uncertainty over the Sender.GetHitInfo, set On Error command to handle unpredicted situations.
On Error Resume Next
' Get index for the column clicked
sortColIndex = Sender.GetHitInfo(X,Y).Column.Index
' Get hit type. 1 is a column\caption header.
sortColHitType = Sender.GetHitInfo(X,Y).HitType
' If user clicked on Header, Set Sortable = False
CALL GridCommon_GridMouseDownEventHandler (Sender, rGridRS, sortColIndex, sortColHitType)
' Reset On Error command
On Error GoTo 0
End Sub



2. CALL GridCommon_GridMouseDownEventHandler which: Sorts the grid by recordset, ascending descending based on consecutive clicks on a column, and sort the grid based on the column clicked upon. The grid is sorted in a developer supplied rs object (which may be the original rs used to fill the grid).

Here’s the code:

'**************************************************************
' Name: GridMouseDownEventHandler
' Purpose: passed trapped mouse down on a grid event to here.
' If user clicked on a column Header, Set Sortable = False
' Assumptions: 7.22 Datagrid ActiveX control.
' Effects: handles trapped user caption header initiated grid sorts.
' Inputs: TheGrid is the grid control itself, by reference.
' TheRS is a grid to do the sorting in, by reference.
' sortColIndex is the column clicked upon by the user for sorting.
' sortColHitType is the type of grid object clicked upon by the user.
' Returns: None.
' Dev Notes: see below.
'**************************************************************
Sub GridMouseDownEventHandler (ByRef TheGrid, ByRef TheRS, ByVal sortColIndex, ByVal sortColHitType)
' ** For Developer Reference **
' Sender.GetHitInfo(X,Y).HitTYpe apparent values:
' 1 : ColumnHeader - A Column Header in the DataGrid control.
' 8 : None - The background area, visible when the control contains no table, few rows, or when a table is scrolled to its bottom.
' N/A : ColumnResize - The column border, which is the line between column headers. It can be dragged to resize a column's width.
' 7: Cell - A cell in the DataGrid control.
' ? : Caption - The caption of the DataGrid control.
' ? : ParentRows - The parent row section of the System.Windows.Forms.DataGrid control. The parent row displays information from or about the parent table of the currently displayed child table, such as the name of the parent table, column names and values of the parent record.
' ? : RowHeader - A row header in the System.Windows.Forms.DataGrid control.
' ? : RowResize - The row border, which is the line between grid row headers. It can be dragged to resize a row's height.

' Due to uncertainty over the Sender.GetHitInfo, set On Error command to handle unpredicted situations.
On Error Resume Next

' If user clicked on Header, Set Sortable = False
SELECT CASE sortColHitType
CASE 1 ' Column Header
' Call SortGridbyRS to sort the grid based on a recordset sort based on a specific column index
' SortGridbyRS (byRef theGrid, byRef theRS, byVal theSortColIndex)
SortGridbyRS TheGrid, TheRS, sortColIndex

' Call SetSortGlyph to display the Up or Down glyph on the grid column header. NOTE: SetSortGlyph sets sorting = False.
' SetSortGlyph (byRef theGrid, byVal theSortColIndex)
SetSortGlyph TheGrid, sortColIndex
Case Else
' User clicked somewhere other than the Header, Reset Sorted column first, if necessary, then Set Sortable = True for correct multi-select functionality.
' Turn sortable back on.
If TheGrid.Sortable = False Then
' Reset any previously sorted column before setting sortable = True so that grid control sort is not triggered.
' SetSortGlyph (byRef theGrid, byVal theSortColIndex)
SetSortGlyph TheGrid, 0
' Set Sortable = True so that multi-select functions correctly.
TheGrid.Sortable = True
End If
End Select
' Reset On Error command
On Error GoTo 0
End Sub

'**************************************************************
' Name: SortGridbyRS
' Purpose: Sort the data display in a Grid control by
' first sorting a recordset and then placing
' that RS into the grid.
' Assumptions: The grid column object clicked on has the current sort properties for the column to be sorted.
' Effects: Client Side memory sort of an ADO Record Set (RS.SORT), sorted on the provided Sort Column Idex.
' If previous click on this column was no sort or Descending sort, then the sort will be Ascending.
' If previous click on this column was a Ascending Sort, then the sort will be Descending.
' Inputs: by Reference theGrid - Grid control itself
' by Referehce theRS - the ADO Recordset to put into Grid
' TheSortColIndex - integer - the column to be sorted.
' Returns:
' Dev Notes: Calls the RefreshGridByRS subroutine to
' refresh the grid.
'**************************************************************
Sub SortGridbyRS(byRef theGrid, byRef theRS, byVal theSortColIndex)
' Sort the recordset based on the grid column index provided.
' Test to see if the column has already been sorted (i.e. the currently sorted column name is in the RS sort property).
' If the same column was the last sort, then reverse sort direction Asc/ Desc.

DIM sortFieldName
DIM lastRSsort
DIM sortString
DIM incomingSortableValue

' Turn sortable off if True. Record the original value so that it can be reset after the sort (if it came in as True).
If theGrid.Sortable = True Then
incomingSortableValue = True
theGrid.Sortable = False
Else
incomingSortableValue = False
End If

' Set the On Error command to handle exceptions where a required object does not exist.
On Error Resume Next

' Get the Fieldname for the Column Index provided
sortFieldName = theGrid.Columns.Item(theSortColIndex).FieldName

' Get value for previous sort (if exists), expected format: FIELDNAME Asc / FIELDNAME Desc
lastRSsort = "" & theRS.Sort

' Test if same column as previous sort?
If InStr(lastRSsort, sortFieldName) Then
' Test if previous sort was Ascending
If InStr(lastRSsort, "Asc") Then
' Set current sort to Descending
sortString = sortFieldName & " Desc"
Else
' Previous sort was Descending, set current sort to Ascending
sortString = sortFieldName & " Asc"
End If
Else
' Not the same solumn as previous sort, set current sort to Ascending
sortString = sortFieldName & " Asc"
End If

' Sort the recordset based on the sortString
theRS.Sort = sortString

' Refresh the grid so that the newly sorted data is displayed.
RefreshGridByRS theGrid, theRS

' If sortable was set to True when the sub was called, then turn it back on.
If incomingSortableValue = True Then
theGrid.Sortable = True
End If

' Reset On Error command
On Error GoTo 0
End Sub

'**************************************************************
' Name: SetSortGlyph
' Purpose: Update the grid control by setting the .Sorted
' property for a specific column in order to display
' the correct sort glyph (Ascending, Descending,
' or none).
' Assumptions: Developer will call: SetSortGlyph theGrid, 0
' before setting the grid control sortable property
' to True (in order to avoid a client-side grid
' control sort).
' Effects: - The grid control sortable property will be set to False.
' - A column in the grid will be set as "Is Sorted"
' - A sort glyph will be displayed in the grid
' control header column based on which column has
' been set to "Is Sorted".
' Inputs: the grid control
' the sorted column index - integer
' Returns:
' Dev Notes: As a column.Sorted property has been set it will
' be necessary to reset Sorted to none before
' setting the grid control sortable property = True
' in order to avoid a client-side grid control sort.
'**************************************************************
Sub SetSortGlyph (byRef theGrid, byVal theSortColIndex)
' ** For Developer Reference **
' Set the grid column headerglyph to display as sorted up or down based on the grid column index provided.
' Test to see if the column has already been sorted (i.e. the currently sorted column name is in the RS sort property).
' If the same column was the last sort, then reverse sort direction Asc/ Desc.

' ** For Developer Reference **
' DataGridColumn object Sorted property - TxDataGridColumnSort enum.
'csNone = 0
'csDown = 1
'csUp = 2

DIM lastSortColIndex
DIM lastSortDirection

' Set the On Error command to handle exceptions where a required object does not exist.
On Error Resume Next

' Reset any existing Sorted value
If Not theGrid.SortedColumn.Sorted Is Nothing Then
lastSortColIndex = theGrid.SortedColumn.Index
lastSortDirection = theGrid.SortedColumn.Sorted
' Reset existing sorted value to not sorted
theGrid.SortedColumn.Sorted = csNone
End If

' if theSortColIndex is defined then set the sort glyph accordingly
If theSortColIndex >0 Then
' Turn sortable off if True.
If theGrid.Sortable = True Then
theGrid.Sortable = False
' Else Do Nothing, Sortable is already False
End If

' Test if the last sorted column is being resorted
If lastSortColIndex = theSortColIndex Then
' Same column is being sorted again, test for sort direction. csUp = 2
If lastSortDirection = 2 Then
' Set current sort indicator to Down
theGrid.Columns.Item(theSortColIndex).Sorted = csDown
Else
' Existing sort indicator is set to Down, set sort indicator to Up
theGrid.Columns.Item(theSortColIndex).Sorted = csUp
End If
Else
' Existing sort indicator is not set or is set to Down, set sort indicator to Up
theGrid.Columns.Item(theSortColIndex).Sorted = csUp
End If
End If

' Reset On Error command
On Error GoTo 0
End Sub



Glyph’s?!
Those little icons that show up in the column caption to indicate the grid column and sort direction. You can actually see the changes to the grid based on setting the column header caption sort glyph’s, as well as sortable = true or false. Eoghan spent a ton of time on this. If the glyph’s are left ON, then when you load the record set (say by Data Grid!) this is a clue for SLX to run a SQL.Text with appended order by clause on the server….oops, that was the original problem! So you need to set the grid glyph’s off when you finish up the sort and reload the record set.

In Summary
Thanks to Eoghan’s brain storm we have a proven method to speed up grid sort’s AND sort hand built recordset grids (the one’s without valid SQL.TEXT statements).

About the Reporter:
RJ Samp is a certified SLX Developer that has been working with SLX since its inception (inaugural Partner Conference in February 1997, including golf with Pat Sullivan). He’s been working at Discovery Channel’s Discovery Education Division since May 1997. Eoghan Byrt is his boss and project manager of the conversion from SLX 6.10 to 7.22 HF 21.

RJ Samp, Wheaton IL 2010-01-28

rjsamp@comcast.net
http://www.rjsamp.com

[Reply][Quote]
 Page 1 of 1 
  You can subscribe to receive a daily forum digest in your user profile. View the site code of conduct for posting guidelines.

   Forum RSS Feed - Subscribe to the forum RSS feed to keep on top of the latest forum activity!
 

 
 slxdeveloper.com is brought to you courtesy of Ryan Farley & Customer FX Corporation.
 This site, and all contents herein, are Copyright © 2024 Customer FX Corporation. The information and opinions expressed here are not endorsed by Sage Software.

code of conduct | Subscribe to the slxdeveloper.com Latest Article RSS feed
   
 
page cache (param): 11/26/2024 2:33:42 PM