logo
vbRad Home
Source Code
Book Reviews
Forum
Links
About Us
Contribute

Compare Databases with SQL Effects Clarity
 
 How to quickly dump the contents of ADO recordset into MsFlexGrid

Posted on
2/18/2001
Author:
Robert Gelb
Email:
Not Shown
Applies To OS:
NT, 9x, 2000
Product:
5, 6



These routines are not particularly difficult or advanced, as much as they are useful.  I don't know how many times I've had to do some data massaging and these routines provided a quick way to see the data, optionally do various operations on it such as filtering or sorting.
Recordset Into Grid
Now, I know that just about every grid out there has data binding.  But, come on, no real programmer uses data binding.  It is limited by its very nature and takes control from the hands of developer.  Provided for download is a small application that takes advantage of these routines.  As you can see in the image or from code a little while below, the routines allow optional autosizing of columns and highliting of rows.  The routines are in a BAS module called modDataIntoGrid, so you can take it anywhere.

Download...

P.S.  One last note.  If you are out there fighting for the last ounce of speed and you have a client-side cursor with a dataset that has no Carriage Returns, use LoadRecordsetIntoGridNoCr sub instead of LoadRecordsetIntoGrid.  It will make loading large sets of data into MsFlexGrid much, much faster by taking advantage of the .Clip property of MsFlexGrid.

 

Code

Add the following to a .BAS module

Option Explicit

Private Sub HighlightGridRow(grd As MSFlexGrid, iRow As Long)
    With grd
        If .Rows > 1 Then
            .Row = iRow
            .Col = 1
            .ColSel = .Cols - 1
            .RowSel = iRow
        End If
    End With
End Sub



Public Sub LoadRecordsetIntoGrid(rs As Recordset, grd As MSFlexGrid, _
                Optional AutosizeColumns As Boolean = True, _
                Optional HighlightFirstRow As Boolean = True)
                
    Dim x As Long
    Dim Count As Long

    grd.Redraw = False
    grd.Clear

    'setup the minimum number of rows & add column headers
    grd.Rows = 2
    grd.FixedRows = 1
    grd.Row = 0
    grd.Cols = rs.Fields.Count + 1
    For x = 0 To rs.Fields.Count - 1
        grd.Col = x + 1
        grd.Text = rs.Fields(x).Name
        grd.ColData(x + 1) = rs.Fields(x).Type
    Next

    If rs.CursorLocation = adUseClient Then
        grd.Rows = rs.RecordCount + 1
        For Count = 1 To rs.RecordCount
            
            grd.TextMatrix(Count, 0) = Count    'assign line number
            For x = 0 To rs.Fields.Count - 1
                'we use Variant conversion to avoid any possible NULL errors
                grd.TextMatrix(Count, x + 1) = "" & CVar(rs.Fields(x).Value)
            Next
            rs.MoveNext
        Next
    ElseIf rs.CursorLocation = adUseServer Then
        Do While Not rs.EOF
            Count = Count + 1
            
            If Count >= grd.Rows Then
                'increase the amount of rows by 100 at a time
                'makes everything faster
                grd.Rows = grd.Rows + 100
            End If
            
            grd.TextMatrix(Count, 0) = Count    'assign line number
            For x = 0 To rs.Fields.Count - 1
                'we use Variant conversion to avoid any possible NULL errors
                grd.TextMatrix(Count, x + 1) = "" & CVar(rs.Fields(x).Value)
            Next
    
            rs.MoveNext
        Loop
		
        'reset the number of rows to the number of records		
        grd.Rows = Count + 1    
    End If
    
    'autosize the grid
    If AutosizeColumns Then SetGridColumnWidth grd

    'highlight the first row
    If HighlightFirstRow Then
        If grd.Rows > 1 Then HighlightGridRow grd, 1
    End If
    
    'redraw the entire grid
    grd.Redraw = True
End Sub



Public Sub LoadRecordsetIntoGridNoCr(rs As Recordset, grd As MSFlexGrid, _
                Optional AutosizeColumns As Boolean = True, _
                Optional HighlightFirstRow As Boolean = True)
                
    'This sub assumes that the records doesn't have any
    'data in it with Carriage Returns
    'This knowledge allows the routine to dump the
    'entire recordset wholesale into the MsFlexGrid 
    'via the .Clip property
    
    Dim x As Long
    Dim Count As Long

    'this prevents the grid from repainting 
    'everytime something is added
    grd.Redraw = False
    grd.Clear

    'setup the minimum number of rows & add column headers
    grd.Rows = 2
    grd.FixedRows = 1
    grd.Row = 0
    grd.Cols = rs.Fields.Count + 1
    For x = 0 To rs.Fields.Count - 1
        grd.Col = x + 1
        grd.Text = rs.Fields(x).Name
        grd.ColData(x + 1) = rs.Fields(x).Type
    Next

    If rs.CursorLocation = adUseClient Then
        If rs.RecordCount > 0 Then
            'setup all the rows necessary for this recordset
            grd.Rows = rs.RecordCount + 1
            grd.Row = 1
            grd.Col = 1
                        
            grd.ColSel = rs.Fields.Count
            grd.RowSel = rs.RecordCount
            
            'fill in the recordset
            grd.Clip = rs.GetString(, , Chr$(9), Chr$(13))
            
            'remove the highlight
            grd.RowSel = 0
            grd.ColSel = 0
            grd.Row = 1
            grd.Col = 1
            
            'assign record numbers
            For x = 1 To grd.Rows - 1
                grd.TextMatrix(x, 0) = x
            Next
            
        End If
    ElseIf rs.CursorLocation = adUseServer Then
        Do While Not rs.EOF
            Count = Count + 1
            
            If Count >= grd.Rows Then
                'increase the amount of rows by 100 at a time 
                'makes everything faster
                grd.Rows = grd.Rows + 100
            End If
            
            grd.TextMatrix(Count, 0) = Count    'assign line number
            For x = 0 To rs.Fields.Count - 1
                'we use Variant conversion to avoid any possible NULL errors
                grd.TextMatrix(Count, x + 1) = "" & CVar(rs.Fields(x).Value)
            Next
    
            rs.MoveNext
        Loop
		
        'reset the number of rows to the number of records
        grd.Rows = Count + 1    
    End If
    
    'autosize the grid
    If AutosizeColumns Then SetGridColumnWidth grd

    'highlight the first row
    If HighlightFirstRow Then
        If grd.Rows > 1 Then HighlightGridRow grd, 1
    End If
    
    'redraw the entire grid
    grd.Redraw = True
