GridView (RadGrid) and Custom Paging - telerik

Ok, so I'm trying to get my custom paging going on the Telerik RadGrid (similar to the asp:Gridview), but I'm still hitting a wall. (the first part of my question was answered here)
So I have implemented the suggestion. I use the following Stored Proc
ALTER PROCEDURE [dbo].[bt_HealthMonitor_GetAll]
(
#StartRowIndex int,
#MaximumRows int
)
AS
SET NOCOUNT ON
Select
RowNum,
[ID],
[errEx],
[errURL],
[errSource],
[errUser],
[errMessage],
[errIP],
[errBrowser],
[errOS],
[errStack],
[errDate],
[errNotes]
From
(
Select
[ID],
[errEx],
[errURL],
[errSource],
[errUser],
[errMessage],
[errIP],
[errBrowser],
[errOS],
[errStack],
[errDate],
[errNotes],
Row_Number() Over(Order By [ID]) As RowNum
From dbo.[bt_HealthMonitor] t
)
As DerivedTableName
Where RowNum Between #StartRowIndex And (#StartRowIndex + #MaximumRows)
Order By [ID] Desc
Then another stored procedure to get the record count
ALTER PROCEDURE [dbo].[bt_HealthMonitor_GetRecordCount]
AS
SET NOCOUNT ON
return (Select Count(ID) As TotalRecords From bt_HealthMonitor)
And I'm using LINQ to SQL to bind to my RadGrid
Protected Sub RadGrid1_NeedDataSource(ByVal source As Object, ByVal e As Telerik.Web.UI.GridNeedDataSourceEventArgs)
Dim startRowIndex As Integer = (RadGrid1.CurrentPageIndex * RadGrid1.PageSize)
Dim maximumRows As Integer = RadGrid1.PageSize
Dim HealthMonitorDC As New DAL.HealthMonitorDataContext
Dim r = HealthMonitorDC.bt_HealthMonitor_GetAll(startRowIndex, maximumRows)
RadGrid1.DataSource = r
End Sub
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Dim HealthMonitorDC As New DAL.HealthMonitorDataContext
Dim count = HealthMonitorDC.bt_HealthMonitor_GetRecordCount()
RadGrid1.MasterTableView.VirtualItemCount = count.ReturnValue
RadGrid1.VirtualItemCount = count.ReturnValue
End Sub
But the problem I'm experiencing is that the grid only grabs the first 10 rows (as expected) but I need to get it so that it will recognize that there are 200 rows in the table so that the paging icons show up.
If I use the dropdownlist to display 50 records, then 50 show up, but still no paging icons to get me to the next 50.
What am I doing wrong?

You need to tell the grid how many records there are in total. This is done by setting the grid's VirtualItemCount property (you will have to query the total number of records).
For details, have a look at the documentation page or refer to the online demo for custom paging.

Martin is correct regarding VirtualItemCount. The easiest place to implement this is in the NeedDataSource event.
Remember that you'll need to put some logic in there to account for fewer records on the last page. That means that if you have 14 records with 5 per page, you want to make sure your logic only tries to retrieve 4 records on the last call.
Here's how I did it (using a generic list):
If gridRecords.Count < (grid.pagesize * (grid.pageIndex + 1)) Then
gridRecords.GetRange(grid.pageIndex * grid.pagesize, gridRecords.Count - (grid.pagesize * grid.pageIndex))
Else
gridRecords.GetRange(grid.pageIndex * grid.pagesize, grid.pagesize)
End If
Obviously, you'll want to do this as part of your data access call if you're only retrieving the records from the database as you go.

You can implement also using the ObjectDataSource.
http://www.unboxedsolutions.com/sean/archive/2005/12/28/818.aspx
i.e using RadGrid with ObjectDataSource with CustomPaging i.e Paging logic needs to implemented on your own.
Also ObjectDataSource has two methods
1. SelectMethod (Where you can specify the method which returns the data)
2. SelectCountMethod (Where you can specify the method which returns the total Count)

Related

Clicking on specific row in a WebTable using UFT/QTP

