Copyright: Copyright © 1993-1997 Sheridan Software Systems


Can I add groups and switch columns between groups at runtime?

Reference: DAT1125

Yes.  Use the Add method on groups and set the Group property of columns.

The following code sample demonstrates how to add three new groups to the DataGrid and then add two columns in the grid to these groups.  The same code can be used for both the DataCombo and the DataDropdown.

Private Sub Command1_Click()

For i = 0 To 3

SSDBGrid1.Groups.Add i

Next i

' Set the groups

SSDBGrid1.Columns(1).Group = 2

SSDBGrid1.Columns(2).Group = 2

End Sub


Contents
Frequently Asked Questions (by topic)	Back to main help contents

Conversion | Data Binding | Formatting | Searching | Moving/Copying | Programming

To see this list categorized by control, click here.

Conversion Issues

What is different in version 2.0?

What is the best method of learning Data Widgets 2.0?

Is there an automatic conversion utility available when converting from Data Widgets 1.0 to Data Widgets 2.0?

Data Binding Issues

Why can't Data Widgets controls be bound in Visual C++ 4.0?

How can I write all of the data that resides in an Additem DataGrid into a database?

How can I trap for messages through the DBEngine directly and display the Error Number and Error Description from DAO?

When using SQLPassThrough, the DataCombo's ListAutoPosition and ListAutoValidate no longer work. Why?

Why do I get an error when I bind the DataCombo's DataSource to a MSRDC control and perform a MSRDC1.ResultSet.Update?

When I bind the SSDBCombo’s DataSourceList to a DataControl and choose an item from the list, my other bound controls do not reflect the same record.

Formatting & Design Issues

When I set the CellStyleSet to a particular cell then scroll the cell out of view, the CellStyleSet is no longer applied when the cell scrolls back into view - how can I fix this?

How would I limit the number of characters in the text portion of the DataCombo?

How would I color a row based upon what has been entered into a cell?

How can I format a cell within the DataGrid for a Zip Code without using the NumberFormat property of the column object?

How can I limit the number of characters typed in a cell in a DataGrid and accept only numeric values a valid entry?

When starting the Custom DataGrid editor, why do I get an error 31037 "Error loading from file"?

How can I sort the Columns in an AddItem DataGrid since there is no "Ordered" property?

How can I place the Record number of the row in an Unbound Column of a bound SSDBGrid?

When using the SSDBCombo in Visual C++ 4.X, why will a charcter typed in the edit portion appear for a second then disappear?

Search and Retrieval

The Enhanced Data Control displays a message box when the Find function does not find anything.  How can I post my own message instead of the default message?

How can I search for a string in a column of the SSDBGrid?

How can I perform my own incremental search in an SSDBCombo?

How can I create a DataCombo that acts as a "Quicken™" Combo box?

How can I put default search strings and selection criteria in the Find dialog without having to construct my own Find dialog?

Moving and Copying Data

How do I copy the SSDBGrid contents to the clipboard?

How can I drag an entire row from one AddItem DataGrid to another AddItem DataGrid?

How can I copy the contents of a bound DataGrid to an AddItem DataGrid?

How can I select a consecutive number of cells and copy their contents to the clipboard?

How can I copy text from cell to cell in an AddItem grid using the mouse without overwriting any existing text?

Programmatic Control

Can I add groups and switch columns between groups at runtime?

How would I use one drop down to update several columns on a grid?

When using an unbound DataGrid, how can I display a value from my dynaset in a text box as I change rows?

How can I compare the LastRow parameter in the RowColChange event with the current bookmark for the DataGrid?

How can I lock a cell in a bound DataGrid?

How can I total a column in a bound DataGrid?

If I am loading an Additem DataGrid with a dynaset, how can I synchronize the dynaset with the DataGrid?

How can I update a DataGrid without moving off the row or if the Grid loses focus?

How can I synchronize the horizonal scrolling of two DataGrids?

How can I set focus to the next control in the tab order when I hit the tab key while the DataGrid has focus?

How can I determine if I am loading an EvenRow or an OddRow in the Bound SSDBGrid?

How can I check if the current row in the grid is selected or deselected?

How can I loop through the SelBookmarks collection in the order they appear on the DataGrid, not in the order they were selected?

How can I manually 'ListAutoPosition' through an AddItem combo list using all entered characters?

How do I know what row I am on in a DataGrid?

When distributing my application that has a Data Widgets 2.0 control included, the Form will open, but will return an error "Can’t Load Custom Control DLL".

How can I programmatically select a row?

Why isn’t the SSDBCombo or SSDBDropdown dropping down?


Contents Controls
Frequently Asked Questions (by control)

Grid | Combo/DropDown | EDC | General

To see this list categorized by topic, click here.

SSDBGrid

When I set the CellStyleSet to a particular cell then scroll the cell out of view, the CellStyleSet is no longer applied when the cell scrolls back into view - how can I fix this?

Can I add groups and switch columns between groups at runtime?

When using an unbound DataGrid, how can I display a value from my dynaset in a text box as I change rows?

How can I compare the LastRow parameter in the RowColChange event with the current bookmark for the DataGrid?

How can I lock a cell in a bound DataGrid?

How can I total a column in a bound DataGrid?

How would I color a row based upon what has been entered into a cell?

If I am loading an Additem DataGrid with a dynaset, how can I synchronize the dynaset with the DataGrid?

How can I update a DataGrid without moving off the row or if the Grid loses focus?

How can I write all of the data that resides in an Additem DataGrid into a database?

How can I search for a string in a column of the SSDBGrid?

How can I copy the contents of a bound DataGrid to an AddItem DataGrid?

How can I synchronize the horizonal scrolling of two DataGrids?

How can I format a cell within the DataGrid for a Zip Code without using the NumberFormat property of the column object?

How can I set focus to the next control in the tab order when I hit the tab key while the DataGrid has focus?

How can I limit the number of characters typed in a cell in a DataGrid and accept only numeric values a valid entry?

How can I determine if I am loading an EvenRow or an OddRow in the Bound SSDBGrid?

When starting the Custom DataGrid editor, why do I get an error 31037 "Error loading from file"?

How do I copy the SSDBGrid contents to the clipboard?

How can I place the Record number of the row in an Unbound Column of a bound SSDBGrid?

How can I check if the current row in the grid is selected or deselected?