End Sub



Private Sub SetGridColumnWidth(grd As MSFlexGrid)
    'params:    ms flexgrid control
    'purpose:   sets the column widths to the 
    '           lengths of the longest string in the column
    'requirements:  the grid must have the same 
    '               font as the underlying form

    Dim InnerLoopCount As Long
    Dim OuterLoopCount As Long
    Dim lngLongestLen As Long
    Dim sLongestString As String
    Dim lngColWidth As Long
    Dim szCellText As String

    For OuterLoopCount = 0 To grd.Cols - 1
        sLongestString = ""
        lngLongestLen = 0

        'grd.Col = OuterLoopCount
        For InnerLoopCount = 0 To grd.Rows - 1
            szCellText = grd.TextMatrix(InnerLoopCount, OuterLoopCount)
            'grd.Row = InnerLoopCount
            'szCellText = Trim$(grd.Text)
            If Len(szCellText) > lngLongestLen Then
                lngLongestLen = Len(szCellText)
                sLongestString = szCellText
            End If
        Next
        lngColWidth = grd.Parent.TextWidth(sLongestString)

        'add 100 for more readable spreadsheet
        grd.ColWidth(OuterLoopCount) = lngColWidth + 200
    Next
End Sub


Add Your Comment  

Name: Email Address: all fields optional
Notify me via email when someone responds to this message (valid email required).

Enter the word:
 



Comments
#1. By John Kwan. Posted on 6/28/2006 4:01:16 AM
The demo is really good. However, is it possible to load a huge data set? I guessed that I tried to load something like > 100K of lines and I got an error of cannot allocate. I guess the grid control was not able to handle that volume. Can this be fixed?

#2. By Author. Posted on 6/28/2006 10:45:07 PM
Sorry. This is a limitation of the flexgrid. I'd recommend getting a 3rd party grid for large data sets.

#3. By Anonymous. Posted on 8/27/2006 11:57:29 AM
Very nice!

#4. By jeeten. Posted on 12/26/2006 10:30:22 AM
hi john Kwan,
Msflexgrid can handle a max of 2048 rows.
More than than i suggest you use datagrid or make the flexgrid get its data form alocal recordset and clear itself and re-update if the user starts approaching the 2048 row.
Some kind of "pages of 2048 rows" are displayed at any time.
Either way,a flexgrid with more than a thousand row is quite unergonomic and quite hard to give a meaningful use.

#5. By wapper. Posted on 3/28/2007 8:43:41 AM
Autosize columns will not work if you just remember the longest string and then get its TextWidth. "www" is wider than "iiii" if you are not using proportional font like Courier.

#6. By Max. Posted on 4/11/2007 4:29:06 PM
It is a pretty nice program but I can't use the modDataIntoGrid module in my project because i get an error about the ".CursorLocation" for recordset, it said that it couldn’t find the method or the data member, do you know why? I already add the ActiveX Data Objetcs 2.1 library. Thank you.

#7. By Author. Posted on 4/11/2007 4:35:20 PM
To comment 6: Add a reference to ADO 2.5 or higher instead.

#8. By nelo. Posted on 4/30/2007 12:49:36 PM
its very very good........

#9. By Rupin. Posted on 6/29/2007 6:50:41 PM
Hi,
The code is awesome..
But i am having a problem that in one of my forms the grid resizes and in other it does not...can you point out where i should take care..
Thanks

#10. By Peace_Dawg. Posted on 8/28/2007 9:44:31 PM
Dude you are awesome! As a novice and really trying to resurrect my programming knowledge; I as well as many others find it extremely difficult to find down to earth help with programming. I know just delivering code doesn't teach you, but it sure helps to allow sifting through the code for educational purposes. Much appreciated! I hope you create more examples of regularly used items for others to learn from.

#11. By Anonymous. Posted on 10/11/2007 6:47:19 PM
Its good but with 200 records it has an important delay, the logic its very good
Thanks

#12. By dhans. Posted on 1/11/2008 11:42:52 AM
Hi,

How to mshflaxgrid add rows varies methods. It s problem some time add rows displays in not mshflaxgrid

#13. By Arun babu. Posted on 6/9/2008 11:40:36 AM
nice work , i would like to add append methord of adorecordset also over here.

#14. By Geetha. Posted on 6/13/2008 9:23:02 AM
really its nice article...........
i have one doubt...
i have to pass the string from DLl file to POS screen in RMS
Thaks in advance
geetha

#15. By Adham. Posted on 7/17/2008 5:49:52 PM
Thank you Mr.Robert Gelb.
If you have any new code, i wish to send me as my e-mail
PLEASE.