Help with Virtual Grid

General Help regarding HMG, Compilation, Linking, Samples

Moderator: Rathinagiri

User avatar
mol
Posts: 3495
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 289 times
Been thanked: 197 times
Contact:

Help with Virtual Grid

Post by mol »

I'm trying to use virtual grid to browse array.
I need to sort this array.
How to refresh virtual grid?
Normal REFRESH causes RT error.
Im using form1.grid1.ItemCount := len(aArrayToBrowse)
but, I'm wonder if it is another method.

And second question is:
When I set grid.value to any value, is it the way to move highlighted row to the beginning of grid on the screen?

Regards, Marek

User avatar
Rathinagiri
Posts: 5352
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Has thanked: 215 times
Been thanked: 233 times
Contact:

Post by Rathinagiri »

Marek,

Virtual grid is really virtual and very fast.

It doesn't have any data in it. Only the selected page of rows ( for example if 10 rows are shown from 1 million rows that 10 rows are required) by the system are required at the runtime using the Query method.

Now if you alter the sorting automatically the virtual grid is also sorted on window-repaint. So what we have to do? Just 'force window-repaint.'

Regarding your second question the answer is yes.

Please consider this small sample:

Code: Select all

#include <hmg.ch>

Function Main
   private aArray := { { '001', 'One', 'January' },;
                     { '002', 'Two', 'February' },;
                     { '003', 'Three', 'March' },;
                     { '004', 'Four', 'April' },;
                     { '005', 'Five', 'May' },;
                     { '006', 'Six', 'June' },;
                     { '007', 'Seven', 'July' },;
                     { '008', 'Eight', 'August' },;
                     { '009', 'Nine', 'September' },;
                     { '010', 'Ten', 'October' },;
                     { '011', 'Eleven', 'November' },;
                     { '012', 'Twelve', 'December' } }

   define window vgrid at 0, 0 width 500 height 400 main
   
      define textbox tbox1
         row 10
         col 10
         width 100
      end textbox
      define grid vgrid1
         row 40
         col 10
         width 350
         height 100
         widths { 60, 100, 150 }
         virtual .t.
         items aArray
         onQueryData getvgriddata()
         onheadclick { { || headclick1() }, { || headclick2() }, { || headclick3() } }
         headers { 'Number', 'Name', 'Month' }
      end grid
      define button addsomeitems
         row 150
         col 10
         caption 'Add Items'
         action AddItemToVGrid()
      end button   
   end window
   vgrid.vgrid1.value := 1
   vgrid.center
   vgrid.activate
   Return

function getvgriddata
   local i := this.queryrowindex
   local j := this.querycolindex
   this.querydata := aArray[ i, j ]
   return nil

function headclick1
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 1 ] < y[ 1 ] } )
   vgrid.vgrid1.visible := .t.
   return nil   
   
function headclick2
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 2 ] < y[ 2 ] } )
   vgrid.vgrid1.visible := .t.
   return nil   

function headclick3
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 3 ] < y[ 3 ] } )
   vgrid.vgrid1.visible := .t.
   return nil      
   
function AddItemToVGrid()   
   vgrid.vgrid1.visible := .f.
   aadd( aArray, { '0' + alltrim( str( len( aArray ) + 1 ) ), 'New Item' + str( len( aArray ) + 1 ), 'New Item' + str( len( aArray ) + 1 ) } )
   vgrid.vgrid1.itemcount := len( aArray )
   vgrid.vgrid1.visible := .t.
   return nil
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.

User avatar
mol
Posts: 3495
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 289 times
Been thanked: 197 times
Contact:

Post by mol »

THX!
But - what about my second question? Is it possible to move highlighted row to e.g. first displayed row?

User avatar
Rathinagiri
Posts: 5352
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Has thanked: 215 times
Been thanked: 233 times
Contact:

Post by Rathinagiri »

Windows will EnsureVisibility of the row value but we can't say that it is the first item shown in the grid. I think it could be done using some c code.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.

