Tech Note 03g: Using the Grid Object

April 02, 2008

© NSB Corporation. All rights reserved.

There is additional documentation on Microsoft's website.

The Grid Object displays and operates on tabular data. It allows complete flexibility to sort, merge, and format tables containing strings. It is included as part of the "ActiveX Control Objects 1.0" download, available at Microsoft's web site. See Tech Note 02 for more information on how to load this module onto your system.

It can be used to implement a "sorting" data display that groups information by category, allowing the user to modify the order in which information is presented or to create a spreadsheet.

To create a Grid Object, use a command such as the following:

addObject "Grid","Grid",0,0,215,150

Properties

Properties either set or return values. The syntax is

msgbox Grid.CellAlignment 'get the current CellAlignment

Grid.CellAlignment=9 'set the CellAlignment to general

Most properties refer to the current cell or all selected cells. The FillStyle property sets this.

Property Name

Description

CellAlignment

Sets/Returns how value are aligned in cells
0 Left Top
1 Left Center (default for strings)
2 Left Bottom
3 Center Top
4 Center Center
5 Center Bottom
6 Right Top
7 Right Center (default for numbers)
8 Right Bottom
9 General: Left Ctr for strings, Rt Ctr for number

CellBackColor

Color

CellForeColor

Color

CellFontBold

True/False

CellFontItalic

True/False

CellFontName

String name of font

CellFontSize

Fontsize in points

CellFontStrikeThrough

True/False

CellFontUnderline

True/False

CellHeight

height of current cell

CellLeft

left of current cell

CellTop

top of current cell

CellWidth

width of current cell

CellTextStyle

text style
0 Flat (normal text)
1 Raised
2 Inset
3 Raised Light
4 Inset Light

Clip

Set/returns contents of current cell

Col

Col position of current cell

Row

Row position of current cell

ColAlignment

Sets alignment for specified row: see CellAlignment
GridCtrl1.ColAlignment(2)=9

ColData

Assigns a specific number to col
GridCtrl1.ColData(2)=3

RowData

Assigns a specific number to row
GridCtrl1.RowData(1)=4

ColisVisible

True/False
GridCtrl1.ColisVisible(1)

ColPos

returns distance from upper left corner

ColPosition

Moves a column
GridCtrl1.ColPosition(1)=2

RowPosition

Moves a row
GridCtrl1.RowPosition(1)=2

Cols

returns or sets the number of columns

Rows

or sets the number of rows

ColSel

returns or sets the current selected column

RowSel

returns or sets the current selected row

ColWidth

returns or sets the column width in twips
GridCtrl1.ColWidth(1)=1440

FillStyle

0:operations affect current cell, 1:selected cells

FocusRect

0:no box, 1:light box, 2:heavy box

ForeColor

color

ForeColorSel

color

GridColor

color

GridLines

Defines how lines look between cells
0 No Lines. No lines in between cells.
1 Lines(default for GridLines). Sets line style between cells to normal lines.
2 Inset Lines. Sets line style between cells to inset lines.
3 Raised Lines. Sets line style between cells to raised lines

GridLineWidth

Values from 0 to 10

HighLight

0 don't hilite, 1 always, 2 if object has focus

LeftCol

returns or sets the leftmost visible cell

Redraw

True/False. Redraw after each change?

RowHeight

Returns or stes height of specified row
GridCtrl1.RowHeight(1)=1440

RowHeightMin

Mimimum height for a row

RowIsVisible

True/False
GridCtrl1.RowIsVisible(1)

RowPos

returns distance from upper left corner

ScrollBars

0 none, 1 horizontal, 2 vertical, 3 both

ScrollTrack

True/False. Update object while using scrollbar?

SelectionMode

0 normal selection, 1 by row, 2 by column

Sort

sorts rows base on current selection
0 None
1 Generic Ascending. Guesses whether text is string or number
2 Generic Descending.
3 Numeric Ascending. Converts strings to numbers.
4 Numeric Descending
5 String Ascending. Case insensitive
6 String Descending. Case insensitive
7 String Ascending. Case sensitive
8 String Descending. Case sensitive
9 Custom. Uses Compare event to compare rows

Text

returns or sets contents of current cell

TextArray

returns or sets cell specified by cellIndex
cellIndex is calculated as row*cols + col
GridCtrl1.TextArray(cellIndex)