I am having hard time clicking specific row in a Web Table. My code finding proper row, but when I use Child Item method it complains that Object is not found. Here is my code:
Desc = "Record to click"
If Browser("B").Page("P").WebTable("W").exist(10) Then
totalRows = Browser("B").Page("P").WebTable("W").RowCount()
For RowNum = 1 To totalRows
If aDesc = Browser("B").Page("P").WebTable("W").GetCellData(RowNum,2) Then
Browser("B").Page("P").WebTable("W").ChildItem(RowNum,2,"WebElement",0).click
End If
Next
End If
I spied on the value in the row it is Web Element, I tried to use Link- didn't work. Also I tried to Child Item(aDesc,2,"WebElement",0)- didn't work either. I used 0 for the index because there is only one element in the row - simple text. I keep getting this error in many other tests. On rare occasion this approach works in some tests, but most of the time it complains for absence of object.
Thank you very much for your help!
It happened with me as well. When I researched, I found in some of the old HP blogs that ChildItem method does not works correctly with WEBElement, but that was for QTP 9.0, and I was using 12.02.Anyhow, I can't figure out why its happening, and ended up using the following -
Set oExcptnDetail = Description.Create
oExcptnDetail("micclass").value = "WebElement"
oExcptnDetail("html tag").value = "TD"
Set chobj=Browser("").Page("").WebTable("Code").ChildObjects(oExcptnDetail)
chobj(0).Click
On a side note, in order to check a webelement/link exist in a certain row and column, use the following.
Browser("B").Page("P").WebTable("W").ChildItemCount(2,2,"WebElement")
Getcell data will return you anything that is in the desired row and column irrespective of what it is (link,webelement etc) and hence your assumption of if loop will go wrong.
Try this:
Browser("B").Page("P").WebTable("W").object.rows(rownum-1).cells(colnum-1).Click
I was trying to click the first link in my table and this code clicked the item
Set oDesc = Description.Create()
oDesc("html tag").Value = "A"
Set rc = Browser("B").Page("A").WebTable("html id:=gridTable").ChildObjects(oDesc)
rc(0).Click
'num = rc.Count() 'get the number of link in a page
'For i=0 to num-1
'ref = rc(0).GetROProperty("href") 'get the “href”propety of the i th link
'MsgBox ref
'Next
or
Browser("B").Page("A").WebTable("html id:=gridTable").ChildItem(2,8,"Link",0).click
successfully clicks the link I needed

Anyway to iterate quickly over a collection of UDTs?

Let's say I have a collection of UDTs. I populate it as below:
public type udtEmp
Id as long
Name as string
end type
dim col as new Collection
dim empRec as udtEmp, empDummy as udtEmp
for n = 1 to 100000
empRec = empDummy ' reset record
emp.Id = n
emp.Name = "Name " & n
col.add emp, cstr(emp.Id)
next
Now I want to loop through it. I am using a Long data type as the index to .Item()
dim n as long
For n = 1 To 100000
emp = col.Item(n)
Next
The code above works, but it's really slow - takes 10,000 milliseconds to iterate. If I accessed the collection via a key, its much faster - 78 milliseconds.
For n = 1 To 100000
emp = col.Item(cstr(n))
Next
The problem is that when I iterate over collection, I don't have the keys. If I had a collection of objects instead of UDTs, I could do for each obj in col, but with UDTs, it won't let me iterate in that manner.
One of my thoughts was to have a secondary collection of indexes and keys to point to the main collection, but I am trying not to complicate the code unless I absolutely have to.
So what are my options?
the elegance of the code or the performance of it is a serious decision you have to make. the choice should be based on the impact of the results. for each is elegant but slow and goes with objects and classes. but if the speed is a mater then use UDT and arrays.
in your case, i think an array of UDT is best suited for your situation. and to gain more speed , try to access arrays using SAFE_ARRAY (that you can google for it), the result is much impressive.
You can use a user typed class collection. It'll provide the for-each iteration ability with great performance.
Easiest way to make that happen is through the Class Builder Utility (https://msdn.microsoft.com/en-us/library/aa442930(v=vs.60).aspx). You might need to first run the Add-in Manager and load the Class Builder Utility. (I think that there were install options regarding these features when you installed vb6/vs6? So if you don't see the Class Builder Utility in the Add-in manager it's could be due to that).
To match your udt sample, using the Class Builder Utility, first add a class (eg: Employee), with two properties (eg: EmpId and EmpName, long and string types respectively). Then add a collection (eg: Employees) based on the Employee class. Save it to the project (that will create two new class modules) and close the Utility.
Now you can create the new Employees collection, load it up, and iterate through it via index, key or for-each. (note: don't use a pure number for the key - requesting an item by a key that is a pure number, even as a string, will be interpreted as an index request, it'll be slow and you probably won't get the desired item)
Also - once the new classes have been created, you can add customized properties and methods to them to handle whatever kinds of fancy stuff you may have requirements for.
Dim i As Long
Dim Emp As Employee
Dim colEmp As New Employees
Dim name As String
' Loading
For i = 1 To 100000
colEmp.Add i, "name" & CStr(i), "key" & CStr(i)
Next i
' iterate with index
For i = 1 To 100000
Set Emp = colEmp(i)
name = Emp.EmpName
Next i
' iterate with key
For i = 1 To 100000
Set Emp = colEmp("key" & i)
name = Emp.EmpName
Next i
'iterate with for-each
For Each Emp In colEmp
name = Emp.EmpName
Next Emp
Timings
On my system for the above code:
Loading time: 1 second
Index time: 20 seconds
Key time: 0.29 seconds
For-each time: 0.031 seconds

Filter in OpenOffice Calc

Scenario:
I have a spreadsheet with info from a giveaway campaign in which I get paid per new Twitter follow my client receives through my campaign. Unfortunately the application I use does not track new followers vs existing ones because they offer an entry for new and existing followers for the "Follow on Twitter for 1 Entry". Because I also offer other means to gain entries I need to export the data and filter the results to show only those who've gained an entry on the Twitter Follow and then filter out those who are new vs existing by means of a separate application.
Problem:
There should be a separate column for each data type; name,email,action, etc. The action column is where I would expect to find the "Follow On Twitter" but the file is very disorganized and the action can be found in many different columns. Therefore I need a way to show only the rows in which there is a field with "Follow on Twitter". I am at a loss to try and figure out how to do this.
The following macro will search for "Follow On Twitter" in each cell. For each row, if a match is found, the row will be shown, else it will be hidden. You will have to adjust the macro to match your sheet's total number of rows/columns.
Sub Dummy()
GlobalScope.BasicLibraries.LoadLibrary("Tools")
Dim ActiveSheet As Object
ActiveSheet = ThisComponent.CurrentController.ActiveSheet
Dim r,c As Integer
For r = 0 To 25
Dim found As Boolean
found = False
For c = 0 to 10
Dim cell As Object
cell = ActiveSheet.getCellByPosition(c, r)
If cell.String = "Follow On Twitter" Then
found = True
Exit For
End If
Next c
Dim row As Object
row = ActiveSheet.getRows.getByIndex(r)
row.IsVisible = found
Next r
MsgBox "Done"
End Sub

Calculated control displays the total number of records that appear in the subform

My assignment is to create a calculated control that displays to total number of Members in the subform. How can I accomplish this when there is no definitive field that I can use in the expression. There are only three fields in the subform: First Name, Last Name, and Phone. If I do something like this =[frmPlanMemberSubform].[Form]![FirstName] that only calculate and displays the first name of the member in the subform. Actually there are only two names in the subform. Theoretically I suppose to get back a count of 2. But I can't figure out how to do it with the existing fields in the subform. Any Access experts out there? Please help. Here is what the database looks like in form view.
As you can see there is nothing in the Total Members control box.
Follow these steps:
1) In the code of the master form insert a function similar to this:
Private Function NumRecords()
Dim rec As Recordset
On Error GoTo lbErr
Set rec = Me!<subform-name>.Form.RecordsetClone
rec.MoveLast
NumRecords = rec.RecordCount
lbExit:
Exit Function
lbErr:
MsgBox Error, vbExclamation
Resume lbExit
End Function
2) In the field to display the number of records insert the following string in the value property:
=NumRecords()
3) Create the Form_Current trigger as follows:
Private Sub Form_Current()
Me!<fieldname>.Requery
End Sub
enter image description here

