activex_data_objects thread: Recordset starts at 2nd record after query...
Here we go again with this COM stuff. I have a function that creates a
recordset and binds it to a class. This works fine. The only problem is
that it starts at record ordinal 2 instead of 1 (Even after a ->MoveFirst
() call. This is telling me there is something underlying in the ADO
component that is screwed up. Either from a previous database access,
which I'm doing, or with this access function. Has anyone ever had this
sort of a problem? The project is due today and I am holding everything up
until I get this one. Isn't that always the case...
Anyway, here is the function that I'm using:
ADO_RETURN AppData::AccessTitlerDataset(Titler * pTitler, UINT index)
{
ADO_STATIC _RecordsetPtr pRstTitler =
NULL;
ADO_STATIC IADORecordBinding*
iADORecordBindingPtrTitler = NULL;
ADO_STATIC CRstBind_TitlerObject
cRstBind_TitlerObject;
// Initialize variables
_bstr_t bstrException = (L"");
_variant_t vtNumber;
// Append field string to SQL statement...
bstr_t bstrIndexString;
bstr_t bstrFilename = TITLER_RECORDSET;
bstr_t bstrTitlername = DATABASE_PATH;
bstr_t bstrFindString = TITLER_FIND_STRING;
hr = S_OK;
record_count = 0;
m_block_count = 0;
try
{
// Append field string to SQL statement...
bstrTitlername += bstrFilename;
bstrTitlername += (L".bin");
// Establish record search string
vtNumber.vt = VT_I2;
vtNumber = (SHORT)(index + 1);
bstrIndexString = vtNumber;
bstrFindString += bstrIndexString;
// Instantiate recordset interface object
SAFE_CALL(pRstTitler.CreateInstance(__uuidof(Recordset)));
// Use client-side cursor for this recordset object
pRstTitler->CursorLocation = adUseClient;
// Use cache size of 1024 (default is 1)
pRstTitler->CacheSize = CACHE_SIZE;
// Now hook up to target database
// Create the recordset object with SQL command to read data from
provider
SAFE_CALL(pRstTitler->Open( bstrTitlername, "Provider=MSPersist;",
adOpenForwardOnly, adLockOptimistic, adCmdFile));
// Get pointer to binding interface
SAFE_CALL(pRstTitler->QueryInterface(__uuidof(IADORecordBinding),
(LPVOID*)&iADORecordBindingPtrTitler));
// Bind recordset
SAFE_CALL(iADORecordBindingPtrTitler->BindToRecordset
(&cRstBind_TitlerObject));
// Row data is now in the bound class. Load them into
application...
// If binding error occurred, get out...
if(cRstBind_TitlerObject.GetStatus() == TRUE)
{
// Force cursor to beginning of recordset
SAFE_CALL(pRstTitler->MoveFirst());
// Determine if methods used in algorithms are supported
m_supports_previous = pRstTitler->Supports(adMovePrevious);
m_supports_find = pRstTitler->Supports(adFind);
if((m_supports_previous != FALSE) && (m_supports_find !=
FALSE))
{
do
{
// Row data is now in the bound class. Load them into
application...
// If binding error occurred, get out...
if(cRstBind_TitlerObject.GetStatus() == TRUE)
{
// Get next record with this index
SAFE_CALL(pRstTitler->Find
(bstrFindString,0,adSearchForward, vtMissing));
// Was record found?
if(!pRstTitler->EndOfFile && !pRstTitler->BOF)
{
// Format titler data...
m_block_count++;
pTitler->SetID(static_cast<WORD>
(cRstBind_TitlerObject.m_id));
pTitler->SetTitlerID(static_cast<WORD>
(cRstBind_TitlerObject.m_titler_id));
pTitler->SetTitlerPortNumber(static_cast<WORD>
(cRstBind_TitlerObject.m_port_number));
pTitler->SetTitlerSlotNumber(static_cast<WORD>
(cRstBind_TitlerObject.m_slot_number));
pTitler->SetFduID(static_cast<WORD>
(cRstBind_TitlerObject.m_fdu_id));
pTitler->SetMonitorID( static_cast<WORD>
(cRstBind_TitlerObject.m_monitor_id), static_cast<WORD>(m_block_count) );
pTitler->SetMonitorIndex( static_cast<WORD>
(cRstBind_TitlerObject.m_monitor_index));
}
else
{
// Finished without errors
break;
}
}
else
{
// Destroy recordset.
if( pRstTitler->State == adStateOpen)
pRstTitler->Close();
#ifdef _ADO_NO_RETURNS_
// Indicate corrupt record found
SetLastAdoError( ado_data_error );
#else
return FALSE; // Failed to complete database
parsing operation
#endif
}
// Bump step index
record_count++;
// Advance cursor for next FIND...
if(!pRstTitler->EndOfFile)
pRstTitler->MoveNext();
} while( !pRstTitler->EndOfFile && !pRstTitler->BOF );
}
else
{
// Provider algorithm support does not exist therefore
cannot proceed
// Destroy recordsets.
if( pRstTitler->State == adStateOpen)
pRstTitler->Close();
bstrException = "Provider algorithm support does not
exist!";
throw(bstrException);
}
}
else
{
// Destroy recordset.
if( pRstTitler->State == adStateOpen)
pRstTitler->Close();
#ifdef _ADO_NO_RETURNS_
// Indicate corrupt record found
SetLastAdoError( ado_bind_error );
#else
return FALSE; // Failed to complete database parsing
operation
#endif
}
// Destroy recordset.
if( pRstTitler->State == adStateOpen)
pRstTitler->Close();
// Finished without errors. MonitorToKeypad object initialized
correctly
#ifdef _ADO_NO_RETURNS_
// Clear error
SetLastAdoError( ado_null );
#else
return TRUE;
#endif
}
catch(_bstr_t& err) // ADO faults
{
TRACE( "*** _bstr_t Exception ***\n" );
AfxMessageBox( err );
#ifdef _ADO_NO_RETURNS_
// Clear error
SetLastAdoError( ado_data_error );
#else
return( FALSE );
#endif
}
catch(_com_error& e)
{
_bstr_t bstrErrorString = (L"");
_bstr_t bstrErrorSourceString = (L"");
_bstr_t bstrErrorMessageString = (L"");
_bstr_t bstrErrorMessage = (L"");
bstrErrorString = e.Error();
bstrErrorMessageString = e.Description();
bstrErrorSourceString = e.Source();
#ifdef _DEBUG
// Notify the user of errors if any.
_variant_t vtConnect = pRstTitler->GetActiveConnection();
// GetActiveConnection returns connect string if connection
// is not open, else returns Connection object.
switch(vtConnect.vt)
{
case VT_BSTR:
bstrErrorMessage += (L"Error: ");
bstrErrorMessage += bstrErrorString;
bstrErrorMessage += (L"\n\n");
bstrErrorMessage += (L"Source: ");
bstrErrorMessage += bstrErrorSourceString;
bstrErrorMessage += (L"\n\n");
bstrErrorMessage += (L"Description: ");
bstrErrorMessage += bstrErrorMessageString;
MessageBox(0,bstrErrorMessage,"Connection not
open...",MB_OK);
break;
case VT_DISPATCH:
PrintProviderError(vtConnect);
break;
default:
MessageBox(0,"Connection not open...","Unknown
Error",MB_OK);
break;
} // switch{}
// Destroy recordset.
if( pRstTitler->State == adStateOpen)
pRstTitler->Close();
#ifdef _ADO_NO_RETURNS_
// Errors detected
SetLastAdoError( ado_data_error );
#else
return FALSE; // Failed to complete database parsing
operation
#endif
#else
// Destroy recordset.
if( pRstTitler->State == adStateOpen)
pRstTitler->Close();
bstrException = (L"Error: ");
bstrException += bstrErrorString;
bstrException += (L"\n");
bstrException += (L"Descr: ");
bstrException += bstrErrorMessageString;
bstrException += (L"\n");
bstrException += (L"Source: ");
bstrException += bstrErrorSourceString;
bstrException += (L"\n");
throw(bstrException);
#endif
}
}