TextMatrix

returns or sets value of specified cell
GridCtrl1.TextMatrix(r,c)

TextStyle

One of the following:
0 Flat (normal text)
1 Raised
2 Inset
3 Raised Light
4 Inset Light

TopRow

returns or sets the topmost visible cell

Version

returns the version of the Grid Control

WordWrap

True/False

 

Methods

Method Name

Arguments

Description

AddItem

item[,index]

Adds a row. Use a tab separated string for multiple columns. If index not specified, new row goes at end.

Clear

 

clears all cells

HideGridLines

 

Hides the lines between the grid cells

Move

left[,top][,width][,height]

Move the grid to new coordinates. Since there is no hide or show, this can be used to move a grid offscreen. Units are in twips: there are 15 twips per pixel.

RemoveItem

index

Deletes the specified row.

 

 

Events

 

Events cause subroutines in your program to be called, if they exist. You should name the subroutine <objectName>_evenName.

 

For example, to capture leaving a cell in GridCtrl1, you will need

sub Grid_LeaveCell
'your code
end sub

 

Event Name

Arguments

Description

Click

Cell clicked in

Compare

row1,row2

Called by Sort with option 9. Return minus 1 if row1 is less, 0 if equal, 1 if row1 is greater than row2.

EnterCell

 

Called when selecting a cell.

LeaveCell

 

Called when de selecting a cell

RowColChange

 

Called when cell changes

Scroll

 

Called when object is scrolled

SelChange

 

Called when selection is changed.

 

Remarks

 

1. The Row and Col properties specify the current cell in a Grid. You can specify the current cell in code, or the user can change it at run time using the mouse or the arrow keys. The Text property references the contents of the current cell.

2. If a cell's text is too long to be displayed in the cell, and the WordWrap property is set to True, the text wraps to the next line within the same cell. To display the wrapped text, you may need to increase the cell's column width (ColWidth property) or row height (RowHeight property).

3. The Cols and Rows properties are used to determine the number of columns and rows in a Grid control.

4. Russ Smith, an NS Basic/CE user, notes on the topic of getting two grids to scroll together:

I solved the problem of having a title grid that appears to scroll with the record grid. The following Sub is called when I first load the record grid and every time the _Scroll() method is called. When I load the grid, I set recTitle.colData(0) to -1 to force a redraw.

Sub ShowTitles() If recTitle.colData(0)<>recGrid.leftCol Then recTitle.redraw = False recTitle.cols = RS.fields.Count 'just to be sure we have enough slots Dim gC gC = recGrid.leftCol Do recTitle.textMatrix(0,gC-recGrid.leftCol)=RS.fields(gC).name gC=gC+1 Loop While recGrid.ColIsVisible(gC) recTitle.colData(0)=recGrid.leftCol recTitle.Cols = gC-recGrid.leftCol recTitle.redraw = True End If End Sub

As you can see, it really doesn't scroll the other grid, but the titles appear over the appropriate columns so I'm happy. I tried setting recTitle.leftCol to recGrid.leftCol but it just ignored it.

5. If you're feeding data from an ADOCE database into a Grid control, Russ notes:

If you use recGrid.rowData(idx) to store RS.absolutePosition as you load the grid with record data, the following code sets the record pointer to the same record as is selected in the grid:

RS.Move recGrid.rowData(recGrid.rowSel)-1, adBookmarkFirst

