Microsoft KB Archive/248678: Difference between revisions

From BetaArchive Wiki
m (Text replacement - "<" to "<")
m (Text replacement - """ to """)
 
(One intermediate revision by the same user not shown)
Line 111: Line 111:
Private Sub Form_Activate()
Private Sub Form_Activate()
   Set rs = New ADODB.Recordset
   Set rs = New ADODB.Recordset
   rs.Fields.Append &quot;Col&quot;, adInteger
   rs.Fields.Append "Col", adInteger
   rs.Open
   rs.Open
   rs.AddNew &quot;Col&quot;, 1
   rs.AddNew "Col", 1
   rs.AddNew &quot;Col&quot;, 2
   rs.AddNew "Col", 2
   rs.AddNew &quot;Col&quot;, 3
   rs.AddNew "Col", 3
   rs.AddNew &quot;Col&quot;, 4
   rs.AddNew "Col", 4
   rs.AddNew &quot;Col&quot;, 5
   rs.AddNew "Col", 5
   Set rsClone = rs.Clone
   Set rsClone = rs.Clone
   rs.MoveLast
   rs.MoveLast
   Debug.Print &quot;Initial rs Record:&quot;, rs!Col
   Debug.Print "Initial rs Record:", rs!Col
   Debug.Print &quot;Initial rsClone Record:&quot;, rsClone!Col
   Debug.Print "Initial rsClone Record:", rsClone!Col
End Sub
End Sub


Line 128: Line 128:
   rs!Col = 1000
   rs!Col = 1000
   rs.Update
   rs.Update
   Debug.Print &quot;rs Record after edit:&quot;, rs!Col
   Debug.Print "rs Record after edit:", rs!Col
   Debug.Print &quot;rsClone Record after edit:&quot;, rsClone!Col
   Debug.Print "rsClone Record after edit:", rsClone!Col
   rsClone.Bookmark = rs.Bookmark
   rsClone.Bookmark = rs.Bookmark
   Debug.Print &quot;Clone sync'd with rs:&quot;, rsClone!Col
   Debug.Print "Clone sync'd with rs:", rsClone!Col
End Sub
End Sub


Private Sub rs_WillChangeField(ByVal cFields As Long, ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, _
Private Sub rs_WillChangeField(ByVal cFields As Long, ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, _
                               ByVal pRecordset As ADODB.Recordset)
                               ByVal pRecordset As ADODB.Recordset)
   Debug.Print &quot;rs WillChangeField:&quot;, pRecordset!Col
   Debug.Print "rs WillChangeField:", pRecordset!Col
End Sub
End Sub


Private Sub rsClone_WillChangeField(ByVal cFields As Long, ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, _
Private Sub rsClone_WillChangeField(ByVal cFields As Long, ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, _
                                     ByVal pRecordset As ADODB.Recordset)
                                     ByVal pRecordset As ADODB.Recordset)
   Debug.Print &quot;rsClone WillChangeField:&quot;, pRecordset!Col
   Debug.Print "rsClone WillChangeField:", pRecordset!Col
End Sub
End Sub


Line 156: Line 156:
<p>'''NOTE''': The clone record position does not change. If it explicitly set to the record that was edited, it does show the changes.</p></li>
<p>'''NOTE''': The clone record position does not change. If it explicitly set to the record that was edited, it does show the changes.</p></li>
<li><p>Uncomment the first line of the Command1_Click procedure and run the application again. This time, the clone is positioned on the same record as the main Recordset prior to the edit. The results are as follows:</p>
<li><p>Uncomment the first line of the Command1_Click procedure and run the application again. This time, the clone is positioned on the same record as the main Recordset prior to the edit. The results are as follows:</p>
<pre class="fixed_text">&gt;
<pre class="fixed_text">>
Initial rs Record:          5  
Initial rs Record:          5  
Initial rsClone Record:      1  <-- clone is repositioned after this point
Initial rsClone Record:      1  <-- clone is repositioned after this point
Line 167: Line 167:


'''NOTE''': The Fields argument of the cloned Recordset's event procedures also give the value of the fields in the cloned recordset's current position. Replacing the event '''Debug.Print''' statements with
'''NOTE''': The Fields argument of the cloned Recordset's event procedures also give the value of the fields in the cloned recordset's current position. Replacing the event '''Debug.Print''' statements with
<pre class="codesample">  Debug.Print &quot;rsClone WillChangeField:&quot;, Fields(0).Value
<pre class="codesample">  Debug.Print "rsClone WillChangeField:", Fields(0).Value
                 </pre>
                 </pre>
produces identical results as the existing code.
produces identical results as the existing code.

Latest revision as of 13:51, 21 July 2020

Article ID: 248678

Article Last Modified on 10/16/2002



