Results 1 to 7 of 7

Thread: DBGrid Refresh of Records

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Nov 2021
    Posts
    18

    DBGrid Refresh of Records

    I've been working on this darn problem for over a week can't figure it out. I am updating an older program from a DAO database to an Access 2000 ADO formatted database. I have a grid on a form (Microsoft Data Bound Grid Control 5.0 - SP-3: DBGrid32.OCX) which is attached to a data controller (Microsoft Data Bound List Control 5.0 - SP-3: DBList32.OCX). The controller is named datSub. The form has another data controller named datMain that controls the data on the main form.

    I was able to successfully attach the data controller to the Access 2000 database. I converted all the code over to the ADO syntax. Everything in the program works fine except posting new records to the grid. I have a routine that looks up data and ads records to the data table the the data controller is hooked to. After the new records are created I try to refresh the grid and no records appear. If I close the form and reopen it, the new records are there. Additionally, If I move off of the main record and then go back to it, the records appear. If have the following code in my datMain reposition event:

    'Restrict the line item information to a specific record number
    datSub.RecordSource = "select * from CycleItem " & "where CycleItem.[Cycle Number] = '" & txtCycleNum.Text & "'" & " _
    order by [Row Number], [Item Number], [Position] ASC"

    datSub.Refresh

    This is working perfectly. The routine that won't post data to the grid is as follows:

    Private Sub GetStockData()

    'Declare form variables
    Dim sql1 As String
    Dim sqlRow As String
    Dim dbname As String
    Dim db1 As ADODB.Connection
    Dim rs1 As ADODB.Recordset
    Dim rsRow As ADODB.Recordset
    Dim stItemNum as string
    Dim stSize As String
    Dim inPosition As Integer
    Dim cuValue As Currency

    'Select database to use
    dbname = "dcdata.mdb"
    Set db1 = New ADODB.Connection

    'Specify the connection string
    db1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source= " & dbname

    'Open Database
    db1.Open

    'Initiate the recordsets
    Set rsRow = New ADODB.Recordset
    Set rs1 = New ADODB.Recordset

    'Define recordset to be used for data

    sql1 = "select * from [Stock]"
    sql1 = sql1 & "where [Row Number] = '" & stRow & "'"
    sql1 = sql1 & " order by [Row Number], [Item Number] ASC"
    rs1.Open sql1, db1, adOpenKeyset, adLockPessimistic, adCmdText

    'Check for at least one record in database
    If rs1.RecordCount > 0 Then

    'Define recordset to be used for data
    sqlRow = "select * from [CycleItem]"

    'Open recordset

    rsRow.Open sqlRow, db1, adOpenKeyset, adLockPessimistic, adCmdText

    'Go to first record

    rs1.MoveFirst
    Do While Not rs1.EOF

    stItemNum = rs1![Item Number]
    stSize = rs1![Size]
    cuValue = rs1![Value]
    inPosition = rs1![Position]


    'Set the recordset to rsRow for all operations in the loop
    With rsRow
    .AddNew
    ![Cycle Number] = txtCycleNum.Text
    ![Row Number] = rs1![Row Number]
    ![Item Number] = rs1![Item Number]
    !Size = rs1![Size]
    !Position = inPosition
    !Description = rs1![Description]
    ![System Quantity] = rs1![Quantity]
    !Unit = rs1![Unit]
    !Value = cuValue
    ![First Count] = 0
    ![First Variance] = 0
    ![Second Count] = 0
    ![Second Variance] = 0
    .Update
    End With

    rs1.MoveNext
    Loop

    'Reset the data controller record source that is connected to the datagrid
    datSub.RecordSource = "select * from CycleItem " & "where CycleItem.[Cycle Number] = '" & _
    txtCycleNum.Text & "'" & " order by [Row Number], [Item Number], [Position] ASC"

    'Post new data to grid
    datSub.Refresh

    Else
    InUserResponse = MsgBox("No items were found.", vbOKOnly, "Record Check Check")

    End If

    'Reset recordsets and db

    Set rs1 = Nothing
    Set rsRow = Nothing
    db1.Close

    Exit Sub

    I have confirmed that the new records are actually in the database table right after the routine is run. I have have tried switching the the Microsoft ADO Data Control 6.0 with the Microsoft DataGrid Control 6.0, and have the exact same issue. The routine use to work perfectly with the Access 97 DAO database. I'm sure it is just something I am not familiar with on the ADO version. Any help would be greatly appreciated!!! Once I get this figured out, I have to convert a bunch of other programs. Thanks!!!

  2. #2
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: DBGrid Refresh of Records

    adOpenKeyset

    Uses a keyset cursor. Like a dynamic cursor, except that you can't see records that other users add, although records that other users delete are inaccessible from your Recordset. Data changes by other users are still visible.
    Each separate Connection is a "user" and you have at least 3 Connections: datSub, datMain, and db1 here.


    The ADO Data Control (not "controller") is only meant for very simple applications that use a single query. What you want here is a DataEnvironment, the ADODC's big brother that can support many queries using the same Connection.


    I doubt any of this has anything to do with DAO or the creaky old Jet 3.x ANSI database format. There is no such thing as "an ADO database" or "DAO database."

    I'm not sure why you have that loop either. That looks very strange, but is probably the sort of thing better done using an INSERT INTO... SELECT FROM query.


    As a quick fix you might try using a adOpenDynamic cursor instead though. I'm just not sure whether that is consistent with your other cursor settings or the bookmark requirements of the DataGrid Control.

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Nov 2021
    Posts
    18

    Re: DBGrid Refresh of Records

    dilettante,
    Thanks for the advise. Unfortunately, when I change the record set to adOpenDynamic, the routine doesn't work (returns a no data found message).

    The datMain data control is attached to my "CycleHeader" table. This table includes all the redundant information for the cycle count (i.e. date, row, total count value, etc.). My datSub data control is attached to my "CycleItem" table. This table includes all the individual item detail (i.e. part number, size, item count, etc.). CycleHeader and CycleItem are related by the Cycle Number field. The datSub control is attached to the data grid. Both controls RecordsetType property are set as a 1-Dynaset.

    When I change records in my main cycle count form, the reposition event redefines the record source property of the datSub control so it only shows the records in the data grid that are associated with the current Cycle Count on the main from. The reposition event is as follows:

    'Restrict the line item information to a specific record number

    datSub.RecordSource = "select * from CycleItem " & "where CycleItem.[Cycle Number] = _
    '" & txtCycleNum.Text & "'" & " order by [Location Number], [Item Number], [Position] ASC"
    datSub.Refresh

    This is all working perfectly in the present code. The only problem I am having is that whenever I add a new record to the cycle item table and then try to refresh the datSub data control, the new records do not show up in the grid.

    The only way I can get the new records to show up is to either run my save routine from my Save command button or reposition the datMain to another record then back to the original record or close the main form then reopen it.

    I've tried adding the save record code I use on the command button to the end of the GetStockData record routine, but that doesn't work either. It only seems to work when I "click" the save command button. My Save Record Code is as follows:

    If (datMain.Recordset.EditMode = dbEditAdd) Or (datMain.Recordset.EditMode = dbEditInProgress) Then
    datMain.Recordset.Update
    If datMain.Recordset.RecordCount > 1 Then
    datMain.Recordset.MoveLast
    Else
    datMain.Refresh
    End If

    Else
    'Force edit mode
    datMain.Recordset.Edit
    datMain.Recordset.Update

    End If

    I've even tried closing all the recordsets and database I use in the routine before resetting the datSub Recordsource. No matter what order I do things, the datSub recordcount = 0. When I checked the CycleItem table and the records are actually there. They just won't show up in the datSub recordcount until I either run my save routine from my Save command button or reposition the datMain to another record then back to the original record or close the main form then reopen it.

    This all worked perfect when my database was in an Access97 format. This all started when it was changed to an Access2000 format. The code I use to use to open a database and recordset in the Access97 format is as follows:

    'Select database to use
    dbDCData = "dcdata.mdb"
    Set db1 = DBEngine.Workspaces(0).OpenDatabase(dbDCData)

    Set rs1 = db1.OpenRecordset(sql1, dbOpenSnapshot) 'sql1 defines the records to use

    I initially tried to change the data controls to Access2000 format. The data controls worked with the Access2000 tables. However, whenever I tried to open a record via code, I received an "Unrecognized Database Format" error.

    On a side note, I was forced to update everything after a recent Microsoft Office 365 update crashed all of our Access97 programs (i.e. whenever you opened a form, the program would shut down). I have updated all the Access programs to Access365 and they are working fine. It's the VB6 programs I am having problems with now.

    I have to tackle much larger programs after I figure this out. Any help would be greatly appreciated. Thanks!!!!!!!!!!!!

  4. #4
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: DBGrid Refresh of Records

    At the time I was still using the MS AdoDC-control, I've never used its "RecordSource"-Property.

    Instead I've always set its RecordSet-Property, using a (globally defined) Helper-Function like:
    Set MyAdoDC.Recordset = GetRs("Select stuff From SomeTable")

    I highly recommend such a central Rs-retrieval-function, because it can make your live much easier with ADO.

    Here is the one I use (with slight variations, depending on whether I work in true disconnected mode, or not).

    Code:
    Public Function GetRs(ByVal SQL As String, ParamArray P()) As ADODB.Recordset
      Set GetRs = New ADODB.Recordset
      
      Dim Cmd As New ADODB.Command, i As Long
      Set Cmd.ActiveConnection = Cnn
          Cmd.CommandText = SQL
      For i = 0 To UBound(P)
        Select Case VarType(P(i))
          Case vbString: Cmd.Parameters.Append Cmd.CreateParameter(, adVarChar, , 4096, P(i))
          Case Else:     Cmd.Parameters.Append Cmd.CreateParameter(, VarType(P(i)), , , P(i))
        End Select
      Next
    
      GetRs.CursorLocation = adUseClient
      GetRs.Open Cmd, , adOpenStatic, adLockBatchOptimistic
      GetRs.Properties("Update Criteria") = adCriteriaKey 'allow only PKs, to locate Rows for Updates in the Where-Clause
    End Function
    With the above you can then work without any SQL-String-Concat-Fiddling like e.g.

    Const strSQL = "Select * From Tbl Where strFld=? And datFld Between ? And ?"
    Set Rs = GetRs(strSQL , Text1.Text, DatePicker1.Value, DatePicker2.Value

    ...meaning, that you can pass the Values in question "as they are" (in their native DataTypes) -
    just take care that they are in the same Order as the questionmarks in your SQL-def.


    Edit: As for "refreshing" an AdoDC-Control (e.g. after Updates or UpdateBatch-calls)...
    A simple AdoDC.Recordset.Requery should do...

    Olaf
    Last edited by Schmidt; Dec 12th, 2021 at 03:03 PM.

  5. #5
    PowerPoster dilettante's Avatar
    Join Date
    Feb 2006
    Posts
    24,487

    Re: DBGrid Refresh of Records

    If you have a lot of these old VB4/VB5 DAO programs that were never fully converted to VB6 and ADO it might not be worth the cost of trying at this late date.

    This was a common problem when Jet 4.0 came out. The band-aid that was offered with VB6 was a newer version of DAO that could make use of the Jet 4.0 database engine. New functionality was lost, and you were stuck with the limitations of the older Jet SQL syntax in order to maintain compatibility. But compatibility with the old VB4/VB5 code was the goal anyway.

    So you might get away with very few changes if you just use DAO 3.6 instead of the old DAO 3.5x libraries after upgrading the MDB file(s) to Jet 4.0 format.

    Just replacing the reference to DAO 3.5x with a reference to DAO 3.60 instead might get you 95% or more of the way to your goal.

  6. #6
    Angel of Code Niya's Avatar
    Join Date
    Nov 2011
    Posts
    9,017

    Re: DBGrid Refresh of Records

    Quote Originally Posted by Schmidt View Post
    With the above you can then work without any SQL-String-Concat-Fiddling like e.g.

    Const strSQL = "Select * From Tbl Where strFld=? And datFld Between ? And ?"
    Set Rs = GetRs(strSQL , Text1.Text, DatePicker1.Value, DatePicker2.Value

    ...meaning, that you can pass the Values in question "as they are" (in their native DataTypes) -
    just take care that they are in the same Order as the questionmarks in your SQL-def.
    There is actually a far better reason for this approach, it protects you from SQL injection attacks. It prevents malicious end-users from injecting something like Delete TblCustomers into your queries and nuking all your customer data from a TextBox.
    Treeview with NodeAdded/NodesRemoved events | BlinkLabel control | Calculate Permutations | Object Enums | ComboBox with centered items | .Net Internals article(not mine) | Wizard Control | Understanding Multi-Threading | Simple file compression | Demon Arena

    Copy/move files using Windows Shell | I'm not wanted

    C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter

    There's just no reason to use garbage like InputBox. - jmcilhinney

    The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Nov 2021
    Posts
    18

    Talking Re: DBGrid Refresh of Records

    dilettante,
    I changed the reference to DAO 3.60 and my original code worked perfectly with my Access2000/2003 databases (thank you, thank you, thank you). I had to position the DAO 3.60 reference near the top of my references list to ensure it took priority.

    I was using use Crystal Reports 5.0 (very old version) for my reporting. Unfortunately, I didn't have much luck trying to connect that version with the Access2000 tables. I ended up upgrading to Crystal Report 10 (had that version in my library) and converting all my reports to the new version. I added a reference to the Crystal Reports 10 reports ActiveX Report Viewer in my program. I then created a new form I named "ReportView" and added the report control to the form. I modified my print code in my other forms to send the data to the ReportView form as follows:

    ‘These Crystal Report Variables are in the Global Module
    Public Appl As New CRAXDRT.Application
    Public MyReport As CRAXDRT.Report

    Private Sub cmdPrint_Click()

    Dim stCycleNum As String
    Dim stMsg As String

    'Crystal Report Variables
    Dim strReportPath As String
    Dim strReportName As String

    'Set path to report file
    strReportPath = App.Path

    'Open the New report
    Set MyReport = New CRAXDRT.Report

    'Set record number variable so we can reposition the record after returning from the report viewing form (goes to last record by default if the data control is not repositioned).
    stCycleNum = txtCycleNum.Text

    'Define the report to be used
    strReportName = "\CycleCountSheet.rpt"
    Set MyReport = Appl.OpenReport("" & strReportPath & "" & strReportName)

    'Set selection formula to current record
    MyReport.RecordSelectionFormula = "{CycleHead.Cycle Number} = '" & stCycleNum & "'"

    'Open the form for viewing
    ReportView.Show vbModal

    'Reset the report definition
    Set MyReport = Nothing[/INDENT]

    [COLOR="#008080"]'Reposition record to current Cycle Number.
    datMain.Recordset.FindLast "[Cycle Number] = '" & stCycleNum & "'"


    For all my different reports, all I need to do is change the "strReportName" variable and my report record selection formula.

    For now, everything is working great. Thank you so much for your help!!!!!
    Last edited by MudManiac; Jan 5th, 2022 at 11:05 AM. Reason: Updated Reponse

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width