User avatar
Rathinagiri
Posts: 5352
Joined: Tue Jul 29, 2008 6:30 pm
DBs Used: MariaDB, SQLite, SQLCipher and MySQL
Location: Sivakasi, India
Has thanked: 215 times
Been thanked: 233 times
Contact:

Post by Rathinagiri »

Here is the solution from an old source code. I think it will work for you.

Code: Select all

#include <hmg.ch>

Function Main
   private aArray := { { '001', 'One', 'January' },;
                     { '002', 'Two', 'February' },;
                     { '003', 'Three', 'March' },;
                     { '004', 'Four', 'April' },;
                     { '005', 'Five', 'May' },;
                     { '006', 'Six', 'June' },;
                     { '007', 'Six', 'June' },;
                     { '008', 'Six', 'June' },;
                     { '009', 'Six', 'June' },;
                     { '010', 'Six', 'June' },;
                     { '011', 'Six', 'June' },;
                     { '012', 'Six', 'June' },;
                     { '013', 'Six', 'June' },;
                     { '014', 'Six', 'June' },;
                     { '015', 'Six', 'June' },;
                     { '016', 'Six', 'June' },;
                     { '017', 'Six', 'June' },;
                     { '018', 'Six', 'June' },;
                     { '019', 'Six', 'June' },;
                     { '020', 'Six', 'June' },;
                     { '021', 'Six', 'June' },;
                     { '022', 'Six', 'June' },;
                     { '007', 'Seven', 'July' },;
                     { '008', 'Eight', 'August' },;
                     { '009', 'Nine', 'September' },;
                     { '010', 'Ten', 'October' },;
                     { '011', 'Eleven', 'November' },;
                     { '012', 'Twelve', 'December' } }

   define window vgrid at 0, 0 width 500 height 400 main
   
      define textbox tbox1
         row 10
         col 10
         width 100
      end textbox
      define grid vgrid1
         row 40
         col 10
         width 350
         height 100
         widths { 60, 100, 150 }
         virtual .t.
         items aArray
         onQueryData getvgriddata()
         onheadclick { { || headclick1() }, { || headclick2() }, { || headclick3() } }
         headers { 'Number', 'Name', 'Month' }
      end grid
      define button addsomeitems
         row 150
         col 10
         caption 'Add Items'
         action AddItemToVGrid()
      end button   
      define button setvalue
         row 150
         col 200
         caption 'Set Value'
         action setnewvalue()
      end button   
   end window
   vgrid.vgrid1.value := 1
   vgrid.center
   vgrid.activate
   Return

function getvgriddata
   local i := this.queryrowindex
   local j := this.querycolindex
   this.querydata := aArray[ i, j ]
   return nil

function headclick1
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 1 ] < y[ 1 ] } )
   vgrid.vgrid1.visible := .t.
   return nil   
   
function headclick2
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 2 ] < y[ 2 ] } )
   vgrid.vgrid1.visible := .t.
   return nil   

function headclick3
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 3 ] < y[ 3 ] } )
   vgrid.vgrid1.visible := .t.
   return nil     
   
function AddItemToVGrid()   
   vgrid.vgrid1.visible := .f.
   aadd( aArray, { '0' + alltrim( str( len( aArray ) + 1 ) ), 'New Item' + str( len( aArray ) + 1 ), 'New Item' + str( len( aArray ) + 1 ) } )
   vgrid.vgrid1.itemcount := len( aArray )
   vgrid.vgrid1.visible := .t.
   return nil
   
function setnewvalue

   vgrid.vgrid1.visible := .f.
   vgrid.vgrid1.value := 14   
   
   GridMakeVisible( 'vgrid', 'vgrid1', 14 )
   GridMakeFirstItem( 'vgrid', 'vgrid1', 14 )
   vgrid.vgrid1.visible := .t.
   return nil   

