Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Get number of actually shown records on grid 1

Status
Not open for further replies.

Gerrit Broekhuis

Programmer
Aug 16, 2004
316
NL
Hi,

Is there a way to count the number of records that are actually visible in a grid? For example when scrolling a grid towards the bottom not all records will be shown and I need to know the number of gridrows that actually show data.

I know how to calculate the number of records that can be shown (partially) on a grid. The table can have more or less records than the grid can show. And when the grid is scrolled vertically perhaps only a few records are actually visible in the grid. And I need code to calculate the number of visible records on the grid. Even when you have a grid that can show 30 records and you have a table with 300 records, only one record may be visible on the grid after scrolling.

As a human being it’s easy to count the number of visible records, but in code it’s not that easy apparently.

In this screenimage you see a sample grid with 6 visible records (due to scrolling). This particular grid can contain 16 records. The table has 160 records. In real life, with form and grid resizing things will be even more different.

I calculated the number of records the grid can contain (16). But how can I get count the number of visible records (6)?

Regards, Gerrit

grid_urfdcp.png
 
Funny you should ask. I was looking at a similar problem last week with a grid where we wanted to scroll things so that there was little or no empty space at the bottom if there were undisplayed records. Since I didn't need it to be exact, this isn't perfect, but it's way better than just letting the grid decide:

[pre]*-- TEG 8/1/2023
* Added this method to experiment with changing
* which rows are shown in the grid, so the user
* isn't confused about what data is available.
* The steps to do this are:
* - Figure out how many rows we can show.
* - Figure out whether we have more than that.
* - If not, just make sure all rows are displayed.
* - If yes, position the current record near the middle.
* Note that we don't need to be 100% correct here, as long
* as we end up with something that's not misleading.

LOCAL lnRowsDisplayed, lnTotalRows
LOCAL lnSpaceForRows, lnRecNo

ThisForm.LockScreen = .T.

* How many rows can we fit?
lnSpaceForRows = This.Height - This.HeaderHeight - ;
IIF(INLIST(This.ScrollBars, 1, 3), SYSMETRIC(8), 0)
lnRowsDisplayed = FLOOR(m.lnSpaceForRows / This.RowHeight)

lnTotalRows = RECCOUNT(This.RecordSource)

lnRecNo = RECNO(This.RecordSource)

LOCAL lnI, lnToScroll, lnDesiredRow

IF m.lnTotalRows <= m.lnRowsDisplayed
* They all fit. Make sure they're all shown

*-- TEG 8/7/2023
* Need to figure out this record's position in index order
LOCAL lnPos
lnPos = 1
GO TOP IN (This.RecordSource)
DO WHILE RECNO(This.RecordSource) <> m.lnRecNo
lnPos = lnPos + 1
SKIP IN (This.RecordSource)
ENDDO
* No need to reset position. We must end on the current row.

IF m.lnPos <> This.RelativeRow
* We need to move the current row down (because RelativeRow can't be negative)
lnToScroll = m.lnPos - This.RelativeRow
FOR lnI = 1 TO m.lnToScroll
This.DoScroll(0)
ENDFOR
ENDIF

ELSE
* Can't show all rows. Put current record near middle, if possible
lnDesiredRow = INT(m.lnRowsDisplayed/2)

LOCAL lnCurRec, lnRecsToEnd
lnRecsToEnd = 0

DO CASE
CASE m.lnDesiredRow < This.RelativeRow
* Is the current record near the end of the table? If so,
* how many records until the end?
lnCurRec = RECNO(This.RecordSource)
DO WHILE NOT EOF(This.RecordSource) AND lnRecsToEnd <= m.lnDesiredRow
SKIP 1 IN (This.RecordSource)
lnRecsToEnd = m.lnRecsToEnd + 1
ENDDO
GO (m.lnCurRec) IN (This.RecordSource)

* We want to scroll the list up, but not if that scrolls blank rows in
lnToScroll = This.RelativeRow - m.lnDesiredRow
IF m.lnRecsToEnd < m.lnToScroll
lnToScroll = 0
ENDIF

FOR lnI = 1 TO m.lnToScroll
This.DoScroll(1)
ENDFOR

CASE m.lnDesiredRow > This.RelativeRow
* We want to scroll the list down
lnToScroll = m.lnDesiredRow - This.RelativeRow

FOR lnI = 1 TO m.lnToScroll
This.DoScroll(0)
ENDFOR

OTHERWISE
* Nothing to do. It's right where it should be
ENDCASE

ENDIF m.lnTotalRows <= m.lnRowsDisplayed

ThisForm.LockScreen = .F.

RETURN[/pre]

Tamar
 
Hi Tamar,

I will try and check the results.
BTW I don’t use FLOOR but CEILING to calculate the available number of resords that can be shown. The grid will respond, even if half (or even less) of a row is visible.

Regards, Gerrit
 
Gerrit said:
But how can I get count the number of visible records (6)?

How about something like this:

In the main program or in the Init of the form you put:

Code:
public norows
norows=0

In the main program you create a function or procedure:

Code:
PROCEDURE MYFUNCT
norows=norows+1
return 0  && or other value depending on....
ENDPROC

In the grids column1 object you set a Dynamic property like DynamicForeColor to: Myfunct()
This function is called automatically by every row displayed in the grid.

Edit: Only DynamicBackColor, DynamicCurrentControl, DynamicForeColor and DynamicInputMask seem to work properly, the others are sometimes evaluated more than once if that column has the focus)


When you want to determine the number of displayed rows you execute something like these lines:

Code:
thisform.grid1.setfocus  && room for improvement... Like remembering thisform.activecontrol for returning focus at the end.
norows=0
thisform.grid1.refresh
thisform.label1.caption=str(norows)

You can also call the code above from the Scrolled event and/or from the AfterRowColChange event of the grid.
Indexes, filters and deleted records are no problem.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top