How can I loop through the SelBookmarks collection in the order they appear on the DataGrid, not in the order they were selected?

How can I drag an entire row from one AddItem DataGrid to another AddItem DataGrid?

How can I copy text from cell to cell in an AddItem grid using the mouse without overwriting any existing text?

How can I sort the Columns in an AddItem DataGrid since there is no "Ordered" property?

How do I know what row I am on in a DataGrid?

SSDBCombo & SSDBDropDown

How would I limit the number of characters in the text portion of the DataCombo?

How would I use one drop down to update several columns on a grid?

When using SQLPassThrough, the DataCombo's ListAutoPosition and ListAutoValidate no longer work. Why?

How can I perform my own incremental search in an SSDBCombo?

Why do i get an error when I bind the DataCombo's DataSource to a MSRDC control and perform a MSRDC1.ResultSet.Update?

How can I create a DataCombo that acts as a "Quicken™" Combo box?

How can I manually 'ListAutoPosition' through an AddItem combo list using all entered characters?

Why isn’t the SSDBCombo or SSDBDropdown dropping down?

When I bind the SSDBCombo’s DataSourceList to a DataControl and choose an item from the list, my other bound controls do not reflect the same record.

When using the SSDBCombo in Visual C++ 4.X, why will a charcter typed in the edit portion appear for a second then disappear?

Enhanced Data Control

The Enhanced Data Control displays a message box when the Find function does not find anything.  How can I post my own message instead of the default message?

How can I put default search strings and selection criteria in the Find dialog without having to construct my own Find dialog?

General Control Questions

Why can't Data Widgets controls be bound in Visual C++ 4.0?

What is different in version 2.0?

Is there an automatic conversion utility available when converting from Data Widgets 1.0 to Data Widgets 2.0?

How can I trap for messages through the DBEngine directly and display the Error Number and Error Description from DAO?

How can I select a consecutive number of cells and copy their contents to the clipboard?

What is the best method of learning Data Widgets 2.0?

When distributing my application that has a Data Widgets 2.0 control included, the Form will open, but will return an error "Can’t Load Custom Control DLL".

How can I programmatically select a row?


How can I check if the current row in the grid is selected or deselected?

Reference: DAT1204

The following code determines the selection state of the current row.

Dim Selected as boolean

For i = 0 to SSDBGrid1.Selbookmarks.count -1

