Microsoft KB Archive/288772

= BUG: Error Message Received When You Use the DTPicker to Update Table =

Article ID: 288772

Article Last Modified on 11/5/2003

-

APPLIES TO


 * Microsoft Data Access Components 2.5
 * Microsoft Data Access Components 2.5 Service Pack 1
 * Microsoft Data Access Components 2.6
 * Microsoft Data Access Components 2.7

-



This article was previously published under Q288772



SYMPTOMS
When you use the DTPicker to update a table, you may receive the following error message if an intrinsic control is also updating the table:

Consumer's event handler called a non-reentrant method in the provider.

If just the DTPicker is doing an update, no error is returned, but the table is not updated.



CAUSE
OCXs are not supplying pre-Update notifications, such as intrinsic controls.



RESOLUTION
Issue a recordset.move 0 or use a databinding collection.



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.



MORE INFORMATION
OCX controls (DTPicker) in general wait for a pre-Update notification before they issue an IRowset::SetData for the Provider to update the data. This is not supported in providers because it would cause re-reentrancy problems during pending updates. As a result, it waits for an event that does not occur when using server-side cursors or it issues a re-entrancy error message.

The client-side cursors allow an IRowset::SetData within the client's update call; as a result, it works against client-side cursors. Additionally, because all providers support pre-Move notifications, an operation such as Move(0) also fires the event that causes the IRowset::SetData to happen when using server-side cursors.

Steps to Reproduce Behavior
 Create a Standard EXE project in Visual Basic. Form1 is created by default. On the Project menu, click Components, and then register the following controls with the project:Microsoft Windows Common Controls-2 6.0.

 On Project References, select Microsoft ActiveX Data Objects 2.6 Library. Be sure to deselect Microsoft ActiveX Data Objects 2.5 if it is selected. On the default form (Form1), add the following controls:  Frame1 with two options buttons inside:

Name=Option1

caption= Access

Name=Option2

caption= SQL Server

</li> Two command buttons:

Name=cmdopen

caption = Open Database

Name= cmdupdate

Caption = Update

</li> One text box:

Name= text1

text=

</li> One DTPicker:

Name= DTPicker1

</li></ul> </li>  Add the following code to the form.

Note You must change User ID =<UID> and password = to the correct values before you run this code. Make sure that <UID> has the appropriate permissions to perform this operation on the database. Option Explicit ' For SQL Server, change the Data source, ' Initial catalogue, user name and password here Const SQLConnect As String = &quot;Data Source = margerysp2w2k; Initial Catalog=northwind;user id= ;password= ;&quot; 'For Access, change the path to correctly point to the Northwind.MDB Const AccessConnect As String = &quot;Data Source=E:\Office2000sr1\Office\Samples\northwind.MDB&quot; Const TableName As String = &quot;orders&quot; 'Providers Const AccessProvider As String = &quot;Microsoft.Jet.OLEDB.4.0&quot; Const SQLProvider As String = &quot;SQLOLEDB&quot; Dim Cn As ADODB.Connection Dim RS As ADODB.Recordset

Private Sub cmdopen_Click Set Cn = New ADODB.Connection 'Set up connection depending on option chosen If Option1.Value Then  ' Access is selected by default With Cn .CursorLocation = adUseServer .ConnectionString = AccessConnect .Provider = AccessProvider .Open End With 'Access Else With Cn .ConnectionString = SQLConnect .Provider = SQLProvider .Open End With 'SQL Server End If '  Open the record set, and bind Set RS = New ADODB.Recordset RS.Open &quot;Select * from &quot; & TableName, Cn, adOpenKeyset, adLockOptimistic, adCmdText '  Now bind With Text1 .DataField = &quot;shipcountry&quot; Set .DataSource = RS End With With DTPicker1 .DataField = &quot;ShippedDate&quot; Set .DataSource = RS End With 'datepicker 'Bind using the BindingCollection. 'Set bc = New BindingCollection 'Set bc.DataSource = RS 'bc.Add DTPicker1, &quot;value&quot;, &quot;ShippedDate&quot; 'bc.Add Text1, &quot;Text&quot;, &quot;ShippedCountry&quot; End Sub

'Bind using the BindingCollection. 'Set bc = New BindingCollection 'Set bc.DataSource = RS 'bc.Add DTPicker1, &quot;value&quot;, &quot;ShippedDate&quot; 'bc.Add Text1, &quot;Text&quot;, &quot;ShippedCountry&quot;

Private Sub cmdupdate_Click

With RS  .Update .Close End With 'RS Cn.Close End Sub

Private Sub Form_Load Option1.Value = True End Sub </li> Modify the General Declarations sections as indicated in the code comments.</li> Test the preceding code by running it with either Microsoft SQL Server or Microsoft Access. Click Open Database.</li> Change the Country name only, and then click Update. Note that the Country name is updated.</li> Change just the date in the DTPicker, and then click Update. Note that the datebase is updated and closed. Click Open Database again, and note that the date is not changed.</li> Change both the Country and the date, click Update, and note that the error message cited in the &quot;Symptoms&quot; section is displayed.</li>  Uncomment the followng lines: Set bc = New BindingCollection Set bc.DataSource = RS bc.Add DTPicker1, &quot;value&quot;, &quot;ShippedDate&quot; bc.Add Text1, &quot;Text&quot;, &quot;ShippedCountry&quot; Comment out the following lines: 'With Text1 ' .DataField = &quot;ShippedCountry&quot; ' Set .DataSource = RS 'End With 'With DTPicker1 '  .DataField = &quot;ShippedDate&quot; '  Set .DataSource = RS 'End With 'datepicker and repeat step 9. Both fields should be updated successfully. </li></ol>

<div class="references_section">