how to code the itemchanged event and datawindows

I am using PowerBuilder classic 12.5
am having difficulties in inserting, editing, creating and printing reports.
i have a datawindow, dw_NewEmployee with dataobject, d_newrecord which is update-able.
should i use the columns to insert records through the columns or i
create single line texts on the window object
is the itemchanged event used on columns and rows on dataobject or
on single line texts... I am having trouble figuring out how to implement validation rules.
please give me an example to validate employee ID_Number
I see that you seem confused about the datawindow usage.
Let's try to summarize:
you create a new datawindow d_newrecord (say it is a grid) based on a sql select in your database, say select id_number, name from employee.
in the detail zone of the datawindow (that will be repeated for each record at runtime but that is only once in design), you need to put one column object for each column (here you will have id_number and name) these objects are both to display existing data and receive user input for editing data and inserting new records.
don't forget to set the Rows / Update properties if you need to make the dw updatable.
in the header zone of the datawindow you can have a static text associated to each column that is just here to display the column name, it does not concern table data.
in some window object, you place a datawindow control dw_newemployee where the content of the datawindow will be painted, you set d_newrecord as its dataobject.
you need to set at some point the transaction object of the dw, for example in the open() event of the window:
dw_newemployee.SetTransObject(sqlca)
dw_newemployee.Retreive() //if you are using some retreival arguments, don't forget to include them here
When you want to insert new data in your table (for example with a window button "add"), in the clicked() event of the button you call dw_newemployee.InsertRow(0) to insert at the end.
The ItemChanged() event will be triggered after one cell will be modified, you will be given the row, item (a dwobject) and new data. By choosing the returned value of the event, you can accept or reject the new data.
Here is an example for a field validation in itemchanged() event:
long ll_return_code = 0
string ls_column
ls_column = lower(dwo.name)
choose case ls_column
case "id_number"
if long(data) = 42 THEN
messagebox("validation error", "You cannot use 42 for the ID")
ll_return_code = 1 //reject and stay in cell
end if
case "name"
if data = "foobar" then
messagebox("validation error", "Do not use dummy value...")
ll_return_code = 2 //reject but allow to go elsewhere
end if
end choose
return ll_return_code

Resources