function GridMakeFirstItem( cParent, cControl, nValue )
   local nHandle := GetControlHandle( cControl, cParent )
   GridMakeFirst( nHandle, nValue )
   return nil   

function GridMakeVisible( cParent, cControl, nValue )
   local nHandle := GetControlHandle( cControl, cParent )
   GridEnsureVisible( nHandle, nValue )
   return nil   
   
   
#pragma BEGINDUMP

#include <windows.h>
#include <commctrl.h>
#include "hbapi.h"

HB_FUNC ( GRIDMAKEFIRST )
{
   HWND hWnd1;
   int value1,scroll1,top1;
   POINT pt1,pt2;
   hWnd1 = (HWND) hb_parnl (1);
   value1 = (int) hb_parni (2);
   
   top1 = SendMessage((HWND) hWnd1,LVM_GETTOPINDEX,(WPARAM) (int) 0,(LPARAM) (int) 0);
   top1++;
   SendMessage((HWND) hWnd1,LVM_GETITEMPOSITION,(WPARAM) (int) top1,(LPARAM) &pt1);
   SendMessage((HWND) hWnd1,LVM_GETITEMPOSITION,(WPARAM) (int) value1,(LPARAM) &pt2);
   scroll1 = pt2.y - pt1.y;
   SendMessage((HWND) hWnd1,LVM_SCROLL,(WPARAM)(int) 0,(LPARAM)(int) scroll1);
}

HB_FUNC ( GRIDENSUREVISIBLE )
{
   HWND hWnd1;
   int value1;
   hWnd1 = (HWND) hb_parnl (1);
   value1 = (int) hb_parni (2);
   value1--;
   
   SendMessage((HWND) hWnd1,LVM_ENSUREVISIBLE,(WPARAM) (int) value1,(LPARAM) FALSE);
}
#pragma ENDDUMP
   
It is working well for ordinary grid (by commenting out line nos 46 and 48). For virtual grids, at least the item is ensured to be visible if not be the first item.
East or West HMG is the Best.
South or North HMG is worth.
...the possibilities are endless.

User avatar
mol
Posts: 3495
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 289 times
Been thanked: 197 times
Contact:

Post by mol »

Thanks Rathi for this very nice sample!
It's a pitty it's not working with virtual grid.

User avatar
mol
Posts: 3495
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 289 times
Been thanked: 197 times
Contact:

Post by mol »

Does Virtual Grid use ColumnControls?

In my opinion, NO, but, I don't know where check the source code...

User avatar
mol
Posts: 3495
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 289 times
Been thanked: 197 times
Contact:

Post by mol »

I want to return to grid definition.
Is there a way to format numeric columns displayed by GRID?

I have a column with numbers with 4 decimal places, but I want to display only two digits, with $ sign, eg. "$ 99,999.99".
I'm trying with ColumnControls with {"TEXHBOX","NUMERIC","$ 99,999.99"} but it doesn't work. It's for input data only, I think.

BROWSE has FORMAT <acFormat> property, but what about GRID?

User avatar
mol
Posts: 3495
Joined: Thu Sep 11, 2008 5:31 am
Location: Myszków, Poland
Has thanked: 289 times
Been thanked: 197 times
Contact:

Post by mol »

Hi guys!
I don't want to start new topic.
Can I ask if someone realized refreshing only one row in VIRTUAL GRID?
We can refresh it by setting ItemCount to 0 and back to number of rows, but it causes fklickering on screen.

User avatar
SALINETAS24
Posts: 564
Joined: Tue Feb 27, 2018 3:06 am
DBs Used: DBF
Has thanked: 76 times
Been thanked: 101 times
Contact:

Post by SALINETAS24 »

mol wrote:
Mon May 27, 2013 10:14 am
I want to return to grid definition.
Is there a way to format numeric columns displayed by GRID?

I have a column with numbers with 4 decimal places, but I want to display only two digits, with $ sign, eg. "$ 99,999.99".
I'm trying with ColumnControls with {"TEXHBOX","NUMERIC","$ 99,999.99"} but it doesn't work. It's for input data only, I think.