If CStr(SSDBGrid1.Bookmark) = CStr(SSDBGrid1.SelBookmarks(i) then

msgbox "Row is Selected"

Selected = true

End if

Next

If Selected = False then

msgbox "Row is Not Selected"

End If


How can I compare the LastRow parameter in the RowColChange event with the current bookmark for the DataGrid?

Reference: DAT1136

Use the following procedure:

Private Sub SSDBGrid1_RowColChange(ByVal LastRow As Variant, ByVal LastCol As Integer)

Dim bm As String

bm = CStr(SSDBGrid1.Bookmark)

If bm <> CStr(LastRow) Then

Form1.Print "new row"

Else

Form1.Print "same row"

End If

End Sub


How can I copy text from cell to cell in an AddItem grid using the mouse without overwriting any existing text?

Reference: DAT1223

Use the following in an AddItem grid with 3 columns and FieldSeparator of comma:

(General)(declarations)

Dim tempstr$

Private Sub SSDBGrid1_InitColumnProps()

For i = 0 To 20

SSDBGrid1.AddItem "Data Widgets," & i

Next i

End Sub

Private Sub SSDBGrid1_DragDrop(Source As Control, X As Single, Y As Single)

Dim dropcol%

dropcol = SSDBGrid1.ColContaining(X)

If SSDBGrid1.Columns(dropcol).Text <> "" Then

MsgBox ("something here: Cancel")

Else

SSDBGrid1.Bookmark = SSDBGrid1.RowContaining(Y)

SSDBGrid1.Columns(dropcol).Text = tempstr

SSDBGrid1.Update

End If

End Sub

Private Sub SSDBGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

If Button = 2 Then	' Right mouse button clicked

SSDBGrid1.DragIcon = LoadPicture("c:\vb4\icons\arrows\point04.ico")

SSDBGrid1.Drag 1	' Set drag action to drag

SSDBGrid1.Bookmark = SSDBGrid1.AddItemBookmark(SSDBGrid1.RowContaining(Y))	' Set the bookmark of the row

tempstr = SSDBGrid1.Columns(SSDBGrid1.ColContaining(X)).CellText(bm)

End If

End Sub


How can I copy the contents of a bound DataGrid to an AddItem DataGrid?

Reference: DAT1165

The following procedure copies the entire contents of a data-bound grid to an AddItem grid.

Place a bound SSDBGrid on a form. Place a seccond SSDBGrid on a form and set the following properties:

DataMode	=  2 - AddItem

Place a command button on the form and put the following code in the Click event. This code copies the grid data to the clipboard:

Private Sub Command1_Click()

Dim bm As Variant

Dim datastr As String

MousePointer = 11

For i = 0 To SSDBGrid1.Columns.Count - 1

SSDBGrid2.Columns.Add i

SSDBGrid2.Columns(i).Caption = SSDBGrid1.Columns(i).Caption

Next i

For X = 0 To SSDBGrid1.Rows - 1

bm = SSDBGrid1.GetBookmark(X)

datastr = ""

For i = 0 To SSDBGrid1.Columns.Count - 1

datastr = datastr & SSDBGrid1.Columns(i).CellText(bm)

If i < SSDBGrid1.Columns.Count - 1 Then

datastr = datastr & vbTab

End If

Next i

SSDBGrid2.AddItem datastr

Next X

MousePointer = 0

End Sub


How can I create a DataCombo that acts as a "Quicken" Combo box?
How can I create a DataCombo that acts as a "Quicken™" Combo box?

Reference: DAT1218

A "Quicken" combo fills in the edit portion based on the letters the user types. For example, if the user types "A" the combo fills in the text of the first value that begins with the letter A. When they type the second letter, the combo fills in the text of the first value that begins with the two letters typed. For example, if the combo were attached to a list of foods, typing A might fill the edit portion of the combo with the word "apple." If the user then typed the letter "V" the combo would be filled with "avocado."

Use the following procedure to emulate a "Quicken" combo box:

(General)(declarations)

Private ComboSelstart As Integer

Private Sub SSDBCombo1_Click()

ComboSelstart = 0

End Sub

Private Sub SSDBCombo1_KeyUp(KeyCode As Integer, Shift As Integer)

If KeyCode >= 65 And KeyCode <= 90 Then

Data1.Recordset.FindFirst "author like '" & SSDBCombo1.Text & "*'"

If Not Data1.Recordset.NoMatch Then

ComboSelstart = ComboSelstart + 1

SSDBCombo1.Text = Data1.Recordset("author")

SSDBCombo1.SelStart = ComboSelstart

SSDBCombo1.SelLength = Len(SSDBCombo1.Text) - ComboSelstart

Else

ComboSelstart = 0

SSDBCombo1.SelStart = ComboSelstart

SSDBCombo1.SelLength = Len(SSDBCombo1.Text)

End If

End If

End Sub

Private Sub SSDBCombo1_LostFocus()

If SSDBCombo1.IsItemInList = False then

Msgbox "Item not in list"

ComboSelstart = 0

End If

End Sub

For a dropdown in column 1 of a grid, change KeyUp event to look like this....

Private Sub SSDBGrid1_KeyUp(KeyCode As Integer, Shift As Integer)

If KeyCode >= 65 And KeyCode <= 90 And SSDBGrid1.Col = 1 Then

Data1.Recordset.FindFirst "author like '" & SSDBGrid1.Columns(1).Text & "*'"

If Not Data1.Recordset.NoMatch Then

ComboSelstart = ComboSelstart + 1

SSDBGrid1.Columns(1).Text = Data1.Recordset("author")

SSDBGrid1.ActiveCell.SelStart = ComboSelstart

SSDBGrid1.ActiveCell.SelLength = Len(SSDBGrid1.Columns(1).Text) - ComboSelstart

Else

ComboSelstart = 0

SSDBGrid1.ActiveCell.SelStart = ComboSelstart

SSDBGrid1.ActiveCell.SelLength = Len(SSDBGrid1.Columns(1).Text)

End If

End If

End Sub


How can I determine if I am loading an EvenRow or an OddRow in the Bound SSDBGrid?

Reference: DAT1183

Use the following code to determine the type of row being loaded.

First, add this statement to the (General) (declarations) section of the form containing the grid:

Dim rs as dynaset

Then enter the following event code:

Private Sub SSDBGrid1_InitColumnProps()

Set rs = Data1.Recordset.Clone

SSDBGrid1.Columns.Add 0

SSDBGrid1.Columns(0).Caption = "Record Number"

End Sub

Private Sub SSDBGrid1_RowLoaded(ByVal Bookmark As Variant)

rs.Bookmark = Bookmark

If rs.AbsolutePosition Mod 2 = 0 Then

Debug.Print "evenrow"

Else

Debug.Print "oddrow"

End If

End Sub


How can I drag an entire row from one AddItem DataGrid to another AddItem DataGrid?

Reference: DAT1211

The following procedure shows how to drag a selected row from one grid to another:

First, place two SSDBGrid's on a form - both in AddItem mode with  AllowAddNew set to True. Then specify the following code for the events of each grid:

Private Sub SSDBGrid1_InitColumnProps()

For i = 0 To 20

SSDBGrid1.AddItem "Data Widgets," & i

Next i

End Sub

Public Sub SSDBGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim bm As Variant

If Button = 2 and SSDBGrid1.Whereis(X,Y) = ssWhereIsData Then	' Right mouse button clicked

' Use the following line to specify a custom drag icon (optional)

SSDBGrid1.DragIcon = LoadPicture("d:\vb4\icons\dragdrop\drag1pg.ico")

SSDBGrid1.Drag 1	' Set drag action to drag

bm = SSDBGrid1.AddItemBookmark(SSDBGrid1.RowContaining(Y))	' Get the bookmark of the row

SSDBGrid1.Bookmark = bm	' Set the current bookmark to the row

End If

End Sub

Private Sub SSDBGrid2_DragDrop(Source As Control, X As Single, Y As Single)

SSDBGrid2.AddItem ""

For i = 0 To SSDBGrid1.Columns.Count - 1

SSDBGrid2.Columns(i).Text = SSDBGrid1.Columns(i).CellText(SSDBGrid1.Bookmark)	' Copy Grid1 contents to Grid2	Next i

SSDBGrid2.Update

SSDBGrid2.MoveNext

SSDBGrid1.Drag 2	' Drag action stopped

End Sub


How can I format a cell within the DataGrid for a ZIP Code without using the NumberFormat property of the column object?

Reference: DAT1173

Use this two step procedure to perform the formatting:

1. Set the Column object's FieldLen property to 9 in the InitColumnProps event of the DataGrid:

Private Sub SSDBGrid1_InitColumnProps()

SSDBGrid1.Columns(n).FieldLen = 9

End Sub

2. Parse the text of the column into ZIP code format.

Private Sub SSDBGrid1_AfterColUpdate(ByVal ColIndex As Integer)

Dim TextLen As Integer

Dim strg As String

strg = SSDBGrid1.Columns(ColIndex).Text

TextLen = Len(strg)

If TextLen = 5 Then

SSDBGrid1.Columns(ColIndex).Text = Left$(strg, 5) & " "

ElseIf TextLen > 5 Then

SSDBGrid1.Columns(ColIndex).Text = Left$(strg, 5) & "-" & Right$(strg, TextLen - 5)

End If

End Sub


How can I limit the number of characters typed in a cell in a DataGrid and accept only numeric values a valid entry?
How can I limit the number of characters typed in a cell in a DataGrid and accept only numeric values as a valid entry?

Reference: DAT1179

The following code allows only numeric keystrokes (or backspaces) and limits the length of the value entered to six digits:

Put the following code in the DataGrid's KeyPress event:

If SSDBGrid1.Col = 0 Then

If Len(SSDBGrid1.Columns(0).Text) > 5 And KeyAscii <> 8 Then

KeyAscii = 0

Beep

Else

If (KeyAscii < 48 Or KeyAscii > 57) And KeyAscii <> 8 Then

KeyAscii = 0

Beep

End If

End If

End If


How can I lock a cell in a bound DataGrid?

Reference: DAT1138

Use the RowColChange event, as outlined in the following procedure:

The following will lock the cell in row 5, column 1:

Private Sub SSDBGrid1_RowColChange(ByVal LastRow As Variant, ByVal LastCol As Integer)

If SSDBGrid1.Col = 1 And Data1.Recordset.AbsolutePosition = 5 Then

SSDBGrid1.Columns(1).Locked = True

Else

SSDBGrid1.Columns(1).Locked = False

End If

End Sub


How can I loop through the SelBookmarks collection in the order they appear on the DataGrid, not in the order they were selecte
How can I loop through the SelBookmarks collection in the order they appear on the DataGrid, not in the order they were selected?

Reference: DAT1206

The following will step through the selected bookmarks in the order they appear:

Private Sub Command1_Click()

Dim bm As Variant

Dim j, i  As Integer

' MoveFirst is necessary when using GetBookmark method;

' this method is specific to the DataGrid's current location

SSDBGrid1.MoveFirst

For i = 0 To SSDBGrid1.Rows - 1

bm = SSDBGrid1.GetBookmark(i)	' Get the bookmark for each row

For j = 0 To SSDBGrid1.SelBookmarks.Count - 1	' For each selected row

If CStr(bm) = CStr(SSDBGrid1.SelBookmarks(j)) Then

' If DataGrid bookmark matches selbookmark

Debug.Print SSDBGrid1.Columns(0).CellText(bm)

End If

Next j

Next i

End Sub


How can I manually 'ListAutoPosition' through an AddItem combo list using all entered characters?

Reference: DAT1226

This routine will position the combo list based on the current value entered.

Private Sub SSDBcombo1_Change()

Dim i%

Dim bm As Variant

If SSDBcombo1.Text <> "" Then

For i = 0 To SSDBcombo1.Rows - 1

SSDBcombo1.MoveFirst

bm = SSDBcombo1.GetBookmark(i)

If UCase(SSDBcombo1.Text) = UCase(Mid(SSDBcombo1.Columns(0).CellText(bm), 1,                                                           Len(SSDBcombo1.Text))) Then

SSDBcombo1.Bookmark = bm

Exit For

End If

Next i

End If

End Sub


How can I perform my own incremental search in an SSDBCombo?

Reference: DAT1187

Use the following procedure:

Private Sub SSDBCombo1_PositionList(ByVal Text As String)

Dim sctr As String

sctr = "name like'" & Text & "*" & "'"

Debug.Print sctr

Data1.Recordset.FindFirst sctr

SSDBCombo1.Bookmark = Data1.Recordset.Bookmark

End Sub


How can I place the Record number of the row in an Unbound Column of a bound SSDBGrid?

Reference: DAT1200

The following procedure adds an unbound row number column to a bound DataGrid:

Note	This code will only work if the RecordsetType property of the Data Control is set to "1-Dynaset".

(General)(declarations)

Dim flag As Boolean

Dim rs As Recordset

Private Sub Form_Activate()

flag = True

Set rs = Data1.Recordset.Clone()

End Sub

Private Sub SSDBGrid1_InitColumnProps()

SSDBGrid1.Columns.Add 0

End Sub

Private Sub SSDBGrid1_RowLoaded(ByVal Bookmark As Variant)

If flag = True Then

rs.Bookmark = Bookmark

SSDBGrid1.Columns(0).Text = rs.AbsolutePosition

End If

End Sub


How can I programmatically select a row?

Reference: DAT1246

Add it to the SelBookmarks collection.

To programmatically select a row you must add it to the SelBookmarks collection.  This collection holds all the selected rows bookmarks in the order they were selected.

The following selects the current row:

SSDBGrid1.SelBookmarks.Add SSDBGrid1.Bookmark


How can I put default search strings and selection criteria in the Find dialog without having to construct my own Find dialog?

Reference: DAT1222

Use the SendKeys statement to add your own criteria to the dialog.

Private Sub SSDBData1_ShowFindDialog()

DoEvents	' Give time to show the dialog

SendKeys "*"	' Send a default string - an asterisk

SendKeys "%L"	' Choose L for Less than

SendKeys "%D"	' Choose D to search down

SendKeys "{TAB}"	' Tab to field list box

SendKeys "{PGUP}"	' Go to the top of the list

SendKeys "{down 3}"	' Arrow down to the default field

End Sub


How can I search for a string in a column of the SSDBGrid?

Reference: DAT1161

Use the following procedure to search for a string in a grid column:

Place a SSDBGrid on a form (it doesn't matter which data mode the grid is in.) Place a text box on a form. Place a command button on the form, put the following code in the Click event:

Private Sub Command1_Click()

' This code is designed to search for

' the contents of the text box in column 1 of the DataGrid.

Dim bm as Variant

For i = 0 To SSDBGrid1.Rows - 1

SSDBGrid1.MoveFirst

bm = SSDBGrid1.GetBookmark(i)

If Text1.Text = SSDBGrid1.Columns(1).CellText(bm) Then

SSDBGrid1.Bookmark = SSDBGrid1.GetBookmark(i)

Exit For

End If

Next i

End Sub


How can I select a consecutive number of cells and copy their contents to the clipboard?

Reference: DAT1215

Use the following procedure to copy grid cells to the clipboard.

(General)(declarations)

Dim griddata As String

Private Sub Form_Load()

' Create styleset with backcolor of red

SSDBGrid1.StyleSets("color").BackColor = RGB(255, 55, 55)

End Sub

Private Sub SSDBGrid1_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim bm As Variant

' If right mouse click

If Button = 2 Then

' Apply the styleset "color" to the cell

SSDBGrid1.Columns(SSDBGrid1.ColContaining(X)).CellStyleSet ("color"), SSDBGrid1.RowContaining(Y)

' Get the row's bookmark

bm = SSDBGrid1.RowBookmark(SSDBGrid1.RowContaining(Y))

' Build string of cell's contents

griddata = griddata + SSDBGrid1.Columns(SSDBGrid1.ColContaining(X)).CellText(bm)

    ' Copy contents to ClipBoard

    Clipboard.SetText griddata

Else

' If left mouse click clear griddata and Clipboard and clear stylesets applied to DataGrid

SSDBGrid1.Refresh

griddata = ""

Clipboard.SetText griddata

End If

End Sub


How can I set focus to the next control in the tab order when I hit the tab key while the DataGrid has focus?

Reference: DAT1177

Use the following code to allow the user to tab to the next control from the last row of the grid:

Private Sub SSDBGrid1_KeyDown(KeyCode As Integer, Shift As Integer)

If KeyCode = 9 And SSDBGrid1.Row = SSDBGrid1.Rows Then

' The tab key has been pressed on the last row

For i = 0 To Form1.Controls.Count

' Go through the controls and find the next enabled control in the tab order

If Form1.Controls(i).TabIndex > SSDBGrid1.TabIndex And Form1.Controls(i).Enabled = True Then

Form1.Controls(i).SetFocus

Exit For

End If

Next i

End If

End Sub

This code moves to the next control when user tabs off last row in a grid with AllowAddNew set to False. It also moves to next control when user tabs off the Add row in a grid with AllowAddNew set to True.


How can I sort the Columns in an AddItem DataGrid since there is no "Ordered" property?

Reference: DAT1224

The following procedure will sort the contents of an AddItem grid using a memory array as a temporary holding place for the data. It also makes use of an efficient bubble sort algorithm.

This example requires a DataGrid in AddItem DataMode. (This can also be applied to the DataDropdown and the DataCombo in the AddItem DataMode):

Private Sub Command1_Click()

Call Order_An_Additem_Control(SSDBGrid1, SSDBGrid1.Rows, SSDBGrid1.Cols,0)

' This function will sort an additem data grid

' It passes the following parameters:

' "In_Control" = Name of the control being sorted

' "In_Number_Of_Rows" = Number of rows in the additem grid

' "In_Number_OF_Cols" = Number of columns in the additem grid. Leave 0 if there is only one column

' "Sort_Column" = Column to be sorted on

End Sub

Place this code in a Module:

Sub Order_An_Additem_Control(In_Control As Control, ByVal In_Number_Of_Rows As Integer, ByVal In_Number_Of_Cols As Integer, ByVal Sort_Column As Variant)

Dim L_MultiSingle As Integer	' If False then we are using Single Dimentional array, else Multi

Dim i As Integer	' Temporary variable

Dim J As Integer	' Temporary variable

Dim k As Integer	' Temporary variable

Dim l_Array_Holding_Items() As String	' Temporary array that will contain the info in the control

Dim Temp_Text As String

Dim Temp2 As String

' Turn off Redraw

In_Control.Redraw = False

Screen.MousePointer = 11

' Create the array

If (Sort_Column) < 0 Then Sort_Column = 0

If In_Number_Of_Cols > 1 Then	' Create a 2 dimentional array

ReDim l_Array_Holding_Items(In_Number_Of_Rows, In_Number_Of_Cols)

L_MultiSingle = True

Else

ReDim l_Array_Holding_Items(In_Number_Of_Rows)

L_MultiSingle = False

End If

' Populate the arrays

Select Case L_MultiSingle

Case True	' Multi

For i = 0 To In_Number_Of_Rows - 1

For J = 0 To In_Number_Of_Cols - 1

In_Control.Bookmark = In_Control.AddItemBookmark(i)	' Set the bookmark to a row

' Set the array to the contents of the row above

l_Array_Holding_Items(i, J) = In_Control.Columns(J).Text

Next J

DoEvents

Next i

Case False

For i = 0 To In_Number_Of_Rows - 1

In_Control.Bookmark = In_Control.AddItemBookmark(i)	' Sets the bookmark to a row

' Sets the array to the contents of the row above

l_Array_Holding_Items(i) = In_Control.Columns(0).Text

DoEvents

Next i

End Select

' Bubble sort the array

For i = 0 To In_Number_Of_Rows - 1

For J = In_Number_Of_Rows - 1 To i + 1 Step -1

If L_MultiSingle = False Then	' Single Array

DoEvents

If l_Array_Holding_Items(J) < l_Array_Holding_Items(J - 1) Then

 	Temp2 = l_Array_Holding_Items(J)

l_Array_Holding_Items(J) = l_Array_Holding_Items(J - 1)

l_Array_Holding_Items(J - 1) = Temp2

End If

Else ' Multiple

DoEvents

If l_Array_Holding_Items(J, Sort_Column) < l_Array_Holding_Items(J - 1, Sort_Column) Then

 	For k = 0 To In_Number_Of_Cols - 1

Temp2 = l_Array_Holding_Items(J, k)

l_Array_Holding_Items(J, k) = l_Array_Holding_Items(J - 1, k)

l_Array_Holding_Items(J - 1, k) = Temp2

Next k

End If

End If

Next J

Next i

' Repopulate the control with sorted items

In_Control.RemoveAll

Select Case L_MultiSingle

Case True	' Multi

For i = 0 To In_Number_Of_Rows - 1

Temp_Text = ""

For J = 0 To In_Number_Of_Cols - 1

If J = 0 Then

Temp_Text = In_Control.FieldDelimiter & l_Array_Holding_Items(i, J) & In_Control.FieldDelimiter

Else

Temp_Text = Temp_Text & In_Control.FieldSeparator & In_Control.FieldDelimiter & l_Array_Holding_Items(i, J) & In_Control.FieldDelimiter

End If

Next J

In_Control.AddItem Temp_Text

DoEvents

Next i

Case False

 	For i = 0 To In_Number_Of_Rows - 1

In_Control.AddItem l_Array_Holding_Items(i)

DoEvents

Next i

End Select

' Turn Redraw back on

In_Control.Redraw = True

Screen.MousePointer = 0

End Sub


How can I synchronize the horizonal scrolling of two DataGrids?

Reference: DAT1168

Use the following code in the ScrollAfter event of each DataGrid.

Private Sub SSDBGrid1_ScrollAfter()

SSDBGrid2.LeftCol = SSDBGrid1.LeftCol

End Sub

Private Sub SSDBGrid2_ScrollAfter()

SSDBGrid1.LeftCol = SSDBGrid2.LeftCol

End Sub

If you are using the SplitterBar then the above code will not work because SSDBGrid1.LeftCol will remain at "0".  Please refer to the following sample when using the SplitterBar:

Private Sub SSDBGrid1_ScrollAfter()

Dim i%, j%, k%

i = SSDBGrid1.SplitterPos

j = SSDBGrid1.ColPosition(SSDBGrid1.Columns(0).Position + i)

k = SSDBGrid2.ColPosition(SSDBGrid2.Columns(0).Position + i)

If j > k Then

SSDBGrid2.Scroll 1, 0

Else

 	If j > 0 And j <> k Then

SSDBGrid2.Scroll -1, 0

End If

End If

End Sub


How can I total a column in a bound DataGrid?

Reference: DAT1141

Use this procedure to place the total of a grid column in a text box.

Place a bound DataGrid, command button and text box on a form.   Use the following code:

Dim temp as Global Integer

Private Sub Command1_Click()

SSDBGrid1.MoveFirst

For i = 0 To SSDBGrid1.Rows - 1

bm = SSDBGrid1.GetBookmark(i)

temp = temp + SSDBGrid1.Columns(0).CellValue(bm)

Next

Text1.Text = temp

End Sub


How can I trap for messages through the DBEngine directly and display the Error Number and Error Description from DAO?

Reference: DAT1166

This code will give you an idea of how to handle errors from DBEngine.

Private Sub SSDBGrid1_AfterUpdate(RtnDispErrMsg As Integer)

If DBEngine.Errors.Count Then

Debug.Print DBEngine.Errors(0).Number

RtnDispErrMsg = False	'turn off DataGrid default message

MsgBox "Error:  " & DBEngine.Errors(0).Number & "    " & "Description:  " & _                       DBEngine.Errors(0).Description, 32

End If

End Sub


How can I update a DataGrid without moving off the row or if the Grid loses focus?

Reference: DAT1147

Use the following procedure to update the recordset without changing the current row.

In the SSDBGrid's LostFocus event put the following:

Private Sub SSDBGrid1_LostFocus()

If SSDBGrid1.RowChanged = True Then

SSDBGrid1.Update

End If

End Sub


How can I write all of the data that resides in an Additem DataGrid into a database?

Reference: DAT1151

The following procedure will store the entire contents of the AddItem grid in a database.

This code assumes that you have a Data Control on the Form that is attached to a table that contains the same number of fields as columns in the DataGrid.

Private Sub Command1_Click()

For i = 0 To SSDBGrid1.Rows - 1

Data1.Recordset.AddNew

For x = 0 To SSDBGrid1.Columns.Count - 1

Data1.Recordset(x) = SSDBGrid1.Columns(x).CellText(SSDBGrid1.AddItemBookmark(i))

Next x

Data1.Recordset.Update

Next i

End Sub


How do I copy the SSDBGrid contents to the clipboard?

Reference: DAT1196

The following code copies the contents of the grid to the clipboard:

Dim GridData as string

Dim bm as variant

GridData = ""

SSDBGrid1.movefirst

For i = 0 to SSDBGrid1.Rows - 1

bm = SSDBGrid1.GetBookmark(i)

For a = 0 to SSDBGrid1.cols - 1

griddata = griddata + SSDBGrid1.Columns(a).CellText(i) + ""

Next

Next

Clipboard.SetText GridData


How do I know what row I am on in a DataGrid?

Reference: DAT1243

Use bookmarks to determine the row number within a recordset, or the Row property to determine which of the visible rows you are on.

Data Widgets 2.0 refers to Bookmarks only, not row numbers.  This change was made due to the VB4 environment itself.  VB4 uses a Bookmark when referencing a record, not a row number. The Row property in Data Widgets 2.0 pertains to the visible row number only.  Every top row in the DataGrid will return row 0.

If you feel you do need to refer to a row number you can do the following:

If DataMode is Bound - the AbsolutePosition of the DataControl (RecordSetType of Dynaset only) will return the Row number:

lAbsoluteRow = Data1.RecordSet.AbsolutePosition

If DataMode is Unbound - if you were using a RecordSet, the same properties would apply as if it were bound.  You can use the same as above.

lAbsoluteRow = RecordSet.AbsolutePosition

If DataMode is AddItem - the Bookmark property in this DataMode returns an absolute row number.

lAddItemRow = SSDBGrid1.AddItemRowIndex(SSDBGrid1.Bookmark)

To get the number of the visible row, use the Row property:

iVisibleRow = SSDBGrid1.Row

To get the Column number the same would apply in all DataModes.

iColumn = SSDBGrid1.Col


How would I color a row based upon what has been entered into a cell?

Reference: DAT1144

To get this effect you must have a column somewhere in the DataGrid that holds a value that determines the color that row should be.

For example, this sample checks the value that is in column 0 and decides which color to apply to the row.

Private Sub Form_Load()

' Define the stylesets here.

SSDBGrid1.StyleSets("yesStyle").BackColor = RGB(255, 0, 0)

SSDBGrid1.StyleSets("noStyle").BackColor = RGB(0, 255, 0)

End Sub

Private Sub SSDBGrid1_RowLoaded(ByVal Bookmark As Variant)

Dim i As Integer

 	If SSDBGrid1.Columns(0).Text = "no" Then

 	For i = 0 To SSDBGrid1.Cols - 1

SSDBGrid1.Columns(i).CellStyleSet "noStyle"

Next i

ElseIf SSDBGrid1.Columns(0).Text = "yes" Then

For i = 0 To SSDBGrid1.Cols - 1

SSDBGrid1.Columns(i).CellStyleSet "yesStyle"

Next i

Else

' Do not apply any styleset.

For i = 0 To SSDBGrid1.Cols - 1

SSDBGrid1.Columns(i).CellStyleSet "

Next i

End If

End Sub

The reason the stylesets are applied in the RowLoaded event is that the DataGrid is a virtual control.  As rows are scrolled off the screen, the styleset applied to that row no longer exists.  As rows come into view, the RowLoaded event is fired.  By checking the value of Column 0 in the RowLoaded event, you can apply the styleset to that row as it comes into view.


How would I limit the number of characters in the text portion of the DataCombo?

Reference: DAT1130

Use the KeyPress event or the Windows API.

This code limits the edit portion of the DataCombo to five characters.

Private Sub SSDBCombo1_KeyPress(KeyAscii As Integer)

If Len(Trim(SSDBCombo1.Text)) >= 5 Then

KeyAscii = 0

Beep

End If

End Sub

Or you can get the same effect using the Windwos API (this sample is for 32 Bit).

' Place these lines in a module

Public Const EM_LIMITTEXT = &HC5

Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long

' Then place this code in the GotFocus event of the combo

' the third arguement is the maximum permitted length of the string

Dim x As Long

x = SendMessage(SSDBCombo1.HwndEdit, EM_LIMITTEXT, 5, 0)


How would I use one drop down to update several columns on a grid?

Reference: DAT1133

Use the RowColChange event, as outlined in the following procedure.

In this sample both columns 3 and 5 in the DataGrid are attached to the same DropDown control.  In the RowColChange event, the RecordSource of the data control bound to the DropDown is changed based on the Column in the DataGrid.

Private Sub SSDBGrid1_InitColumnProps()

SSDBGrid1.Columns(3).DropDownHwnd = SSDBDropDown1.hWnd

SSDBGrid1.Columns(5).DropDownHwnd = SSDBDropDown1.hWnd

End Sub

Private Sub SSDBGrid1_RowColChange(ByVal LastRow As Variant, ByVal LastCol As Integer)

If SSDBGrid1.Col = 3 And Data2.RecordSource <> "Publishers" Then

Data2.RecordSource = "Publishers"

Data2.Refresh

SSDBDropDown1.DataFieldList = "PubId"

ElseIf SSDBGrid1.Col = 5 And Data2.RecordSource <> "Authors" Then

Data2.RecordSource = "Authors"

Data2.Refresh

SSDBDropDown1.DataFieldList = "Au_ID"

End If

End Sub


If I am loading an Additem DataGrid with a dynaset, how can I synchronize the dynaset with the DataGrid?
If I am loading an Additem DataGrid with a dynaset, how can I synchronize the dynaset with the DataGrid?.

Reference: DAT1146

The procedure below illustrates how to synchronize the movement of the DataGrid with the record pointer.

Dim db as Database

Dim rs as Recordset

Private Sub Form_Load()

Dim i As Integer

Dim ct As Integer

Set db = OpenDatabase(App.Path & "\unbound.mdb")

Set rs = db.OpenRecordset("titles")

ct = rs.Fields.Count

SSDBGrid1.Columns.RemoveAll

For i = 0 To (ct - 1)

SSDBGrid1.Columns.Add i

SSDBGrid1.Columns(i).Visible = True

SSDBGrid1.Columns(i).Caption = rs.Fields(i).Name

Next i

End Sub

Private Sub Form_Activate()

Dim strData As String

rs.MoveFirst

Do While Not rs.EOF

For i = 0 To SSDBGrid1.Cols - 1

strData = strData & rs(i) & vbTab

Next i

SSDBGrid1.AddItem strData

strData = "

rs.MoveNext

Loop

End Sub

Private Sub SSDBGrid1_RowColChange(ByVal LastRow As Variant, ByVal LastCol As Integer)

rs.AbsolutePosition = SSDBGrid1.AddItemRowIndex(SSDBGrid1.Bookmark)

End Sub


Is there an automatic conversion utility available when converting from Data Widgets 1.0 to Data Widgets 2.0?

Reference: DAT1245

No.

There are significant differences between the Data Widgets 1.0 components and the Data Widgets 2.0 components.  Besides making full use of the latest OLE technology, we included many new features and enhancements that were requested by our customers.  An automatic conversion would not make use of the new properties and the object and collection architecture now supported in OLE technology.

For example, in Data Widgets version 1.0 you obtained a cell's value by using an element of an indexed property array - the ColText property of the DataGrid:

sColumnText = SSDataGrid1.ColText(n)

In Data Widgets version 2.0 the columns are now a part of a collection of Column objects.  Array properties and subscripts are no longer used. To obtain the same information, you would use the Text property of the Column object:

sColumnText = SSDBGrid1.Columns(n).Text

This is just a small sample of how the differences apply.  While we do realize the manual conversion can be a time consuming process, we have included a help file, DATW1TO2.HLP, that will help with the process.  This file lists all the Data Widgets 1.0 Properties, Events & Methods that were supported and explains how you can achieve the same functionality in Data Widgets version 2.0.


The Enhanced Data Control displays a message box when the Find function does not find anything.  How can I post my own message
The Enhanced Data Control displays a message box when the Find function does not find anything. How can I post my own message instead of the default message?

Reference: DAT1119

You must set the RtnDispErrMsg parameter of the FindResult event to False, then display your own message through code.

In the FindResult event place this code:

If CStr(vBookmark) = "" Then

  MsgBox "MyMessage"

  RtnDispErrMsg = False

End If


What is different in version 2.0?

Reference: DAT1047

These are the main differences between version 1.X and 2.X of the DataWidgets controls:

1.	They are no longer in the VBX format, they are now 16-bit and 32-bit ActiveX controls.

2.	The ActiveX format utilizes Microsoft’s OLE automation specifications.

3.	OurActiveX controls can now be used on a range of development environments, whereas in the past, the product was limited to environments that supported the VBX format.

4.	Version 2.0 of Data Widgets introduces the use of objects and collections.  Objects allow you to more easily manipulate the custom controls. For example, you can now directly set a property specific to an object (such as an individual column).


What is the best method of learning Data Widgets 2.0?

Reference: DAT1242

Part of the difficulty with learning Data Widgets 2.0 is due to the OLE features of Objects and Collections.  Once you understand this new technology, you will have no problem familiarizing yourself with Data Widgets 2.0.

The manual provides a Guided Tour section which is a basic, but thorough approach to familiarizing yourself with each component and their most common uses.  Once you understand the basics of how to use each control, you will better understand the properties and methods that are applicable to that component.

You may want to review each of the collections used in Data Widgets 2.0 to gain an understanding of the objects the collection comprises. You can then review the properties of each object.

For example, there is a Columns collection that is composed of Column objects.  This collection (like any collection) enables you to add objects to it, remove objects from it, or count how many objects it currently holds.  If you wish to refer to an individual Column object, you refer to it by its place in the collection. Thus, the first Column object added to the collection would be referred to as Columns(0).

If you wish to set certain attributes of Columns(0) you would then refer to the Column object and its properties.  You can set the Text, Caption, Style, BackColor, etc. properties of this Column.  Each would be referred by using the Column object and its place in the Columns collection:

SSDBGrid1.Columns(0).Text = "Hello World"

SSDBGrid1.Columns(0).Caption = "Name"

This does not mean that you will learn every property, method or event, but once you have a better understanding of how objects and collections work you will have an easier time looking for help on a specific property or method you would like to use.


When I bind the SSDBCombo’s DataSourceList to a DataControl and choose an item from the list, my other bound controls do not re
When I bind the SSDBCombo’s DataSourceList to a DataControl and choose an item from the list, my other bound controls do not reflect the same record.

Reference: DAT1249

You must manually reposition the Data control to achieve this effect.

When choosing an item from the list, you are moving the position of the SSDBCombo, but it is not repositioning the bound DataControl.  This is done to increase the speed of positioning of the SSDBCombo.

You can set the Data control’s bookmark equal to the SSDBCombo's bookmark and it will keep the other bound controls in sync with the SSDBCombo.

In the CloseUp event of the SSDBCombo put the following code:

Data1.RecordSet.Bookmark = SSDBCombo1.Bookmark


When I set the CellStyleSet to a particular cell then scroll the cell out of view, the CellStyleSet is no longer applied when t
When I set the CellStyleSet to a particular cell then scroll the cell out of view, the CellStyleSet is no longer applied when the cell scrolls back into view - how can I fix this?

Reference: DAT1121

Use the following procedure:

In order to get this effect, you need to a field in the Database associated with the Styleset.  Whenever this field contains a certain value, you should apply this styleset to the DataGrid in the RowLoaded event.

Place a DBGrid and Command Button on the form and add the following code:

(General)(declarations)

Dim temp as String

Private Sub Form_Load()

temp = ""

SSDBGrid1.StyleSets("color").BackColor = RGB(255, 55, 55)

End Sub

Private Sub Command1_Click()

SSDBGrid1.Columns(1).CellStyleSet ("color"), SSDBGrid1.Row

temp = SSDBGrid1.Columns(1).CellValue(SSDBGrid1.Bookmark)

End Sub

Private Sub SSDBGrid1_RowLoaded(ByVal Bookmark As Variant)

If SSDBGrid1.Columns(1).Text = temp Then

SSDBGrid1.Columns(1).CellStyleSet ("color")

Else

SSDBGrid1.Columns(1).CellStyleSet ""

End If

End Sub


When distributing my application that has a Data Widgets 2.0 control included, the Form will open, but will return an error "Ca
When distributing my application that has a Data Widgets 2.0 control included, the Form will open, but will return an error "Can’t Load Custom Control DLL".

Reference: DAT1244

You must correctly distribute and register all the DLLs needed by Data Widgets 2.0.

There are specific DLLs needed by Data Widgets in order to register the control and make use of the OLE technology.  These DLLs are not included when running the Setup Wizard in Visual Basic 4.

The DLLs required can be found on the Data Widgets 2.0 on-line help in the Technical Specifications section "Distributing Your Application".  The DLLs you need do vary depending on which environment you are supporting (16-bit and/or 32-bit applications) and are listed accordingly in this section.


When starting the Custom DataGrid editor, why do I get an error 31037 "Error loading from file"?

Reference: DAT1194

This error occurs when the shared system files TABCTL16.OCX and/or TABCLT32.OCX are not registered on your system.  This occurs occasionally when an application's uninstall program mishandles the un-registration and removal of its support files.

When the Data Widgets install program installs a shared system file, it first checks to make sure that the version it is about to install is newer than that which already exists on your system.  If it is newer, the install program proceeds to copy the file and then registers it.  If a newer version of the file already exists on your system, the file is not copied and is not registered (It is not registered because existing system file are assumed to be registered and used by other applications).

When TABCTL16.OCX or TABCLT32.OCX is no longer registered, but can still be found on your system - you will receive the error "31037 - Error Loading From File" when executing the Custom Property Pages.

As a measure to correct this problem, you can manually register the file(s) using REGSVR.EXE (for TABCTL16.OCX) and/or REGSVR32.EXE (for TABCTL32.OCX).


When using SQLPassThrough the DataCombo's ListAutoPosition and ListAutoValidate no longer work. Why?
When using SQLPassThrough, the DataCombo's ListAutoPosition and ListAutoValidate no longer work. Why?

Reference: DAT1176

Working with SQLPassThrough disables all search mechanisms.  This is a limitation inherent to Visual Basic 4.  Therefore, the DataCombo will no longer be able to perform the ListAutoPosition or the ListAutoValidate methods.


When using an unbound DataGrid, how can I display a value from my dynaset in a text box as I change rows?

Reference: DAT1135

Use the RowColChange event, as outlined in the following procedure.

In the RowColChange event you could do one of the following:

Private Sub SSDBGrid1_RowColChange(ByVal LastRow As Variant, ByVal LastCol As Integer)

' rs = Recordset

rs.Bookmark = SSDBGrid1.Bookmark

Text1.Text = rs("au_id")

End Sub

OR

Text1.Text = SSDBGrid1.Columns(2).Text


When using the SSDBCombo in Visual C++ 4.X, why will a charcter typed in the edit portion appear for a second then disappear?

Reference: DAT1276

This is caused by a bug in MFC.

There is a bug in MFC that causes problems if the ListAutoValidate property is set to True (the default value). This is caused by MFC requiring each keystrok to be  validated against the list. If the keystroke is not found, the string in the SSDBCombo is reset to it's previous value.

The workaround for this is to set the ListAutoPosition property to False, and if you are using a Remote Data Control, use the Validate event on the MSRDC to handle the validation of the data yourself.


Why can't Data Widgets controls be bound in Visual C++ 4.0?

Reference: DAT956

DataWidgets 2.0 requires Advanced Data Binding.

Visual C++ version 4.0 does not support Advanced Data Binding, therefore, you can not bind Data Widgets 2.0.  Visual C++ version 4.0 does support Simple Data Binding, which is sufficient for Calendar Widgets. However, Visual C++ 4.2  does support the Remote Data Control which allows the Data Widgets components to work in the Bound DataMode.


Why do I get an error when I bind the DataCombo's DataSource to a MSRDC control and perform a MSRDC1.ResultSet.Update?

Reference: DAT1205

This is a problem with the Microsoft Remote Data Control.  The problem can be reproduced with the Microsoft Masked Edit Control.


Why isn’t the SSDBCombo or SSDBDropdown dropping down?

Reference: DAT1248

The DataFieldList property is not set correctly.

Whether you are using the SSDBCombo or SSDBDropdown in Bound; Unbound; or AddItem DataMode you need to set the DataFieldList property.  This property tells the control which Column from the list you would like to appear in the Edit Portion when selected.  Without setting this property the control will not drop down.