ADO operation

xiaoxiao2021-03-06  43

/Ado.cpp/////////mailto: cantollini@hotmail.com//// Date: 11/19/2002 //// Version 2.09 / /

#include "stdafx.h" #include "ado.h"

#define chunksize 100

#ifdef _debug # define new debug_new # undef this_filestatic char this_file [] = __file __; # ENDIF / / / / / / / CADATABASE CLASS ///

DWord Cadodatabase :: getRecordcount (_RecordSetPtr M_PRS) {dword nuMrows = 0; nuMrows = m_PRS-> getRecordcount ();

IF (nuMrows == -1) {if (m_PRS-> endoffile! = variant_true) m_prs-> movefirst ();

While (m_prs-> endoffile! = variant_true) {NumRows ; m_PRS-> MoveNext ();} if (nuMrows> 0) m_PRS-> MoveFirst ();} return numrow

Bool Cadodatabase :: Open (LPCTSTR LPSTRCONNECTION, LPCTSTSTR LPSTRUSERID, LPCTSTR LPSTRPASSWORD) {HRESULT HR = S_OK;

IF (isopen ()) close ();

IF (strcmp (lpstrConnection, _t ("))! = 0) m_strconnection = lpstrConnection;

Assert (! M_strconnection.isempty ());

try {if (m_nConnectionTimeout = 0!) m_pConnection-> PutConnectionTimeout (m_nConnectionTimeout); hr = m_pConnection-> Open (_bstr_t (m_strConnection), _bstr_t (lpstrUserID), _bstr_t (lpstrPassword), NULL); return hr == S_OK;} catch (_COM_ERROR & E) {DUMP_COM_ERROR (E); return false;}}

void CADODatabase :: dump_com_error (_com_error & e) {CString ErrorStr; _bstr_t bstrSource (e.Source ()); _bstr_t bstrDescription (e.Description ()); ErrorStr.Format ( "CADODataBase Error / n / tCode =% 08lx / n / Tcode Meaning =% S / N / Tsource =% S / N / TDESCRIPTION =% S / N ", E.Error (), E.ErrorMessage (), (lpcstr) bstrsource, (lpcstr) bstrdescription; m_strerrorDescription = (LPCSTR ) bstrDescription; m_strLastError = _T ( "Connection String =" GetConnectionString () '/ n' ErrorStr); m_dwLastError = e.Error (); #ifdef _DEBUG AfxMessageBox (ErrorStr, MB_OK | MB_ICONERROR); #endif} BOOL CADODatabase :: isopen () {if (m_pconnection) return m_pconnection-> getState ()! = Adstateclosed; returnaf

Void Cadodatabase :: Close () {if (isopen ()) m_pconnection-> close ();

/////// Cadorecordset Class ////

CADORecordset :: CADORecordset () {m_pRecordset = NULL; m_pCmd = NULL; m_strQuery = _T ( ""); m_strLastError = _T ( ""); m_dwLastError = 0; m_pRecBinding = NULL; m_pRecordset.CreateInstance (__ uuidof (Recordset)); m_pCmd .CreateInstance (__ uuidof (command)); m_neditstatus = cadorecordset :: dbeditnone; m_nsearchdirection = cadorecordset :: searchforward;

CADORecordset :: CADORecordset (CADODatabase * pAdoDatabase) {m_pRecordset = NULL; m_pCmd = NULL; m_strQuery = _T ( ""); m_strLastError = _T ( ""); m_dwLastError = 0; m_pRecBinding = NULL; m_pRecordset.CreateInstance (__ uuidof (Recordset) ); M_pcmd.createInstance (__ uuidof (command)); m_neditstatus = cadorecordset :: dbEditnone; m_nsearchdirection = cadorecordset :: searchForward;

m_pConnection = Padodatabase-> getActiveConnection ();

BOOL CADORecordset :: Open (_ConnectionPtr mpdb, LPCTSTR lpstrExec, int nOption) {Close (); if (strcmp (lpstrExec, _T ( "")) = 0!) M_strQuery = lpstrExec; ASSERT (m_strQuery.IsEmpty ()!);

IF (m_pconnection == null) m_pConnection = MPDB;

M_StrQuery.trimleft (); BOOL BISSELECT = M_STRQUERY.MID (0, Strlen ("SELECT")). Comparenocase ("SELECT") == 0 && NOPTION == OpenUnknown;

try {m_pRecordset-> CursorType = adOpenStatic; m_pRecordset-> CursorLocation = adUseClient; if (bIsSelect || nOption == openQuery || nOption == openUnknown) m_pRecordset-> Open ((LPCSTR) m_strQuery, _variant_t ((IDispatch *) mpdb, TRUE), adOpenStatic, adLockOptimistic, adCmdUnknown); else if (nOption == openTable) m_pRecordset-> Open ((LPCSTR) m_strQuery, _variant_t ((IDispatch *) mpdb, TRUE), adOpenKeyset, adLockOptimistic, adCmdTable); else if (nOption == openStoredProc) {m_pCmd-> ActiveConnection = mpdb; m_pCmd-> CommandText = _bstr_t (m_strQuery); m_pCmd-> CommandType = adCmdStoredProc; m_pConnection-> CursorLocation = adUseClient; m_pRecordset = m_pCmd-> Execute (NULL, NULL, adCmdText); } Else {trace ("Unknown Parameter.% D", NOPTION); RETURN FALSE;}} catch (_COM_ERROR & E) {dump_com_error (e); returnaf false;}

Return M_PRecordset! = null;}

BOOL CADORecordset :: Open (LPCTSTR lpstrExec, int nOption) {ASSERT (m_pConnection = NULL!); ASSERT (! M_pConnection-> GetState () = adStateClosed); return Open (m_pConnection, lpstrExec, nOption);}

Bool Cadorecordset :: OpenSchema (int nschema, lpctstr scheid) {try {_variant_t vtschemaid = vtmissing;

if (! strlen (SchemaID) = 0) vtSchemaID = SchemaID; m_pRecordset = m_pConnection-> OpenSchema ((enum SchemaEnum) nSchema, vtMissing, vtSchemaID); return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE; }}} BOOL CADORECORDSET :: REQUERY () {if (iSopen ()) {{// If AdexecuteRecord is unfained, import Msado15.dll m_precordset-> Requery (adexecuteRecord) under Win2000;} catch (_COM_ERROR & E) { DUMP_COM_ERROR (E); Return False;}} Return True;

BOOL CADORecordset :: GetFieldValue (LPCTSTR lpFieldName, double & dbValue) {double val = (double) NULL; _variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; switch (vtFld.vt) {case Vt_r4: val = vtfld.fltval; break; case vt_r8: val = vtfld.dblval; break; case vt_decimal: // CORRECTED by JOS? Carlos Mart Han EZ GAL 醤 VAL = vtfld.decval.lo32; val * = (vtfld. Decval.sign == 128)? -1: 1; Val / = POW (10, vtfld.decval.scale); break; case vt_ui1: val = vtfld.ival; break; case vt_i2: case vt_i4: val = vtfld. Lval; breaf; case; value: value; default: val = vtfld.dbl;} dbvalue = val;} DBVALUE = Val;} dbval} catch (_ERROR & E)} DBVALUE = Val;} DBVALUE = VAL; RETURN TRUE; DUMP_COM_ERROR (E); Return False;}}

Bool Cadorecordset :: GetfieldValue (Int Nindex, Double & Dbvalue) {Double Val = (Double) NULL; _VARIANT_T VTFLD; _VARIANT_T VTINDEX;

vtIndex.vt = vt_i2; vtindex.ival = nindex; try {vtfld = m_precordset-> fields-> getItem (vtIndex) -> value; switch (vtfld.vt) {case vt_r4: val = vtfld.fltval; break; case vt_r8 : Val = vtfld.dblval; breaf; case vt_decimal: // CORRECTED BY JOS? Carlos Mart Han EZ GAL = vtfld.decval.lo32; val * = (vtfld.decval.sign == 128)? -1: 1 Val / = POW (10, vtfld.decval.scale); Break; case vt_ui1: val = vtfld.ival; break; case vt_i2: case vt_i4: val = vtfld.lval; break; case vt_int: val = vtfld.intVal Break; case vt_null: case vt_empty: val = 0; break; default: val = 0;} dbvalue = val; return true;} catch (_Error & e) {dump_com_error (e); return false;}} bool cadorecordset :: GetFieldValue (LPCTSTR lpFieldName, long & lValue) {long val = (long) NULL; _variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value;! if (vtFld.vt = VT_NULL && vtFld.vt ! = Vt_empty) Val = vtfld.l;} catch (_COM_ERROR & e) {dump_com_error (e); return false;}}

Bool Cadorecordset :: GetfieldValue (INT NINDEX, Long & LVALUE) {long val = (long) null; _variant_t vtfld; _variant_t vtindex; vtIndex.ival = vt_i2; vtIndex.ival = NINDEX;

Try {vtfld = m_precordset-> fields-> getItem (vtItem (vtFld.vt! = vt_null && vtfld.vt! = vt_empty) val = vtfld.lval; lvalue = val; return;} catch _COM_ERROR & E) {dump_com_error (e); return false;}}

BOOL CADORecordset :: GetFieldValue (LPCTSTR lpFieldName, unsigned long & ulValue) {long val = (long) NULL; _variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; if (vtFld.vt =! ! VT_NULL && vtFld.vt = VT_EMPTY) val = vtFld.ulVal; ulValue = val; return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE;}} BOOL CADORecordset :: GetFieldValue (int nIndex, unsigned long & ULVALUE) {long value) null; _variant_t vtfld; _variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = nindex;

Try {vtfld = m_precordset-> fields-> getItem (vtItem (vtfld.vt! = vt_null && vtfld.vt! = vt_empty) Val = vtfld.ulval; ulvalue = val; return;} catch _COM_ERROR & E) {dump_com_error (e); return false;}}

BOOL CADORecordset :: GetFieldValue (LPCTSTR lpFieldName, int & nValue) {int val = NULL; _variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; switch (vtFld.vt) {case VT_BOOL: val = vtfld.boolval; break; case vt_i2: case vt_ui1: val = vtfld.ival; break; case vt_int: val = vTfld.intVal; break; case vt_null: case vt_empty: val = 0; Break; default: val = vtfld. } nvalue = val; return true;} catch (_COM_ERROR & E) {dump_com_error (e); return false;}}

Bool Cadorecordset :: GetfieldValue (Int Nindex, Int & nvalue) {INT VAL = (int) null; _variant_t vtfld; _variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = nindex;

Try {vtfld = m_precordset-> fields-> getItem (vtItem (vtItem) -> value; switch (vtfld.vt) {copy vt_bool: val = vtfld.boolval; break; case vt_i2: case vt_ui1: val = vtfld.ival; break; Case vt_int: val = vtfld.intval; break; case vt_null: case vt_empty: val = 0; break; default: val = vtfld.ival;} nvalue = val; return true;} catch (_ERROR & E) {dump_com_error (e) {dump_com_error (e) Return False;}}} Bool Cadorecordset :: GetfieldValue (LPCTSTSTR LPFIELDNAME, CSTRING & STRILDNAME, CSTRING & STRILE, CSTRING STRDATEFORMAT) {CString Str = _t ("); _variant_t vtfld;

Try {vtfld = m_precordset-> fields-> getItem (lpfieldname) -> value; switch (vtfld.vt) {case vt_r4: str = dbltostr (vtfld.fltval); break; case vt_r8: str = dbltostr (vtfld.dblval) Break; case vt_bstr: str = vtfld.bstrval; break; case vt_i2: case vt_ui1: str = INTOSTR (VTFLD.IVAL); Break; case vt_int: str = INTOSTR (vtfld.intval); Break; case vt_i4: str = Longtostr (vtfld.lval); break; case vt_ui4: str = ulongtostr (vtfld.ulval); break; case vt_decimal: {// CORRECTED BY JOS? Carlos Mart Han EZ GAL 醤 Double Val = vtfld.decval.lo32; val * = (vtfld.decval.sign == 128)? -1: 1; Val / = POW (10, vtfld.decval.scale); str = dbltostr (val);} Break; case vt_date: {COLEDATETIME DT (VTFLD) ;

IF (strdateformat.isempty ()) strdateformat = _t ("% Y-% M-% D% h:% m:% s"); str = dt.format (strdateformat);} Break; case vt_empty: Case VT_NULL: Str.empty (); buk; case vt_bool: str = vtfld.boolval == variant_true? 't': 'f'; break; default: str.empty (); returnif value;} strcalue = str;} strue;} catch (_com_error & e) {dump_com_error (e); return FALSE;}} BOOL CADORecordset :: GetFieldValue (int nIndex, CString & strValue, CString strDateFormat) {CString str = _T ( ""); _variant_t vtFld; _variant_t vtIndex;

VtIndex.vt = vt_i2; vtIndex.ival = nindex; try {vtfld = m_precordset-> fields-> GetItem (vtIndex) -> value; switch (vtfld.vt) {copy vt_r4: str = dbltostr (vtfld.fltval); BREAK Case vt_r8: str = dbltostr (vtfld.dblval); break; case vt_bstr: str = vtfld.bstr: Break; case vt_i2: case vt_ui1: str = INTOSTR (vtfld.ival); Break; case vt_int: str = INTOSTR vtfld.intval); Break; case vt_i4: str = longtostr (vtfld.lval); break; case vt_ui4: str = ulongtostr (vtfld.ulval); break; case vt_decimal: {// CORRECTED BY JOS? Carlos Mart Han EZ Gal醤 Double Val = vtfld.decval.lo32; val * = (vtfld.decval.sign == 128)? -1: 1; Val / = Pow (10, vtfld.decval.scale); str = dbltostr (VAL); } Break; Case vt_date: {COLEDATETIME DT (VTFLD); if (strdateformat.isempty ()) strdateformat = _t ("% Y-% M-% D% H:% M:% S"); str = dt.format (strdateformat);} Break; case vt_bool: str = vtfld.boolval == variant_true? 't': 'f'; break; case vt_empty: Case VT _Null: str.empty (); break; default: str.empty (); return false;} strs false;} strue;} catch (_COM_ERROR & E) {dump_com_error (e); returnaf false;}}

BOOL CADORecordset :: GetFieldValue (LPCTSTR lpFieldName, COleDateTime & time) {_variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; switch (vtFld.vt) {case VT_DATE: {COleDateTime dt (vtFld) ; time = dt;} break; case VT_EMPTY: case VT_NULL: time.SetStatus (COleDateTime :: null); break; default: return FALSE;} return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE; }} BOOL CADORecordset :: GetFieldValue (int nIndex, COleDateTime & time) {_variant_t vtFld; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; try {vtFld = m_pRecordset-> Fields-> GetItem (vtIndex) -> Value ; switch (vtFld.vt) {case VT_DATE: {COleDateTime dt (vtFld); time = dt;} break; case VT_EMPTY: case VT_NULL: time.SetStatus (COleDateTime :: null); break; default: return FALSE;} return True;} catch (_COM_ERROR & E) {dump_com_error (e); return false;}}

BOOL CADORecordset :: GetFieldValue (LPCTSTR lpFieldName, bool & bValue) {_variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; switch (vtFld.vt) {case VT_BOOL: bValue = vtFld.boolVal = = VARIANT_TRUE? TRUE: FALSE; BREAK; CASE VT_EMPTY: CASE VT_NULL: BVALUE = false; break; default: returnaf false;} Return True;} catch (_Error & e) {dump_com_error (e); returnaf false;}}}

BOOL CADORecordset :: GetFieldValue (int nIndex, bool & bValue) {_variant_t vtFld; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; try {vtFld = m_pRecordset-> Fields-> GetItem (vtIndex) -> Value; switch (vtFld.vt) {case VT_BOOL: bValue = vtFld.boolVal == VARIANT_TRUE true: false; break; case VT_EMPTY:? case VT_NULL: bValue = false; break; default: return FALSE;} return TRUE;} catch (_com_error & e ) {dump_com_error (e); return FALSE;}} BOOL CADORecordset :: GetFieldValue (LPCTSTR lpFieldName, COleCurrency & cyValue) {_variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; switch (vtFld. vt) {case VT_CY: cyValue = (CURRENCY) vtFld.cyVal; break; case VT_EMPTY: case VT_NULL: {cyValue = COleCurrency (); cyValue.m_status = COleCurrency :: null;} break; default: return FALSE;} return TRUE ;} Catch (_COM_ERROR & E) {dump_com_error (e); returnafse;}}

BOOL CADORecordset :: GetFieldValue (int nIndex, COleCurrency & cyValue) {_variant_t vtFld; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; try {vtFld = m_pRecordset-> Fields-> GetItem (vtIndex) -> Value; switch (vtFld.vt) {case VT_CY: cyValue = (CURRENCY) vtFld.cyVal; break; case VT_EMPTY: case VT_NULL: {cyValue = COleCurrency (); cyValue.m_status = COleCurrency :: null;} break; default: return FALSE; } Return True;} catch (_COM_ERROR & E) {dump_com_error (e); returnaf;}}

BOOL CADORecordset :: GetFieldValue (LPCTSTR lpFieldName, _variant_t & vtValue) {try {vtValue = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE;} } BOOL CADORecordset :: GetFieldValue (int nIndex, _variant_t & vtValue) {_variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; try {vtValue = m_pRecordset-> Fields-> GetItem (vtIndex) -> Value; return TRUE; } CatCH (_COM_ERROR & E) {dump_com_error (e); return false;}}

BOOL CADORecordset :: IsFieldNull (LPCTSTR lpFieldName) {_variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; return vtFld.vt == VT_NULL;} catch (_com_error & e) {dump_com_error (e) Return False;}}

Bool Cadorecordset :: isfieldnull (int NINDEX) {_variant_t vtfld; _variant_t vtindex;

VtIndex.vt = vt_i2; vtindex.ival = nindex; try {vtfld = m_precordset-> fields-> getItem (vtInDex) -> value; return vtfld.vt == vt_null;} catch (_COM_ERROR & E) {dump_com_error (e); Return false;}}

BOOL CADORecordset :: IsFieldEmpty (LPCTSTR lpFieldName) {_variant_t vtFld; try {vtFld = m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value; return vtFld.vt == VT_EMPTY || vtFld.vt == VT_NULL;} catch ( _COM_ERROR & E) {dump_com_error (e); return false;}}

BOOL CADORecordset :: IsFieldEmpty (int nIndex) {_variant_t vtFld; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; try {vtFld = m_pRecordset-> Fields-> GetItem (vtIndex) -> Value; return vtFld.vt == VT_EMPTY || vtFld.vt == VT_NULL;} catch (_com_error & e) {dump_com_error (e); return FALSE;}} BOOL CADORecordset :: SetFieldEmpty (LPCTSTR lpFieldName) {_variant_t vtFld; vtFld.vt = VT_EMPTY; return PutFieldValue (lpfieldname, vtfld);

Bool Cadorecordset :: setfieldempty (int NINDEX) {_variant_t vtfld; vtfld.vt = vt_empty;

_VARIANT_T VTINDEX; vtIndex.vt = vt_i2; vtIndex.ival = nindex; return putfieldvalue (vtIndex, vtfld);

DWORD CADORECORDSET :: getRecordCount () {dword nrows = 0; nrows = m_precordset-> getRecordCount ();

if (nRows == -1) {nRows = 0; if (! m_pRecordset-> EndOfFile = VARIANT_TRUE) m_pRecordset-> MoveFirst (); while (! m_pRecordset-> EndOfFile = VARIANT_TRUE) {nRows ; m_pRecordset-> MoveNext (); } IF (nrows> 0) m_precordset-> movefirst ();} return nROWS;

Bool Cadorecordset :: Isopen () () (m_precordset! = Null && isconnectionopen ()) Return M_PRecordSet-> getState ()! = Adstateclosed; Return False;

Void Cadorecordset :: Close () {if (isopen ()) {if (m_neditstatus! = dbeditnone) Cancelupdate ();

M_PRecordset-> Putsort (_t (")); m_precordset-> close ();}}

Bool Cadodatabase :: EXECUTE (LPCTSTR LPSTREXEC) {assert (m_pconnection! = Null); assert (strcmp (lpstrexec, _t ("))! = 0); _variant_t vrecords; m_nrecordsaffected = 0;

try {m_pConnection-> CursorLocation = adUseClient; m_pConnection-> Execute (_bstr_t (lpstrExec), & vRecords, adExecuteNoRecords); m_nRecordsAffected = vRecords.iVal; return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE;}} Bool Cadorecordset :: Recordbinding (Cadorecordbinding) {HRESULT HR; M_PRECBINDING = NULL

// Open the binding interface if (FAILED (hr = m_pRecordset-> QueryInterface (__ uuidof (IADORecordBinding), (LPVOID *) & m_pRecBinding))). {_Com_issue_error (hr); return FALSE;} // Bind the recordset to class if ( Failed (hr = m_precbinding-> bindtorecordset (& padorecordbinding))) {_com_issue_error (hr); return false;} return true;}

Bool Cadorecordset :: GetfieldInfo (LPCTSTR LPFIELDNAME, CADOFIELDINFO * FLDINFO) {Fieldptr Pfield = m_pRecordset-> Fields-> GetItem (lpfieldname); Return getFieldInfo (Pfield, FldInfo);

Bool Cadorecordset :: getfieldInfo (int Nindex, CadofieldInfo * fldinfo) {_variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = nindex;

Fieldptr pfield = m_precordset-> fields-> getItem (vtIndex);

Return GetfieldInfo (Pfield, FLDINFO);

Bool Cadorecordset :: GetfieldInfo (Fieldptr Pfield, CadofieldInfo * FldInfo) {MEMSET (FLDInfo, 0, Sizeof (CADOFIELDINFO));

strcpy (fldInfo-> m_strName, (LPCTSTR) pField-> GetName ()); fldInfo-> m_lDefinedSize = pField-> GetDefinedSize (); fldInfo-> m_nType = pField-> GetType (); fldInfo-> m_lAttributes = pField-> GetAttributes (); if (! Ityof ()) fldinfo-> m_lsize = pfield-> getActualsize (); Return True;}

BOOL CADORecordset :: GetChunk (LPCTSTR lpFieldName, CString & strValue) {FieldPtr pField = m_pRecordset-> Fields-> GetItem (lpFieldName); return GetChunk (pField, strValue);} BOOL CADORecordset :: GetChunk (int nIndex, CString & strValue) {_variant_t VtIndex; vtIndex.vt = vt_i2; vtindex.ival = nindex;

Fieldptr pfield = m_precordset-> fields-> getItem (vtInDex); return getchunk (pfield, strvalue);}

Bool Cadorecordset :: getchunk (Fieldptr Pfield, CString & Strvalue) {cstring str = _t ("); long lngsize, lngoffset = 0; _variant_t varchunk;

lngSize = pField-> ActualSize; str.Empty (); while (lngOffSet GetChunk (ChunkSize); str = varChunk.bstrVal; lngOffSet = ChunkSize;} catch (_com_error & e) {DUMP_COM_ERROR (E); return false;}}

LNGOFFSET = 0; strValue = str; return true;}

Bool Cadorecordset :: getChunk (LPCTSTR LPFIELDNAME, LPVOID LPDATA) {Fieldptr Pfield = m_pRecordSet-> Fields-> GetItem (lpfieldname);

Return getChunk (Pfield, LPDATA);

Bool Cadorecordset :: getChunk (int NINDEX, LPVOID LPDATA) {_variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = nindex;

Fieldptr pfield = m_precordset-> fields-> getItem (vtIndex);

Return getChunk (Pfield, LPDATA);

Bool Cadorecordset :: getchunk (Fieldptr Pfield, LPVOID LPDATA) {long lngsize, lngoffset = 0; _variant_t varchunk; uchar chdata; hResult HR; long lbytescopied = 0;

LNGSIZE = Pfield-> actualsize; while (lngoffset getChunk (chunksize);

// Copy the data only upto the Actual Size of Field for (long lIndex = 0; lIndex <= (ChunkSize - 1); lIndex ). {Hr = SafeArrayGetElement (varChunk.parray, & lIndex, & chData); if (SUCCEEDED (hr )) {// Take BYTE by BYTE and advance Memory Location // hr = SafeArrayPutElement ((SAFEARRAY FAR *) lpData, & lBytesCopied, & chData); ((UCHAR *) lpData) [lBytesCopied] = chData; lBytesCopied ;} else break; LNGOFSET = Chunksize;} catch (_COM_ERROR & E) {dump_com_error (e); return false;}} lngoffset = 0; Return true;}

Bool Cadorecordset :: appendchunk (lpctstr lpfieldname, lpvoid lpdata, uint nbytes) {

Fieldptr pfield = m_precordset-> fields-> getItem (lpfieldname);

Return appendchunk (Pfield, LPDATA, NBYTES);

Bool Cadorecordset :: appendchunk (int NindEx, LPVOID LPDATA, UINT NBYTES) {_variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = nindex;

Fieldptr pfield = m_precordset-> fields-> getItem (vtIndex);

Return appendchunk (Pfield, LPDATA, NBYTES);

BOOL CADORecordset :: AppendChunk (FieldPtr pField, LPVOID lpData, UINT nBytes) {HRESULT hr; _variant_t varChunk; long lngOffset = 0; UCHAR chData; SAFEARRAY FAR * psa = NULL; SAFEARRAYBOUND rgsabound [1];

Try {// Create a Safe Array to Store The Array Of Bytes Rgsabound [0] .llbound = 0; RgsAbound [0] .CELEments = NBYTES; PSA = SafeArrayCreate (VT_UI1, 1, RGSABOUND);

while (lngOffset <(long) nBytes) {chData = ((UCHAR *) lpData) [lngOffset]; hr = SafeArrayPutElement (psa, & lngOffset, & chData); if (FAILED (hr)) return FALSE; lngOffset ;} lngOffset = 0 ;

// Assign the Safe Array to a variant. Var chaiant. Varchunk.vt = vt_Array | VT_UI1; VARCHUNK.PARRAY = PSA;

HR = pfield-> appendchunk (varchunk);

IF (succeededed (hr)) return true;} catch (_com_error & e) {dump_com_error (e); returnaf

Return false;}

CString CADORecordset :: GetString (LPCTSTR lpCols, LPCTSTR lpRows, LPCTSTR lpNull, long numRows) {_bstr_t varOutput; _bstr_t varNull ( ""); _bstr_t varCols ( "/ t"); _bstr_t varRows ( "/ r");

IF (strlen (lpcols)! = 0) Varcols = _BSTR_T (LPCOLS);

if (strlen (lpRows) = 0!) varRows = _bstr_t (lpRows); if (numRows == 0) numRows = (long) GetRecordCount (); varOutput = m_pRecordset-> GetString (adClipString, numRows, varCols, varRows, varNull) ;

Return (LPCTSTR) Varoutput;

CString INTOSTR (int NVAL) {CString Strret; Char Buff [10]; ITOA (NVAL, BUFF, 10); strret = buff; Return Strret;

CSTRING Longtostr (long Lval) {CString Strret; Char Buff [20]; LTOA (LVAL, BUFF, 10); STRET = BUFF; Return Strret;

CSTRING ULONGTOSTR (unsigned long) {CString Strret; char buff [20]; Ultoa (Ulval, BUFF, 10); strret = buff; return strret;

}

CSTRING DBLTOSTR (Double DBLVAL, INT NDIGITS) {CSTRING STRET; Char Buff [50];

_GCVT (DBLVAL, NDIGITS, BUFF); strret = buff; return strret;}

CSTRING DBLTOSTR (FLOAT FLTVAL) {CSTRING STRET = _T (""); char buff [50]; _GCVT (FLTVAL, 10, BUFF); strret = buff; return strret;}

Void Cadorecordset :: Edit () {m_NeditStatus = dbedit;}

Bool Cadorecordset :: addNew () {m_neditstatus = dbEDitnone; if (m_precordset-> addnew ()! = S_ok) Return False; m_neditstatus = dbeditnew; return true;

BOOL CADORecordset :: AddNew (CADORecordBinding & pAdoRecordBinding) {try {if (m_pRecBinding-> AddNew (& pAdoRecordBinding) = S_OK!) {Return FALSE;} else {m_pRecBinding-> Update (& pAdoRecordBinding); return TRUE;}} catch (_com_error & e) {DUMP_COM_ERROR (E); return false;}}

Bool Cadorecordset :: Update () {bool bret = true;

IF (M_NeditStatus! = dbEditnone) {

Try {if (m_precordset-> Update ()! = s_ok) Bret = false;} catch (_COM_ERROR & E) {dump_com_error (e); bret = false;}

IF (! Bret) m_precordset-> canpdate (); m_neditstatus = dbeditnone;} return bret;}

Void Cadorecordset :: Cancelupdate () {m_precordset-> cancelupdate (); m_neditstatus = dbeditnone;}

Bool Cadorecordset :: SetFieldValue (int NINDEX, CSTRING STRVALUE) {_variant_t vtfld; _variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = nindex;

IF (! Strvalue.isempty ()) vtfld.vt = vt_bs; else vtfld.vt = vt_null;

// CORRECTED by Giles Forster 10/03/2001 vtfld.bstrval = strval.allocsystring ();

Return PutfieldValue (VtIndex, VTFLD);

Bool Cadorecordset :: setfieldValue (LPCTSTR LPFIELDNAME, CSTRING STRVALUE) {_variant_t vtfld;

IF (! Strvalue.isempty ()) vtfld.vt = vt_bs; else vtfld.vt = vt_null;

// CORRECTED by Giles Forster 10/03/2001 vtfld.bstrval = strval.allocsystring ();

Return PutfieldValue (lpfieldname, vtfld);

BOOL CADORecordset :: SetFieldValue (int nIndex, int nValue) {_variant_t vtFld; vtFld.vt = VT_I2; vtFld.iVal = nValue; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; return PutFieldValue (vtIndex, vtFld) } Bool Cadorecordset :: setfieldValue (LPCTSTR LPFIELDNAME, INT NVALUE) {_variant_t vtfld; vtfld.vt = vt_i2; vtfld.ival = nvalue; Return PutfieldValue (lpfieldname, vtfld);}

BOOL CADORecordset :: SetFieldValue (int nIndex, long lValue) {_variant_t vtFld; vtFld.vt = VT_I4; vtFld.lVal = lValue; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; return PutFieldValue (vtIndex, vtFld) }

Bool Cadorecordset :: setfieldValue (lpctstr lpfieldname, long Lvalue) {_variant_t vtfld; vtfld.vt = vt_i4; vtfld.lval = LVALUE; RETFLD.LVAL = LVALUE; RETFIELDNAME, VTFLD);}

BOOL CADORecordset :: SetFieldValue (int nIndex, unsigned long ulValue) {_variant_t vtFld; vtFld.vt = VT_UI4; vtFld.ulVal = ulValue; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; return PutFieldValue (vtIndex, vtFld }

BOOL CADORecordset :: SetFieldValue (LPCTSTR lpFieldName, unsigned long ulValue) {_variant_t vtFld; vtFld.vt = VT_UI4; vtFld.ulVal = ulValue; return PutFieldValue (lpFieldName, vtFld);}

Bool Cadorecordset :: setfieldValue (int NINDEX, DOUBLE DBLVALUE) {_variant_t vtfld; vtfld.vt = vt_r8; vtfld.dblval = dblValue;

_VARIANT_T VTINDEX; vtIndex.vt = vt_i2; vtIndex.ival = NINDEX;

Return PutfieldValue (VtIndex, VTFLD);

Bool Cadorecordset :: setfieldValue (lpctstr lpfieldname, double dblvalue) {_variant_t vtfld; vtfld.vt = vt_r8; vtfld.dblval = dblvalue; returneldname, vtfld);}

BOOL CADORecordset :: SetFieldValue (int nIndex, COleDateTime time) {_variant_t vtFld; vtFld.vt = VT_DATE; vtFld.date = time; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; return PutFieldValue (vtIndex, vtFld) } BOOL CADORECORDSET :: SetFieldValue (LPCTSTR LPFIELDNAME, COLEDATETIME TIME) {_variant_t vtfld; vtfld.vt = vt_date; vtfld.date = Time; Return PutfieldValue (lpfieldname, vtfld);}

BOOL CADORecordset :: SetFieldValue (int nIndex, bool bValue) {_variant_t vtFld; vtFld.vt = VT_BOOL; vtFld.boolVal = bValue; _variant_t vtIndex; vtIndex.vt = VT_I2; vtIndex.iVal = nIndex; return PutFieldValue (vtIndex, vtFld) }

Bool Cadorecordset :: setfieldValue (LPCTSTR LPFIELDNAME, BOOL BVALUE) {_variant_t vtfld; vtfld.vt = vt_bool; vtfld.boolval = bvalue; Return PutfieldValue (lpfieldname, vtfld);}

Bool Cadorecordset :: SetFieldValue (int NINDEX, COLLURRENCY CYVALUE) {i (cyvalue.m_status == colecurrency :: invalid) Return False;

_variant_t vtfld; vtfld.vt = vt_cy; vtfld.cyval = cyvalue.m_cur; _variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = NINDEX; Return PutfieldValue (vtIndex, vtfld);

Bool Cadorecordset :: SetFieldValue (LPCTSTR LPFIELDNAME (CYVALUE.M_STATUS == Colecurrency :: Invalid) Return False;

_VARIANT_T VTFLD;

vtfld.vt = vt_cy; vtfld.cyval = cyval.m_cur; return putfieldValue (lpfieldname, vtfld);

Bool Cadorecordset :: setfieldValue (int NINDEX, _VARIANT_T VTVALUE) {_variant_t vtindex; vtIndex.vt = vt_i2; vtIndex.ival = nindex; returnus putfieldvalue (vtInDex, vzzalue);}

BOOL CADORecordset :: SetFieldValue (LPCTSTR lpFieldName, _variant_t vtValue) {return PutFieldValue (lpFieldName, vtValue);} BOOL CADORecordset :: SetBookmark () {if (m_varBookmark.vt = VT_EMPTY!) {M_pRecordset-> Bookmark = m_varBookmark; return TRUE; } Return False;

Bool Cadorecordset :: Delete () {if (M_PRecordSet-> Delete (AdaffectCurrent)! = S_OK) Return False;

IF (m_precordset-> Update ()! = s_ok) Return False; M_NeditStatus = dbeditnone; Return True;

Bool Cadorecordset :: Find (LPCTSTR LPFIND, INT NSEARCHDIRECTION) {

m_strfind = lpfind; m_nsearchdirection = nsearchdirection;

Assert (! M_strfind.isempty ());

if (m_nSearchDirection == searchForward) {m_pRecordset-> Find (_bstr_t (m_strFind), 0, adSearchForward, ""); if (IsEof ()!) {m_varBookFind = m_pRecordset-> Bookmark; return TRUE;}} else if (m_nSearchDirection == searchBackward) {m_pRecordset-> Find (_bstr_t (m_strFind), 0, adSearchBackward, ""); if (! IsBof ()) {m_varBookFind = m_pRecordset-> Bookmark; return TRUE;}} else {TRACE ( "Unknown parameter .% d ", nsearchdirection); m_nsearchdirection = searchforward;} Return False;

Bool Cadorecordset :: FindFirst (LPCTSTR LPFIND) {m_precordset-> movefirst (); returnof (lpfind);

BOOL CADORecordset :: FindNext () {if (m_nSearchDirection == searchForward) {m_pRecordset-> Find (_bstr_t (m_strFind), 1, adSearchForward, m_varBookFind); if {m_varBookFind = m_pRecordset-> Bookmark (IsEof ()!); Return TRUE }}} Else {m_precordset-> Find, 1, Adsearchbackward, M_VarBookfind; if (! Isbof ()) {m_varbookfind = m_precordset-> Bookmark; return true;}}} Return false;

BOOL CADORecordset :: PutFieldValue (LPCTSTR lpFieldName, _variant_t vtFld) {if (m_nEditStatus == dbEditNone) return FALSE; try {m_pRecordset-> Fields-> GetItem (lpFieldName) -> Value = vtFld; return TRUE;} catch (_com_error & e) {DUMP_COM_ERROR (E); Return False;}} Bool Cadorecordset :: PutfieldValue (_VARIANT_T VTINDEX, _VARIANT_T VTFLD) {IF (m_neditstatus == dbeditnone) Return False;

Try {m_precordset-> fields-> GetItem (vtIndex) -> value = vtfld; return true;} catch (_ERROR & E) {dump_com_error (e); returnaf false;}}

BOOL CADORecordset :: Clone (CADORecordset & pRs) {try {pRs.m_pRecordset = m_pRecordset-> Clone (adLockUnspecified); return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE;}}

BOOL CADORecordset :: SetFilter (LPCTSTR strFilter) {ASSERT (IsOpen ()); try {m_pRecordset-> PutFilter (strFilter); return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE;}}

BOOL CADORecordset :: SetSort (LPCTSTR strCriteria) {ASSERT (IsOpen ()); try {m_pRecordset-> PutSort (strCriteria); return TRUE;} catch (_com_error & e) {dump_com_error (e); return FALSE;}}

Bool Cadorecordset :: SaveAstr LPSTRXMLFILE {HRESULT HR;

Assert (isopen ()); try {hr = m_precordset-> save (lpstrxmlfile, adpersistXML); return hr == s_ok;} catch (_COM_ERROR & E) {dump_com_error (e); return false;} return true;}

Bool Cadorecordset :: OpenXML (LPCTSTR LPSTRXMLFILE) {HRESULT HR = S_OK;

IF (isopen ()) close ();

try {hr = m_pRecordset-> Open (lpstrXMLFile, "Provider = MSPersist;", adOpenForwardOnly, adLockOptimistic, adCmdFile); return hr == S_OK;} catch (_com_error & e) {dump_com_error (e); return FALSE;}} BOOL CADORecordset :: EXECUTE (CADOCOMMAND * PADOCOMMAND) {ix (isopen ()) close ();

(!. PAdoCommand-> GetText () IsEmpty ()) ASSERT; try {m_pConnection-> CursorLocation = adUseClient; m_pRecordset = pAdoCommand-> GetCommand () -> Execute (NULL, NULL, pAdoCommand-> GetType ()); return TRUE ;} Catch (_COM_ERROR & E) {dump_com_error (e); returnafse;}}

void CADORecordset :: dump_com_error (_com_error & e) {CString ErrorStr; _bstr_t bstrSource (e.Source ()); _bstr_t bstrDescription (e.Description ()); ErrorStr.Format ( "CADORecordset Error / n / tCode =% 08lx / n / Tcode Meaning =% S / N / TSOURE =% S / N / TDESCRIPTION =% S / N ", E.Error (), E.ErrorMessage (), (lpcstr) bstrsource, (lpcstr) bstrdescription; m_strlasterror = _t ( "Query =" getQuery () '/ n' errorstr); m_dwlasterror = E.Error (); #ifdef _debug AFXMESSAGEBOX (ERRORSTR, MB_OK | MB_ICONERROR); #ENDIF}

/////// CADOCOMMAD CLASS /////

CADOCommand :: CADOCommand (CADODatabase * pAdoDatabase, CString strCommandText, int nCommandType) {m_pCommand = NULL; m_pCommand.CreateInstance (__ uuidof (Command)); m_strCommandText = strCommandText; m_pCommand-> CommandText = m_strCommandText.AllocSysString (); m_nCommandType = nCommandType; m_pCommand -> CommandType = (CommandTyPeenum) m_ncommandtype; m_pcommand-> ActiveConnection = Padodatabase-> getActiveConnection (); m_nRecordsaffected = 0;}

BOOL CADOCommand :: AddParameter (CADOParameter * pAdoParameter) {ASSERT (pAdoParameter-> GetParameter () = NULL!); Try {m_pCommand-> Parameters-> Append (pAdoParameter-> GetParameter ()); return TRUE;} catch (_com_error & e ) {Dump_com_error (e); return false;}}

Bool Cadocommand :: AddParameter (CString Strnameter (int ND nDirection, long lsize, int nvalue) {

_VARIANT_T VTVALUE;

VtValue.vt = vt_i2; vzzalue.ival = nvalue;

Return AddParameter (Strname, NTYPE, NDIRECTION, LSIZE, VTVALUE);

Bool Cadocommand :: AddParameter (CSTRING STRNAME, INT NTYPE, INT NDIRECTION, Long Lsize, long Lvalue) {

_VARIANT_T VTVALUE;

VtValue.vt = vt_i4; vtvalue.lval = LVALUE;

Return AddParameter (Strname, NTYPE, NDIRECTION, LSIZE, VTVALUE);

Bool Cadocommand :: AddParameter (CString Strname) {

_VARIANT_T VTVALUE;

VtValue.vt = vt_r8; vzzalue.dblval = dblvalue;

Return AddParameter (Strname, NTYPE, NDIRECTION, LSIZE, VTVALUE, NPRECISION, NSCALE);}

Bool Cadocommand :: AddParameter (CString Strnameter (int ND NDIRECTION, Long Lsize, CString Strvalue) {

_VARIANT_T VTVALUE;

VtValue.vt = vt_bs; vzzalue.bstrval = strvalue.allocsystring ();

Return AddParameter (Strname, NTYPE, NDIRECTION, LSIZE, VTVALUE);

Bool Cadocommand :: Addparameter (CString Strnameter (int NTYPE, INT NDIRECTION, long lsize, coledatetime time) {

_VARIANT_T VTVALUE;

VtValue.vt = vt_date; vtvalue.date = TIME;

Return AddParameter (Strname, NTYPE, NDIRECTION, LSIZE, VTVALUE);

BOOL CADOCommand :: AddParameter (CString strName, int nType, int nDirection, long lSize, _variant_t vtValue, int nPrecision, int nScale) {try {_ParameterPtr pParam = m_pCommand-> CreateParameter (strName.AllocSysString (), (DataTypeEnum) nType, ( ParameterDirectionEnum) nDirection, lSize, vtValue); pParam-> PutPrecision (nPrecision); pParam-> PutNumericScale (nScale); m_pCommand-> Parameters-> Append (pParam); return TRUE;} catch (_com_error & e) {dump_com_error (e) Return false;}} void Cadocommand :: setText (cstring strcommandtext) {assert (! Strcommandtext.isempty ());

m_strcommandtext = strcommandtext; m_pcommand-> commandtext = m_strcommandtext.allocsystring ();}

Void Cadocommand :: settype (int ncommandtype) {m_ncommandtype = ncommandType; m_pcommand-> commandtype = (commandtypeenum) m_ncommandtype;}

BOOL CADOCommand :: Execute () {_variant_t vRecords; m_nRecordsAffected = 0; try {m_pCommand-> Execute (& vRecords, NULL, adCmdStoredProc); m_nRecordsAffected = vRecords.iVal; return TRUE;} catch (_com_error & e) {dump_com_error (e); Return false;}}

void CADOCommand :: dump_com_error (_com_error & e) {CString ErrorStr; _bstr_t bstrSource (e.Source ()); _bstr_t bstrDescription (e.Description ()); ErrorStr.Format ( "CADOCommand Error / n / tCode =% 08lx / n / Tcode Meaning =% S / N / Tsource =% S / N / TDESCRIPTION =% S / N ", E.Error (), E.ERRORMESSAGE (), (LPCST) BSTRSOURCE, (LPCSTR) BSTRDESBRIPTION; M_STRLASTERROR = Errorstr; m_dwlasterror = E.Error (); #ifdef _debug AFXMESSAGEBOX (ERRORSTR, MB_OK | MB_ICONERROR); #ENDIF}

////// Cadoparameter Class //

CADOParameter :: CADOParameter (int nType, long lSize, int nDirection, CString strName) {m_pParameter = NULL; m_pParameter.CreateInstance (__ uuidof (Parameter)); m_strName = _T ( ""); m_pParameter-> Direction = (ParameterDirectionEnum) nDirection; m_strName = strName; m_pParameter-> Name = m_strName.AllocSysString (); m_pParameter-> Type = (DataTypeEnum) nType; m_pParameter-> Size = lSize; m_nType = nType;} BOOL CADOParameter :: SetValue (int nValue) {_variant_t vtVal;

Assert (m_pparameter! = Null); vtVal.vt = vt_i2; vtval.ival = nvalue;

Try {if (m_pparameter-> size == 0) m_pparameter-> size = sizeof (int);

M_pparameter-> value = vtval; return true;} catch (_rm_error & e) {dump_com_error (e); returnaf false;}}

Bool Cadoparameter :: setValue (long Lvalue) {_variant_t vzzal;

Assert (m_pparameter! = Null); vtval.vt = vt_i4; vtval.lval = LVALUE;

Try {if (m_pparameter-> size == 0) m_pparameter-> size = sizeof (long);

M_pparameter-> value = vtval; return true;} catch (_rm_error & e) {dump_com_error (e); returnaf false;}}

Bool Cadoparameter :: setvalue (double dblvalue) {_variant_t vzzal;

Assert (m_pparameter! = Null); vtVal.vt = vt_r8; vtval.dblval = dblvalue;

Try {if (m_pparameter-> size == 0) m_pparameter-> size = sizeof (double);

M_pparameter-> value = vtval; return true;} catch (_rm_error & e) {dump_com_error (e); returnaf false;}}

Bool Cadoparameter :: setValue (CString Strvalue) {_variant_t vtval;

Assert (m_pparameter! = Null); if (! StrValue.isempty ()) vtVal.vt = vt_bs; else vtval.vt = vt_null;

// CORRECTED by Giles Forster 10/03/2001 vtval.bstrval = strvalue.allocsysString (); try {if (m_pparameter-> size == 0) m_pparameter-> size = sizeof (char) * strvalue.getlength ();

M_pparameter-> value = vtval; return true;} catch (_rm_error & e) {dump_com_error (e); returnaf false;}}

Bool Cadoparameter :: setValue (COLEDATETIME TIME) {_variant_t vtval;

Assert (m_pparameter! = Null); vtVal.vt = vt_date; vtval.date = time;

Try {IF (m_pparameter-> size == 0) m_pparameter-> size = sizeof (date);

M_pparameter-> value = vtval; return true;} catch (_rm_error & e) {dump_com_error (e); returnaf false;}}

Bool Cadoparameter :: setValue (_VARIANT_T VTVALUE) {

Assert (m_pparameter! = Null);

Try {if (m_pparameter-> size == 0) m_pparameter-> size = sizeof (variant); m_pparameter-> value = vtvalue; return true;} catch (_COM_ERROR & E) {dump_com_error (e); returnaf false;}}}}

Bool Cadoparameter :: getValue (int & nvalue) {_variant_t vzzal; int nval = 0;

Try {vtval = m_pparameter-> value;

Switch (vtVal.vt) {copy vt_bool: nval = vtVal.BoolVal; Break; Case vt_i2: case vt_ui1: nval = vtval.ival; break; case vt_int: nval = vtVal.intVal; break; case vt_null: case vt_empty: NVAL = 0; brefault: nval = vtval.ival;} nvalue = nval; return true;} catch (_ERROR & E) {dump_com_error (e); returnaf false;}}

Bool Cadoparameter :: getValue (long & lvalue) {_variant_t vtval; long lval = 0;

Try {vtval = m_pparameter-> value; if (vtval.vt! = vt_null && vtVal.vt! = vt_empty) LVAL = vtval.lval; lvalue = lval; return true;} catch (_Error & e) {dump_com_error (e); return FALSE;}} BOOL CADOParameter :: GetValue (double & dbValue) {_variant_t vtVal; double dblVal; try {vtVal = m_pParameter-> Value; switch (vtVal.vt) {case VT_R4: dblVal = vtVal.fltVal; break; case VT_R8 : Dblval = vtVal.dblval; breaf; case vt_decimal: // CASE VT_DES? Carlos Mart Han EZ GAL 醤 dblval = vtval.decval.lo32; dblval * = (vtval.decval.sign == 128)? -1: 1 DBLVAL / = POW (10, vtval.decval.scale); Break; Case VT_UI1: dblval = vtval.ival; break; case vt_i2: case vt_i4: dblval = vtVal.lval; break; case vt_int: dblval = vtval.intval Break; case vt_null: Case vt_empty: dblval = 0; Break; default: dblval = 0;} dbvalue = dblval; return true;} catch (_ERROR & E) {dump_com_error (e); returnaf false;}}}

Bool Cadoparameter :: getValue (CString & Strvalue, CString strdateformat) {_variant_t vzzal; cstring strval = _t (");

Try {vtval = m_pparameter-> value; switch (vtVal.vt) {case vt_r4: strval = dbltostr (vtVal.fltval); break; case vt_r8: strval = dbltostr (vtVal.dblval); break; case vt_bstr: strval = vtval .BSTRVAL; Break; Case vt_i2: Case VT_UI1: Strval = INTOSTR (VtVal.IVAL); Break; Case VT_INT: Strval = INTOSTR (VtVal.intVal); Break; Case VT_i4: Strval = longtostr (vzzal.lval); Break; Case vt_decimal: {// CORRECTED BY JOS? Carlos Mart Han EZ Gal 醤 Double Val = vtval.decval.lo32; Val * = (vtval.decval.sign == 128)? -1: 1; VAL / = POW (10 , vtval.decval.scale); Strval = dbltostr (VAL);} Break; case vt_date: {COLEDATETIME DT (VtVal); if (strdateformat.isempty ()) strdateformat = _t ("% Y-% M-% D% H:% m:% s "); strd = dt.format;} Break; case vt_empty: case vt_null: strVal.empty (); break; default: strVal.empty (); return false;} strval = Strval; return true;} catch (_COM_ERROR & E) {dump_com_error (e); return false;}}

Bool Cadoparameter :: getValue (COLEDATETIME & TIME) {_variant_t vtval;

Try {vtval = m_pparameter-> value; switch (vtVal.vt) {CASE VT_DATE: {CALDATETIME DT (VTVAL); TIME = DT;} Break; Case VT_EMPTY: CASE VT_NULL: Time.setstatus (COLEDATETIME :: Null); Break Default: return false;} Return true;} catch (_COM_ERROR & E) {dump_com_error (e); return false;}}

Bool Cadoparameter :: getValue (_variant_t & vtvalue) {try {vtvalue = m_pparameter-> value; return true;} catch (_Error & e) {dump_com_error (e); returnaf false;}}

void CADOParameter :: dump_com_error (_com_error & e) {CString ErrorStr; _bstr_t bstrSource (e.Source ()); _bstr_t bstrDescription (e.Description ()); ErrorStr.Format ( "CADOParameter Error / n / tCode =% 08lx / n / Tcode Meaning =% S / N / Tsource =% S / N / TDESCRIPTION =% S / N ", E.Error (), E.ERRORMESSAGE (), (LPCST) BSTRSOURCE, (LPCSTR) BSTRDESBRIPTION; M_STRLASTERROR = Errorstr; m_dwlasterror = E.Error (); #ifdef _debug AFXMESSAGEBOX (ERRORSTR, MB_OK | MB_ICONERROR); #ENDIF} IMPLEMENT_DYNAMIC (CADOEXCEPTION, CEXCEPTION)

CadoException :: CadoException (int ncause): CEXCEPTION (TRUE) {m_ncause = ncause; m_strerrorString = strerrorstring;}

CadoException :: ~ CadoException () {

}

INT CADOEXCEPTION:: Get NadoError) {Switch (NadoError) {Case NoError: Return CadoException :: norror; break; default: Return CadoException :: unknown;}}

Void AFXTHROWADOEXCEPTION (INT NADOERROR, CSTRING STRERRORSTRING) {throw new cadoException (NadoError, strerrorstring)

///Ado.h///////////mailto: cantollini@hotmail.com///////// Version 2.09 //

#ifndef _ado_h_ # define _ado_h_

# if _: _:: # (disable: 4146) // cg: (Disable: 4146) // cg: 4146) // cg: in order to use this code against a different version of ADO, the appropriate // ADO library needs to be used in the #import statement # import "c: / Program Files / Common Files / System / ADO / msado15.dll" rename_namespace ( "Adocg") Rename ("EOF", "endoffile") Using namespace adocg;

#pragma Warning (Default: 4146) #include "icrsint.h"

Class CADOCOMMAND;

struct CADOFieldInfo {char m_strName [30]; short m_nType; long m_lSize; long m_lDefinedSize; long m_lAttributes; short m_nOrdinalPosition; BOOL m_bRequired; BOOL m_bAllowZeroLength; long m_lCollatingOrder;};

CSTRING INTTOSTR (INT NVAL);

CSTRING LongtoStr (Long Lval);

CSTRING ULONGTOSTR (unsigned long ";

CSTRING DBLTOSTR (Double DBLVAL, INT NDIGITS = 20);

CString DBLTOSTR (FLOAT FLTVAL);

class CADODatabase {public: enum cadoConnectModeEnum {connectModeUnknown = adModeUnknown, connectModeRead = adModeRead, connectModeWrite = adModeWrite, connectModeReadWrite = adModeReadWrite, connectModeShareDenyRead = adModeShareDenyRead, connectModeShareDenyWrite = adModeShareDenyWrite, connectModeShareExclusive = adModeShareExclusive, connectModeShareDenyNone = adModeShareDenyNone};

CADODatabase () {:: CoInitialize (NULL); m_pConnection = NULL; m_strConnection = _T ( ""); m_strLastError = _T ( ""); m_dwLastError = 0; m_pConnection.CreateInstance (__ uuidof (Connection)); m_nRecordsAffected = 0; m_nConnectionTimeout = 0;} Virtual ~ Cadodatabase () {close (); m_pConnection.release (); m_pconnection = null; m_strconnection = _t ("); m_strlasterror = _t ("); m_dwlasterror = 0; :: couninitialize () ;: } BOOL Open (LPCTSTR lpstrConnection = _T ( ""), LPCTSTR lpstrUserID = _T ( ""), LPCTSTR lpstrPassword = _T ( "")); _ConnectionPtr GetActiveConnection () {return m_pConnection;}; BOOL Execute (LPCTSTR lpstrExec); int GetRecordsAffected () {return m_nRecordsAffected;}; DWORD GetRecordCount (_RecordsetPtr m_pRs); long BeginTransaction () {return m_pConnection-> BeginTrans ();}; long CommitTransaction () {return m_pConnection-> CommitTrans ();}; long RollbackTransaction () {RETURN M_PCONNECTION-> rollbackTrans ();}; bool isopen (); void close (); void setConnectionMode (CadoconnectMo deEnum nMode) {m_pConnection-> PutMode ((enum ConnectModeEnum) nMode);}; void SetConnectionString (LPCTSTR lpstrConnection) {m_strConnection = lpstrConnection;}; CString GetConnectionString () {return m_strConnection;}; CString GetLastErrorString () {return m_strLastError;} ; DWORD GetLastError () {return m_dwLastError;}; CString GetErrorDescription () {return m_strErrorDescription;}; void SetConnectionTimeout (long nConnectionTimeout = 30) {m_nConnectionTimeout = nConnectionTimeout;}; protected: void dump_com_error (_com_error & e);

PUBLIC: _CONNECTIONPTR M_PCONNECTION;

protected: CString m_strConnection; CString m_strLastError; CString m_strErrorDescription; DWORD m_dwLastError; int m_nRecordsAffected; long m_nConnectionTimeout;}; class CADORecordset {public: BOOL Clone (CADORecordset & pRs); enum cadoOpenEnum {openUnknown = 0, openQuery = 1, openTable = 2, openStoredProc = 3};

enum cadoEditEnum {dbEditNone = 0, dbEditNew = 1, dbEdit = 2}; enum cadoPositionEnum {positionUnknown = -1, positionBOF = -2, positionEOF = -3}; enum cadoSearchEnum {searchForward = 1, searchBackward = -1};

enum cadoDataType {typeEmpty = adEmpty, typeTinyInt = adTinyInt, typeSmallInt = adSmallInt, typeInteger = adInteger, typeBigInt = adBigInt, typeUnsignedTinyInt = adUnsignedTinyInt, typeUnsignedSmallInt = adUnsignedSmallInt, typeUnsignedInt = adUnsignedInt, typeUnsignedBigInt = adUnsignedBigInt, typeSingle = adSingle, typeDouble = adDouble, typeCurrency = adCurrency , typeDecimal = adDecimal, typeNumeric = adNumeric, typeBoolean = adBoolean, typeError = adError, typeUserDefined = adUserDefined, typeVariant = adVariant, typeIDispatch = adIDispatch, typeIUnknown = adIUnknown, typeGUID = adGUID, typeDate = adDate, typeDBDate = adDBDate, typeDBTime = adDBTime, typeDBTimeStamp = adDBTimeStamp, typeBSTR = adBSTR, typeChar = adChar, typeVarChar = adVarChar, typeLongVarChar = adLongVarChar, typeWChar = adWChar, typeVarWChar = adVarWChar, typeLongVarWChar = adLongVarWChar, typeBinary = adBinary, typeVarBinary = adVarBinary, typeLongVarBinary = adLongVarBinary, typeChapter = adChapter, typeFileTime = adFileTime, typePropVariant = adPropVariant, typeVarNumeric = adVarNumeric, typeArray = adVariant}; enum cadoSchemaType {schemaSpecific = adSchemaProviderSpecific, schemaAsserts = adSchemaAsserts, schemaCatalog = adSchemaCatalogs, schemaCharacterSet = adSchemaCharacterSets, schemaCollections = adSchemaCollations, schemaColumns = adSchemaColumns, schemaConstraints = Adschemacheckconstraints, SchemaconstraintColumnUsage = adschemaconstraintcolumnage, SchemaconstranetTableusage =

adSchemaConstraintTableUsage, shemaKeyColumnUsage = adSchemaKeyColumnUsage, schemaTableConstraints = adSchemaTableConstraints, schemaColumnsDomainUsage = adSchemaColumnsDomainUsage, schemaIndexes = adSchemaIndexes, schemaColumnPrivileges = adSchemaColumnPrivileges, schemaTablePrivileges = adSchemaTablePrivileges, schemaUsagePrivileges = adSchemaUsagePrivileges, schemaProcedures = adSchemaProcedures, schemaTables = adSchemaTables, schemaProviderTypes = adSchemaProviderTypes, schemaViews = adSchemaViews, schemaProcedureParameters = adSchemaProcedureParameters, schemaForeignKeys = adSchemaForeignKeys, schemaPrimaryKeys = adSchemaPrimaryKeys, schemaProcedureColumns = adSchemaProcedureColumns, schemaDBInfoKeywords = adSchemaDBInfoKeywords, schemaDBInfoLiterals = adSchemaDBInfoLiterals, schemaCubes = adSchemaCubes, schemaDimensions = adSchemaDimensions, schemaHierarchies = adSchemaHierarchies, schemaLevels = adSchemaLevels, schemaMeasures = adSchemaMeasures, schemaPro Perties = adschemaproperties, schemamembers = adschemamembers,};

BOOL SetFieldValue (int nIndex, int nValue); BOOL SetFieldValue (LPCTSTR lpFieldName, int nValue); BOOL SetFieldValue (int nIndex, long lValue); BOOL SetFieldValue (LPCTSTR lpFieldName, long lValue); BOOL SetFieldValue (int nIndex, unsigned long lValue) ; BOOL SetFieldValue (LPCTSTR lpFieldName, unsigned long lValue); BOOL SetFieldValue (int nIndex, double dblValue); BOOL SetFieldValue (LPCTSTR lpFieldName, double dblValue); BOOL SetFieldValue (int nIndex, CString strValue); BOOL SetFieldValue (LPCTSTR lpFieldName, CString strValue ); BOOL SetFieldValue (int nIndex, COleDateTime time); BOOL SetFieldValue (LPCTSTR lpFieldName, COleDateTime time); BOOL SetFieldValue (int nIndex, bool bValue); BOOL SetFieldValue (LPCTSTR lpFieldName, bool bValue); BOOL SetFieldValue (int nIndex, COleCurrency cyValue ); BOOL SetFieldValue (LPCTSTR lpFieldName, COleCurrency cyValue); BOOL SetFieldValue (int nIndex, _variant_t vtValue); BOOL SetFieldValue (LPCTSTR lpFieldName, _variant_t vtValue); BOOL SetFieldEmpty (int nIndex); Bool setfieldempty (lpctstr lpfieldname);

Void Cancelupdate (); Bool Update (); void Edit (); Bool AddNew (); Bool AddNew (Cadorecordbinding & PadorecordBinding)

Bool Find (LPCTSTR LPFIND, INT NSEARCHDIRECTION = Cadorecordset :: SearchForward); Bool FindFirst (LPCTSTR LPFIND); BOOL FINDNEXT ();

Cadorecordset ();

CadorecordSet (CADODATABASE * PADATABASE);

virtual ~ CADORecordset () {Close (); if (m_pRecordset) m_pRecordset.Release (); if (m_pCmd) m_pCmd.Release (); m_pRecordset = NULL; m_pCmd = NULL; m_pRecBinding = NULL; m_strQuery = _T ( ""); m_strlaster = _t (""); m_dwlasterror = 0; m_neditstatus = dbeditnone;}

CString GetQuery () {return m_strQuery;}; void SetQuery (LPCSTR strQuery) {m_strQuery = strQuery;}; BOOL RecordBinding (CADORecordBinding & pAdoRecordBinding); DWORD GetRecordCount (); BOOL IsOpen (); void Close (); BOOL Open (_ConnectionPtr mpdb , LPCTSTR lpstrExec = _T ( ""), int nOption = CADORecordset :: openUnknown); BOOL Open (LPCTSTR lpstrExec = _T ( ""), int nOption = CADORecordset :: openUnknown); BOOL OpenSchema (int nSchema, LPCTSTR SchemaID = _T ( "")); long GetFieldCount () {return m_pRecordset-> Fields-> GetCount ();}; BOOL GetFieldValue (LPCTSTR lpFieldName, int & nValue); BOOL GetFieldValue (int nIndex, int & nValue); BOOL GetFieldValue (LPCTSTR lpFieldName, long & lValue); BOOL GetFieldValue (int nIndex, long & lValue); BOOL GetFieldValue (LPCTSTR lpFieldName, unsigned long & ulValue); BOOL GetFieldValue (int nIndex, unsigned long & ulValue); BOOL GetFieldValue (LPCTSTR lpFieldName, double & dbValue); BOOL GetFieldValue (int NINDEX, DOUBLE & DBVALUE; BOOL GetfieldValue (LPCTSTSTR LPFIELDNAME, CSTRING & STRV alue, CString strDateFormat = _T ( "")); BOOL GetFieldValue (int nIndex, CString & strValue, CString strDateFormat = _T ( "")); BOOL GetFieldValue (LPCTSTR lpFieldName, COleDateTime & time); BOOL GetFieldValue (int nIndex, COleDateTime & time) ; BOOL GetFieldValue (int nIndex, bool & bValue); BOOL GetFieldValue (LPCTSTR lpFieldName, bool & bValue); BOOL GetFieldValue (int nIndex, COleCurrency & cyValue); BOOL GetFieldValue (LPCTSTR lpFieldName, COleCurrency & cyValue); BOOL GetFieldValue (int nIndex, _variant_t & vtValue) Bool getFieldValue (LPCTSTR LPFIELDNAME, _VARIANT_T & VTVALUE);

BOOL IsFieldNull (LPCTSTR lpFieldName); BOOL IsFieldNull (int nIndex); BOOL IsFieldEmpty (LPCTSTR lpFieldName); BOOL IsFieldEmpty (int nIndex); BOOL IsEof () {return m_pRecordset-> EndOfFile == VARIANT_TRUE;}; BOOL IsEOF () {return m_pRecordset-> EndOfFile == VARIANT_TRUE;}; BOOL IsBof () {return m_pRecordset-> BOF == VARIANT_TRUE;}; BOOL IsBOF () {return m_pRecordset-> BOF == VARIANT_TRUE;}; void MoveFirst () {m_pRecordset-> MoveFirst ();}; void MoveNext () {m_pRecordset-> MoveNext ();}; void MovePrevious () {m_pRecordset-> MovePrevious ();}; void MoveLast () {m_pRecordset-> MoveLast ();}; long GetAbsolutePage () {return m_pRecordset-> GetAbsolutePage ();}; void SetAbsolutePage (int nPage) {m_pRecordset-> PutAbsolutePage ((enum PositionEnum) nPage);}; long GetPageCount () {return m_pRecordset-> GetPageCount ();}; long GetPageSize () {return m_pRecordset-> GetPageSize ();}; void setPageSize (int nSize) {m_pRecordset-> PutPageSize (nSize);}; long GetAbsolutePosition () {return m_pRecordset-> GetAbsolutePositi on ();}; void SetAbsolutePosition (int nPosition) {m_pRecordset-> PutAbsolutePosition ((enum PositionEnum) nPosition);}; BOOL GetFieldInfo (LPCTSTR lpFieldName, CADOFieldInfo * fldInfo); BOOL GetFieldInfo (int nIndex, CADOFieldInfo * fldInfo); BOOL AppendChunk (LPCTSTR lpFieldName, LPVOID lpData, UINT nBytes); BOOL AppendChunk (int nIndex, LPVOID lpData, UINT nBytes); BOOL GetChunk (LPCTSTR lpFieldName, CString & strValue); BOOL GetChunk (int nIndex, CString & strValue); BOOL GetChunk (LPCTSTR lpFieldName LPVOID PDATA); BOOL getChunk (int NINDEX, LPVOID PDATA);

CString GetString (LPCTSTR lpCols, LPCTSTR lpRows, LPCTSTR lpNull, long numRows = 0); CString GetLastErrorString () {return m_strLastError;}; DWORD GetLastError () {return m_dwLastError;}; void GetBookmark () {m_varBookmark = m_pRecordset-> Bookmark; }; BOOL SetBookmark (); BOOL Delete ();! BOOL IsConnectionOpen () {return m_pConnection = NULL && m_pConnection-> GetState () = adStateClosed;!}; _RecordsetPtr GetRecordset () {return m_pRecordset;}; _ConnectionPtr GetActiveConnection () { return m_pConnection;}; BOOL SetFilter (LPCTSTR strFilter); BOOL SetSort (LPCTSTR lpstrCriteria); BOOL SaveAsXML (LPCTSTR lpstrXMLFile); BOOL OpenXML (LPCTSTR lpstrXMLFile); BOOL Execute (CADOCommand * pCommand); BOOL Requery ();

public: _RecordsetPtr m_pRecordset; _CommandPtr m_pCmd; protected: _ConnectionPtr m_pConnection; int m_nSearchDirection; CString m_strFind; _variant_t m_varBookFind; _variant_t m_varBookmark; int m_nEditStatus; CString m_strLastError; DWORD m_dwLastError; void dump_com_error (_com_error & e); IADORecordBinding * m_pRecBinding; CString m_strQuery;

protected: BOOL PutFieldValue (LPCTSTR lpFieldName, _variant_t vtFld); BOOL PutFieldValue (_variant_t vtIndex, _variant_t vtFld); BOOL GetFieldInfo (FieldPtr pField, CADOFieldInfo * fldInfo); BOOL GetChunk (FieldPtr pField, CString & strValue); BOOL GetChunk (FieldPtr pField, LPVOID LPDATA); BOOL APPENDCHUNK (Fieldptr Pfield, LPVOID LPDATA, UINT NBYTES);

Class Cadoparameter {public:

enum cadoParameterDirection {paramUnknown = adParamUnknown, paramInput = adParamInput, paramOutput = adParamOutput, paramInputOutput = adParamInputOutput, paramReturnValue = adParamReturnValue};

CADOParameter (int nType, long lSize = 0, int nDirection = paramInput, CString strName = _T ( "")); virtual ~ CADOParameter () {m_pParameter.Release (); m_pParameter = NULL; m_strName = _T ( "");} BOOL SetValue (int nValue); BOOL SetValue (long lValue); BOOL SetValue (double dbValue); BOOL SetValue (CString strValue); BOOL SetValue (COleDateTime time); BOOL SetValue (_variant_t vtValue); BOOL GetValue (int & nValue); BOOL GetValue (long & lValue); BOOL GetValue (double & dbValue); BOOL GetValue (CString & strValue, CString strDateFormat = _T ( "")); BOOL GetValue (COleDateTime & time); BOOL GetValue (_variant_t & vtValue); void SetPrecision (int nPrecision) { M_pparameter-> Putprecision (nPRecision);}; void setscale (int nscale) {m_pparameter-> PutNuMericscale (nscale);

void SetName (CString strName) {m_strName = strName;}; CString GetName () {return m_strName;}; int GetType () {return m_nType;}; _ParameterPtr GetParameter () {return m_pParameter;};

protected: void dump_com_error (_COM_ERROR & E); protected: _parameterptr m_pparameter; cstring m_strname; int m_ntype; cstract m_strlasterror; dword m_dwlasterror;};

class CADOCommand {public: enum cadoCommandType {typeCmdText = adCmdText, typeCmdTable = adCmdTable, typeCmdTableDirect = adCmdTableDirect, typeCmdStoredProc = adCmdStoredProc, typeCmdUnknown = adCmdUnknown, typeCmdFile = adCmdFile}; CADOCommand (CADODatabase * pAdoDatabase, CString strCommandText = _T ( ""), int nCommandType = typecmdstoredProc); Virtual ~ Cadocommand () {m_pcommand.release (); m_pcommand = null; m_strcommandtext = _t (");}

void SetTimeout (long nTimeOut) {m_pCommand-> PutCommandTimeout (nTimeOut);}; void SetText (CString strCommandText); void SetType (int nCommandType); int GetType () {return m_nCommandType;}; BOOL AddParameter (CADOParameter * pAdoParameter); BOOL AddParameter (CString strName, int nType, int nDirection, long lSize, int nValue); BOOL AddParameter (CString strName, int nType, int nDirection, long lSize, long lValue); BOOL AddParameter (CString strName, int nType, int nDirection, long lSize, double dblValue, int nPrecision = 0, int nScale = 0); BOOL AddParameter (CString strName, int nType, int nDirection, long lSize, CString strValue); BOOL AddParameter (CString strName, int nType, int nDirection, long lSize, COleDateTime time); BOOL AddParameter (CString strName, int nType, int nDirection, long lSize, _variant_t vtValue, int nPrecision = 0, int nScale = 0); CString GetText () {return m_strCommandText;}; BOOL Execute (); int GetRecordsAffected () {Return M_nRecordsaffected;}; _commandptr getcommand () {RETURN M_PCOMMAND;}; protected: void dump_com_error (_COM_ERROR & E);

Protected: _commandptr m_pcommand; int m_ncommandType; int m_nrecordsaffected; cstract m_strcommandtext; cstract m_strlasterror; dword m_dwlasterror;};

Class CadoException: Public CEXCEPTION {public:

Enum {noerror, // no error unknown, // unknown error}

DECLARE_DYNAMIC (CADOEXCEPTION); CADOEXCEPTION (int ncause = 0, cstring strorstring = _t (")); virtual ~ cadoException ();

Static int getError (int NADOERROR);

PUBLIC: INT M_NCAUSE; CSTRING M_STRERRORSTRING; protected:};

Void AFXTHROWADOEXCEPTION (int NadoError = 1000, cstring strorstring = _t ("));

# ENDIF / User Example // Create CSTRING STRCONNECTION = _T ("provider = microsoft.jet.oledb.4.0; data source = userdb.mdb"); g_pdb = new cadodatabase; g_pdb-> open (strconnection); // Using Cadorecordset * PRS = New CadorecordSet (App :: g_pdb); if (PRS-> Open ((lpctstr) "Select * from product")) {cstring tempsql; while (! prs-> ieof ()) {prs-> getfieldValue "title", tempsql); m_edit1 = m_EDit1 "| Tempsql; // Sortnum PRS-> getFieldValue (" SortNum ", Tempsql); m_edit1 = m_edit1 ", " Tempsql; PRS-> MoveNext ();} PRS- > Close (); Updatedata (false);} else afxMessageBox ("Record Set Failed"; delete PRS;

转载请注明原文地址:https://www.9cbs.com/read-53282.html

New Post(0)