APPLIES TO

  • Microsoft Visual Basic 5.0 Professional Edition
  • Microsoft Visual Basic 6.0 Professional Edition
  • Microsoft Visual Basic 5.0 Enterprise Edition
  • Microsoft Visual Basic 6.0 Enterprise Edition
  • Microsoft ActiveX Data Objects 2.1
  • Microsoft ActiveX Data Objects 2.1 Service Pack 1
  • Microsoft ActiveX Data Objects 2.1 Service Pack 2
  • Microsoft ActiveX Data Objects 2.5
  • Microsoft ActiveX Data Objects 2.6
  • Microsoft ActiveX Data Objects 2.7



This article was previously published under Q248678

SYMPTOMS

Manipulating an ADO Recordset raises events in its clones. However, the field value is not correct in the clone Recordset events.

CAUSE

Microsoft is currently researching this issue.

RESOLUTION

To resolve this issue take one of the following steps to work around the problem:

  • Base the events on the Recordset variable actually being manipulated.
  • Position the clone to the current recordset position.

    rsClone.BookMark = rs.BookMark
                        
  • If you do not need independent scrolling, you can set the two Recordsets equal to each other instead of one being a clone. For example, use:

    Set rs2 = rs1
                            

    instead of:

    Set rs2 = rs1.Clone
                        


STATUS

This behavior is by design.

MORE INFORMATION

A Clone Recordset is a pointer to the same data as another Recordset, except that a Clone Recordset has an independent Bookmark. Therefore, the current position in the main Recordset and in the Clone can be different. A MoveNext in one does not affect the position of the other.

When you edit a record in one Recordset, the other may or may not be positioned on it. Event procedures, such as WillChangeField or FieldChangeComplete merely pass a pointer to the Recordset and the Fields collection. The events do not reposition the record.

When data is changed in one Recordset, the events in the other provide a Recordset which does not point to the record being affected.

Steps to Reproduce Behavior

  1. In Visual Basic 5.0 or 6.0, open a new Standard EXE project.
  2. From the Project menu select the References menu to add a reference to Microsoft ActiveX Data Objects.
  3. Add a Command button (Command1) and the following code to the default form:

    Option Explicit
    
    Dim WithEvents rs As ADODB.Recordset
    Dim WithEvents rsClone As ADODB.Recordset
    
    Private Sub Form_Activate()
      Set rs = New ADODB.Recordset
      rs.Fields.Append "Col", adInteger
      rs.Open
      rs.AddNew "Col", 1
      rs.AddNew "Col", 2
      rs.AddNew "Col", 3
      rs.AddNew "Col", 4
      rs.AddNew "Col", 5
      Set rsClone = rs.Clone
      rs.MoveLast
      Debug.Print "Initial rs Record:", rs!Col
      Debug.Print "Initial rsClone Record:", rsClone!Col
    End Sub
    
    Private Sub Command1_Click()
      ' rsClone.Bookmark = rs.Bookmark
      rs!Col = 1000
      rs.Update
      Debug.Print "rs Record after edit:", rs!Col
      Debug.Print "rsClone Record after edit:", rsClone!Col
      rsClone.Bookmark = rs.Bookmark
      Debug.Print "Clone sync'd with rs:", rsClone!Col
    End Sub
    
    Private Sub rs_WillChangeField(ByVal cFields As Long, ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, _
                                   ByVal pRecordset As ADODB.Recordset)
      Debug.Print "rs WillChangeField:", pRecordset!Col
    End Sub
    
    Private Sub rsClone_WillChangeField(ByVal cFields As Long, ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum, _
                                        ByVal pRecordset As ADODB.Recordset)
      Debug.Print "rsClone WillChangeField:", pRecordset!Col
    End Sub
    
                        
  4. Run the application and click the command button. The output should appear as follows:

    Initial rs Record:           5 
    Initial rsClone Record:      1 
    rs WillChangeField:          5 
    rsClone WillChangeField:     1 
    rs Record after edit:        1000 
    rsClone Record after edit:   1 
    Clone sync'd with rs:        1000 
                            

    NOTE: The clone record position does not change. If it explicitly set to the record that was edited, it does show the changes.

  5. Uncomment the first line of the Command1_Click procedure and run the application again. This time, the clone is positioned on the same record as the main Recordset prior to the edit. The results are as follows:

    >
    Initial rs Record:           5 
    Initial rsClone Record:      1   <-- clone is repositioned after this point
    rs WillChangeField:          5 
    rsClone WillChangeField:     5 
    rs Record after edit:        1000 
    rsClone Record after edit:   1000 
    Clone sync'd with rs:        1000 
                        

NOTE: The Fields argument of the cloned Recordset's event procedures also give the value of the fields in the cloned recordset's current position. Replacing the event Debug.Print statements with

  Debug.Print "rsClone WillChangeField:", Fields(0).Value
                

produces identical results as the existing code.

Keywords: kbbug kbnofix kbdatabase KB248678