BROWSE has FORMAT <acFormat> property, but what about GRID?
Hola Mol, yo no utilizo el GRID VIRTUAL, pero ya que has abierto el hilo ..., aportare mi grano de arena y haré mi consulta. :lol:

1 - Mi grano de arena... :!:

Por lo poco que entiendo del GRID VIRTUAL, el array interno no existe, por lo que tienes que trabajar con el que has vinculado, y si quieres darle forma, o lo haces cuando creas el array o lo haces cuando lo cargas...

Code: Select all

#include <hmg.ch>

Function Main
   private aArray := { {'001', 'One', 'January' },;
                     { '002', 'Two', 'February' },;
                     { '003', 'Three', 'March' },;
                     { '004', 'Four', 'April' },;
                     { '005', 'Five', 'May' },;
                     { '006', 'Six', 'June' },;
                     { '007', 'Seven', 'July' },;
                     { '008', 'Eight', 'August' },;
                     { '009', 'Nine', 'September' },;
                     { '010', 'Ten', 'October' },;
                     { '011', 'Eleven', 'November' },;
                     { '012', 'Twelve', 'December' } }

   define window vgrid at 0, 0 width 500 height 400 main
   
      define textbox tbox1
         row 10
         col 10
         width 100
      end textbox
      define grid vgrid1
         row 40
         col 10
         width 350
         height 100
         widths { 60, 100, 150 }
         virtual .t.
         items aArray
         onQueryData getvgriddata()
         onheadclick { { || headclick1() }, { || headclick2() }, { || headclick3() } }
		 ONDBLCLICK PonerMensaje() 
         headers { 'Number', 'Name', 'Month' }
      end grid
	  
      define button addsomeitems
         row 150
         col 10
         caption 'Add Items'
         action AddItemToVGrid()
      end button   
   end window
   vgrid.vgrid1.value := 1
   vgrid.center
   vgrid.activate
   Return

function getvgriddata
   local i := this.queryrowindex
   local j := this.querycolindex
   IF j=1
	   this.querydata := TRANSFORM(aArray[ i, j ],"$999")
	ELSE
	   this.querydata := aArray[ i, j ]
   ENDIF
	
   return nil

function headclick1
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 1 ] < y[ 1 ] } )
   vgrid.vgrid1.visible := .t.
   return nil   
   
function headclick2
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 2 ] < y[ 2 ] } )
   vgrid.vgrid1.visible := .t.
   return nil   

function headclick3
   vgrid.vgrid1.visible := .f.
   asort( aArray, , , { |x, y| x[ 3 ] < y[ 3 ] } )
   vgrid.vgrid1.visible := .t.
   return nil      
   
function AddItemToVGrid()   
   vgrid.vgrid1.visible := .f.
   aadd( aArray, { '0' + alltrim( str( len( aArray ) + 1 ) ), 'New Item' + str( len( aArray ) + 1 ), 'New Item' + str( len( aArray ) + 1 ) } )
   vgrid.vgrid1.itemcount := len( aArray )
   vgrid.vgrid1.visible := .t.
   return nil
   
Procedure PonerMensaje()
LOCAL nFil,nCol		
	msgbox(vgrid.vgrid1.Value)
	msgdebug(aArray[vgrid.vgrid1.Value])
RETURN   


2 - Mi consulta :?:

Para trabajar con un GRID VIRTUAL sobre una DBF...,
¿Tengo que cargar todos los registros en el ARRAY vinculado...?
Y si es muy grande..., puede tardar mucho
¿Alguien puede facilitar un ejemplo de un GRID VIRTUAL que cargue los datos de una DBF...?

Agradecido de antemano por vuestra colaboración ...
Como dijo el gran pensador Hommer Simpson..., - En este mundo solo hay 3 tipos de personas, los que saben contar y los que no. :shock:

Post Reply