Retrieving field values from a CDaoRecordset in string format


I am trying to retrieve the values from a CDaoRecordset in string format regardless of what format it is in the Access database.

Can anyway suggest a way to do this.

I haven't had much luck using COleVariant's.

here is some code i have so far: --

//open database specified by user
CString MyMsAccessFileName;
CDaoDatabase m_DbConnection;
CDaoTableDef tabDef(&m_DbConnection);
CDaoTableDefInfo tabInfo;
int nTableCount = m_DbConnection.GetTableDefCount();

for (int i=0; i < 1; i++)      {

      CString tabName = tabInfo.m_strName;
      CDaoRecordset recordset(&m_DbConnection);
      CString strSelect = (_T("Select * from [") + tabName + _T("];"));

      int nRecordCount = recordset.GetRecordCount();
      int nFieldCount = tabDef.GetFieldCount();

      COleVariant oleVar;

      // for each record in the table
      for (int j=0; j < nRecordCount; j++) {

            for (int k=0; k < nFieldCount; k++) {

                  CString strData;
                  recordset.GetFieldValue(k, oleVar);
                  strData = (LPCSTR)oleVar.pbstrVal;            

            } //end for
      } //end for


} //end for

Who is Participating?
You can pull the record back from the recordset into COleVariant regardless of what type of variable is set in access db. That's the buity of using COlevars... Once you have the value in COleVariant variable, you must decide what type it was and pull it out of the COleVariant using the proper type. For example, if you had a string, you would use Var.pbVal;, if you had a long, you would use pb.lVal; or if you had a bool, youd use Var.boolVal and so on. The trick is determening what was in the field itself. You will use the TableDef object for that:
You will need a CDaoFieldInfo object. You will then call tabledef to get field info

TableDefObj.GetFieldInfo(FieldIndex_Or_Name, CDaoFieldInfoObject, AFX_DAO_PRIMARY_INFO);

then, once you get the fieldinfo object populated, see its type member to determine what type it was:

dbBoolean   Yes/No, same as TRUE/FALSE
dbByte   Byte
dbInteger   Short
dbLong   Long
dbCurrency   Currency; see MFC class COleCurrency
dbSingle   Single
dbDouble   Double
dbDate   Date/Time; see MFC class COleDateTime
dbText   Text; see MFC class CString
dbLongBinary   Long Binary (OLE Object); you might want to use MFC class CByteArray instead of class CLongBinary as CByteArray is richer and easier to use.
dbMemo   Memo; see MFC class CString
dbGUID   A Globally Unique Identifier/Universally Unique Identifier used with remote procedure calls. For more information, see                                                            the topic "Type Property" in DAO Help.
Note   Do not use string data types for binary data. This causes your data to pass through the Unicode/ANSI translation layer, resulting in increased overhead and possibly unexpected translation.

Check the m_type against these defines and then use the properties of COleVariant to get the proper field.
if (m_type == dbLong)
long lMuVal = COleVariantObj.lVal;

If you have any questions let me know.
Hope this helps.
ALso, be carefult when dealing with dates.
Use COleDateTime, not CTime.

COleDateTime date = recordset.GetFiledValue("DateFiled_Or_Something").date;

There is a mismatch between Date object return by GetFieldValue and COleDateTime on dates prior to 1899. If you're interested, see MSDN on Date object and it will tell you what the mismatch is (it is minor but it does exist)

Hope this helps.
Dev2003Author Commented:
its ok.....i found a way that works.....

the following code uses a CStringArray called fieldTypes which is created by getting the data type of each field for a specific table. It is populated by converting the 'short' value received from 'm_nType' of a CDaoFieldInfo object. Also note that this code is used in a for loop using int k to go through and reference each field in a table.

recordset.GetFieldValue(k, oleVar);
CString strData;

CString strFieldType = fieldTypes.GetAt(k);
if (strFieldType.Compare("Memo") == 0) {                  strData = (LPCSTR)oleVar.pbstrVal;
} else {
                oleVar.ChangeType( VT_BSTR );
      strData = oleVar.bstrVal;
What you have is perfectly fine. Assuming the code that populates the CStringArray is correct, then checking agains "Memo" or "Text" or "LONG" or so on should work. That is essentially what I tried to tell you. I just included additional info if you wished to get something more than just a string.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.