6. If you change the any one of the bounds properties (Left, Top, Width, Height, the other 3 will be set to -1. Microsoft has no plans to correct this bug.

7. Bill Heintz wiliamh63© verizon.net suggests: Remark #4 mentions the work of programmer Russ Smith. This solution is workable.

Unfortunately, I wanted to create a spreadsheet like application with a row header and a column header that could scroll. I wanted to allow for different sized columns and rows. I could not for the life of me determine why Microsoft wouldn’t allow the you to intercept the _Scroll() method and then tell your titles to move accordingly. Microsoft wouldn’t allow you to move the title rows unless they had their own scroll bars.

The solution is to first set-up the title grid objects. Make sure your row title bar has the vertical scroll bar by setting: GridRowTitles.ScrollBars = 2. The column titles need the horizontal scroll bar: GridColTitles.ScrollBars = 1. Lastly, draw the main grid object on top, covering the title scroll bars. Set this grid area to accept both scrolls.

This code then accepts the main scroll and aligns the title rows accordingly:

sub ScrollGrid_scroll()
'scroll grid, scroll titles when grid scrolled
 if GridRowTitles.TopRow <> ScrollGrid.TopRow then
  GridRowTitles.TopRow= ScrollGrid.TopRow
 end if
 if GridColTitles.LeftCol <> ScrollGrid.LeftCol then
 GridColTitles.LeftCol= ScrollGrid.LeftCol
 end if
end sub

The Grid objects accept user clicks and will scroll in response. To prevent the headers from doing this, simply disable input:

GridColTitles.enabled = false
GridRowTitles.enabled = false
See Sample Program 2 below.

Sample Program 1

Rem demonstrate use of Grid Object
Option Explicit
addobject "gridctrl.gridctrl.1","grid",0,0,215,150
grid.cols=3
grid.rows=9
makeButton "Text","Text",225,30,50,20
makeButton "Clear","Clear",225,0,50,20
makeButton "Bold","B",300,0,20,20
makeButton "Italic","I",325,0,20,20
makeButton "Underline","U",350,0,20,20
makeButton "Strike","S",375,0,20,20
form_load

Private Sub makeButton(name, prompt, x,y,w,h)
  addObject "commandButton",name & "Btn",x,y,w,h
  execute name & "Btn.Text=" & chr(34) & prompt & chr(34)
end sub

Sub BoldBtn_Click()
  Dim n
  n = grid.CellFontBold
  If n Then
    grid.CellFontBold = False
  Else
    grid.CellFontBold = True
  End If
End Sub

Sub ClearBtn_Click()
  grid.Clear
End Sub

Sub Form_Load()
  grid.TextMatrix(0, 0) = "Kenny"
  grid.TextMatrix(1, 0) = "Carmen"
  grid.TextMatrix(2, 0) = "Kyle"
  grid.TextMatrix(3, 0) = "Eric"
      
  grid.TextMatrix(0, 1) = "Grossman"
  grid.TextMatrix(1, 1) = "Crabtree"
  grid.TextMatrix(2, 1) = "Garrison"
  grid.TextMatrix(3, 1) = "Cartman"
      
  grid.TextMatrix(0, 2) = "Denver"
  grid.TextMatrix(1, 2) = "Boulder"
  grid.TextMatrix(2, 2) = "South Park"
  grid.TextMatrix(3, 2) = "Lakeview"
   
  grid.FillStyle = 1
  grid.Row = 0
  grid.Col = 0
  grid.ColSel = 2
  grid.CellFontBold = True
  grid.CellFontUnderline = True
  grid.Col = 0
End Sub

Sub ItalicBtn_Click()
  Dim n
  n = grid.CellFontItalic
  If n Then
    grid.CellFontItalic = False
  Else
    grid.CellFontItalic = True
  End If
End Sub

Sub StrikeBtn_Click()
  Dim n
  n = grid.CellFontStrikeThrough
  If n Then
    grid.CellFontStrikeThrough = False
  Else
    grid.CellFontStrikeThrough = True
  End If
End Sub

Sub TextBtn_Click()
  grid.Text = inputBox("Input Text","Grid Object")
End Sub

Sub UnderlineBtn_Click()
  Dim n
  n = grid.CellFontUnderline
  If n Then
    grid.CellFontUnderline = False
  Else
    grid.CellFontUnderline = True
  End If
End Sub

Sample Program 2

This sample uses the above to demonstrate the smooth scrolling with different sized columns and rows:
(Submitted by Bill Heintz wiliamh63© verizon.net)

option explicit

dim MaxRows, MaxCols
MaxRows = 31
MaxCols = 15
MainForm_Show  'Default Form

'*******Main Routine*********
call startUp
call LoadBlock
'*******End Main Routine*********

'******* Routines **********
sub LoadBlock()
  'populates the table
 dim i, j
  for j = 0 to MaxCols
   for i = 0 to MaxRows
    ScrollGrid.textmatrix(i,j) = i & "," & j
   next 'i
   'replace with yyour own code: give columns different widths:
   ScrollGrid.colwidth(j)= 350 + j * 20
   GridColTitles.colwidth(j)= 350 + j * 20
 
 next 'j
 'can have different row heights, too:
 ScrollGrid.rowheight(12)= 350
 GridRowTitles.rowheight(12)= 350
 
 'to set to 0,0
 ScrollGrid.Row = 0
 ScrollGrid.Col = 0
 GridRowTitles.Row = 0
end sub
'************************
sub setRow(myRow)
 'sets-up current grid row parameters
 ScrollGrid.RowHeight(myRow) = 203
 GridRowTitles.RowHeight(myRow) = 203
 GridRowTitles.Col = 0
 GridRowTitles.Row = myRow
 GridRowTitles.CellAlignment = 7
 ScrollGrid.CellFontName = "Courier New"
 GridRowTitles.textmatrix(MyRow,0) = MyRow 
end sub 'setRow
'************************
sub startUp
 dim i,j
 'set-up grid - Col width you set
 GridRowTitles.ColWidth(0) = 353
 for i = 0 to MaxRows 
  setRow(i)
 next 'i
 for j = 0 to MaxCols
  GridColTitles.textmatrix(0,j) = j
  ScrollGrid.ColWidth(j) = 270
  GridColTitles.ColWidth(j) = 270
 next 'j 
 GridColTitles.enabled = false
 GridRowTitles.enabled = false
end sub  'startUp
'******* End Routines ******

'*******Grid Routines ********
sub ScrollGrid_scroll()
'scroll grid, scroll titles when grid scrolled
 if GridRowTitles.TopRow <> ScrollGrid.TopRow then
  GridRowTitles.TopRow= ScrollGrid.TopRow
 end if
 if GridColTitles.LeftCol <> ScrollGrid.LeftCol then
 GridColTitles.LeftCol= ScrollGrid.LeftCol
 end if
end sub
'******* End Grid Routines ****



'*** Begin Generated Code ***

Dim AppEXEName: AppEXEName = "ScrollGrid"
Dim AppPath: AppPath = "C:\Documents and Settings\heintzwf\my documents\Private\Personal\NSItems\Projects\ScrollGrid.txt"

MainForm_Show 'Default Form

Dim MainForm_Temp
Sub MainForm_Show
   On Error Resume Next

   UpdateScreen

   If IsEmpty(MainForm_Temp) Then
      AddObject "Frame", "MainForm_Form", 0, 0, Output.Width, Output.Height
      MainForm_Form.Visible = False
      MainForm_Form.BackColor = 12632256
      AddObject "PictureBox", "MainForm", 0, 0, 0, 0, MainForm_Form
      MainForm.BorderStyle = 0
      MainForm.Move 0, 0, MainForm_Form.Width * 15, MainForm_Form.Height * 15
      Set MainForm_Temp = MainForm
      MainForm_Form.Caption = "MainForm"
   
      Execute "AddObject " & chr(34) & "GridCtrl.GridCtrl" & chr(34) & ", " & chr(34) & "GridColTitles" & chr(34) & ", 24, 16, 204, 38, MainForm_Form"
      GridColTitles.Cols = 16
      GridColTitles.Rows = 1
      GridColTitles.ScrollBars = 1
      '--------
      Execute "AddObject " & chr(34) & "GridCtrl.GridCtrl" & chr(34) & ", " & chr(34) & "GridRowTitles" & chr(34) & ", 0, 32, 104, 129, MainForm_Form"
      GridRowTitles.CellAlignment = 7
      GridRowTitles.Cols = 1
      GridRowTitles.Rows = 32
      GridRowTitles.ScrollBars = 2
      GridRowTitles.ScrollTrack = True
      '--------
      Execute "AddObject " & chr(34) & "GridCtrl.GridCtrl" & chr(34) & ", " & chr(34) & "ScrollGrid" & chr(34) & ", 24, 32, 217, 142, MainForm_Form"
      ScrollGrid.Cols = 16
      ScrollGrid.Rows = 32
      '--------
   End If
   MainForm_Form.Visible = True
   MainForm_Load
End Sub  'MainForm_Show

Sub MainForm_Hide
   If IsEmpty(MainForm_Temp) Then
      Err.Raise 44000, , "Form not loaded"
      Exit Sub
   End If

   On Error Resume Next
   MainForm_Form.Visible = False
   MainForm_Unload
End Sub  'MainForm_Hide

'*** End Generated Code ***