676 lines
12 KiB
C++
676 lines
12 KiB
C++
#include "stdafx.h"
|
||||
|
|
#include "adsdef.h"
|
|||
|
|
#include "dbftools.h"
|
|||
|
|
#include "io.h"
|
|||
|
|
|
|||
|
|
/////////////////////////////////////////////////////////////////
|
|||
|
|
// CodeBase -- Database classs
|
|||
|
|
CodeBase::CodeBase()
|
|||
|
|
{
|
|||
|
|
m_pDbfTable = NULL;
|
|||
|
|
read_only = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
CodeBase::~CodeBase()
|
|||
|
|
{
|
|||
|
|
if (m_pDbfTable != NULL)
|
|||
|
|
{
|
|||
|
|
if (m_pDbfTable->IsOpen())
|
|||
|
|
m_pDbfTable->Close();
|
|||
|
|
delete m_pDbfTable;
|
|||
|
|
m_pDbfTable = NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DbfTable* CodeBase::Open(const TCHAR *szFile)
|
|||
|
|
{
|
|||
|
|
// add by gjm 2010/07/09
|
|||
|
|
CTDbfString _sfile(szFile);
|
|||
|
|
if (_access(_sfile.toLPCSTR(), 00) != 0) //exist ?
|
|||
|
|
return NULL;
|
|||
|
|
if (_access(_sfile.toLPCSTR(), 06) != 0) // read and write ?
|
|||
|
|
return NULL;
|
|||
|
|
// end
|
|||
|
|
|
|||
|
|
m_pDbfTable = new DbfTable;
|
|||
|
|
|
|||
|
|
// sg add 091013,支持只读方式打开
|
|||
|
|
int nOpenFlag = TG_DBF_USE_SHARED;
|
|||
|
|
if (read_only == 1)
|
|||
|
|
nOpenFlag = TG_DBF_USE_READ_ONLY;
|
|||
|
|
|
|||
|
|
if (!m_pDbfTable->Open(szFile, nOpenFlag))
|
|||
|
|
{
|
|||
|
|
delete m_pDbfTable;
|
|||
|
|
m_pDbfTable = NULL;
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return m_pDbfTable;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
DbfTable* CodeBase::Create(const TCHAR *szFile, const FieldInfo *pFieldArray,
|
|||
|
|
int nCount)
|
|||
|
|
{
|
|||
|
|
// 1、创建数据库
|
|||
|
|
CDBFTableDef *pNewTable = new CDBFTableDef;
|
|||
|
|
|
|||
|
|
// 创建数据表,并填入表头信息
|
|||
|
|
if (!pNewTable->CreateTable(szFile))
|
|||
|
|
{
|
|||
|
|
delete pNewTable;
|
|||
|
|
pNewTable = NULL;
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 增加表列信息
|
|||
|
|
for (int i=0; i<nCount; i++)
|
|||
|
|
{
|
|||
|
|
// 表列信息(DBFField:name、type、len、dec)
|
|||
|
|
FieldInfo field = pFieldArray[i];
|
|||
|
|
|
|||
|
|
// 表列信息(field_name、field_type、field_offset、len_info.char_len、
|
|||
|
|
FIELD_REC fieldRec;
|
|||
|
|
memset(&fieldRec, 0, sizeof(FIELD_REC));
|
|||
|
|
|
|||
|
|
int nLen = field.m_strName.GetLength();
|
|||
|
|
|
|||
|
|
#if (ADS < 17)
|
|||
|
|
strncpy(fieldRec.field_name, field.m_strName.toLPCSTR(), nLen);
|
|||
|
|
#else
|
|||
|
|
strncpy(fieldRec.field_name, field.m_strName.toLPCSTR(), nLen);
|
|||
|
|
#endif
|
|||
|
|
fieldRec.field_name[nLen] = EOS; // field_name
|
|||
|
|
|
|||
|
|
#if (ADS < 17)
|
|||
|
|
fieldRec.field_type = field.m_chType; // field_type
|
|||
|
|
#else
|
|||
|
|
fieldRec.field_type = field.m_chType; // field_type
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
switch(field.m_chType)
|
|||
|
|
{
|
|||
|
|
case FLD_TYPE_NUMERIC: // int、double
|
|||
|
|
fieldRec.len_info.num_size.len = field.m_nLen;
|
|||
|
|
fieldRec.len_info.num_size.dec = field.m_nDec;
|
|||
|
|
break;
|
|||
|
|
case FLD_TYPE_CHARACTER: // string
|
|||
|
|
case FLD_TYPE_DATE: // date
|
|||
|
|
case FLD_TYPE_LOGICAL: // bool
|
|||
|
|
fieldRec.len_info.char_len = field.m_nLen;
|
|||
|
|
break;
|
|||
|
|
default:
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
pNewTable->AddField(&fieldRec);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新数据表
|
|||
|
|
pNewTable->UpdateTable();
|
|||
|
|
|
|||
|
|
// 2、关闭数据库
|
|||
|
|
pNewTable->Close();
|
|||
|
|
delete pNewTable;
|
|||
|
|
pNewTable = NULL;
|
|||
|
|
|
|||
|
|
// 3、打开
|
|||
|
|
return Open(szFile);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/////////////////////////////////////////////////////////////////
|
|||
|
|
// DbfTable -- Recordset class
|
|||
|
|
int DbfTable::GetFieldNum()
|
|||
|
|
{
|
|||
|
|
int nNum = GetFieldCount();
|
|||
|
|
return nNum;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldInfo* DbfTable::GetFieldInfo()
|
|||
|
|
{
|
|||
|
|
FieldInfo *pFields = NULL;
|
|||
|
|
|
|||
|
|
int nCount = GetFieldNum();
|
|||
|
|
pFields = new FieldInfo[nCount];
|
|||
|
|
for (int i=0; i<nCount; i++)
|
|||
|
|
{
|
|||
|
|
pFields[i] = (FieldInfo&)m_DBFFields[i];
|
|||
|
|
}
|
|||
|
|
return pFields;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent* DbfTable::GetFieldContent(int n)
|
|||
|
|
{
|
|||
|
|
FieldContent *pContent = (FieldContent*)m_DBFFields.GetFieldRec(n);
|
|||
|
|
if (pContent != NULL)
|
|||
|
|
{
|
|||
|
|
CTDbfString csContent;
|
|||
|
|
GetFieldValue(n, csContent);
|
|||
|
|
|
|||
|
|
*pContent = (const TCHAR*)(csContent.toCString()); // 赋值
|
|||
|
|
return pContent;
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent* DbfTable::GetFieldContent(const TCHAR *szFieldName)
|
|||
|
|
{
|
|||
|
|
CString csName = szFieldName;
|
|||
|
|
csName.MakeUpper(); // 全部转化为大写字母
|
|||
|
|
|
|||
|
|
int nCount = GetFieldNum();
|
|||
|
|
for (int i=0; i<nCount; i++)
|
|||
|
|
{
|
|||
|
|
DBFField field = m_DBFFields[i];
|
|||
|
|
|
|||
|
|
CString csTmp = field.m_strName.toCString();
|
|||
|
|
csTmp.MakeUpper(); // 全部转化为大写字母
|
|||
|
|
|
|||
|
|
if (_tcscmp(csTmp, csName) == 0) // 查找指定列名的列
|
|||
|
|
{
|
|||
|
|
FieldContent *pContent = (FieldContent*)m_DBFFields.GetFieldRec(i);
|
|||
|
|
if (pContent != NULL)
|
|||
|
|
{
|
|||
|
|
CTDbfString csContent;
|
|||
|
|
GetFieldValue(i, csContent);
|
|||
|
|
|
|||
|
|
*pContent = (const TCHAR*)(csContent.toCString()); // 赋值
|
|||
|
|
return pContent;
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return NULL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
long DbfTable::GetRecordCount(int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
if (!bSkipDeleted) // 计算全部记录,包括被删除记录
|
|||
|
|
return CDBFRecordset::GetRecordCount();
|
|||
|
|
|
|||
|
|
long lCount = 0; // 只计算有效记录
|
|||
|
|
for (MoveFirst(); !IsEOF(); MoveNext())
|
|||
|
|
lCount ++;
|
|||
|
|
return lCount;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
long DbfTable::GetPosition()
|
|||
|
|
{
|
|||
|
|
long lPosition = GetAbsolutePosition();
|
|||
|
|
return lPosition;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::IsEOF()
|
|||
|
|
{
|
|||
|
|
BOOL bRet = CDBFRecordset::IsEOF();
|
|||
|
|
return bRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::IsBOF()
|
|||
|
|
{
|
|||
|
|
BOOL bRet = CDBFRecordset::IsBOF();
|
|||
|
|
return bRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::IsDeleted()
|
|||
|
|
{
|
|||
|
|
BOOL bRet = CDBFRecordset::IsDeleted();
|
|||
|
|
return bRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DbfTable::AppendBegin()
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::AddNew();
|
|||
|
|
m_bIsAdd = true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DbfTable::AppendEnd()
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::Update();
|
|||
|
|
m_bIsAdd = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DbfTable::Close()
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::Close();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DbfTable::Delete()
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::Delete();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
BOOL DbfTable::Pack()
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::Edit();
|
|||
|
|
CDBFRecordset::Update();
|
|||
|
|
return TRUE;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MoveFirst(int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
int nRet = 1;
|
|||
|
|
CDBFRecordset::MoveFirst();
|
|||
|
|
if (IsDeleted() && bSkipDeleted)
|
|||
|
|
nRet = MoveNext(bSkipDeleted);
|
|||
|
|
return nRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MoveLast(int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
int nRet = 1;
|
|||
|
|
CDBFRecordset::MoveFirst();
|
|||
|
|
if (IsDeleted() && bSkipDeleted)
|
|||
|
|
nRet = MovePrev(bSkipDeleted);
|
|||
|
|
return nRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MoveNext(int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
while (1)
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::MoveNext();
|
|||
|
|
if (IsEOF() || !bSkipDeleted)
|
|||
|
|
break;
|
|||
|
|
if (!IsDeleted())
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return (!IsEOF());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MovePrev(int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
while(1)
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::MovePrev();
|
|||
|
|
if (IsBOF() || !bSkipDeleted)
|
|||
|
|
break;
|
|||
|
|
if (!IsDeleted())
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return (!IsBOF());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DbfTable::Move(long offset, int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
if (offset)
|
|||
|
|
{
|
|||
|
|
long nStep = offset/abs(offset);
|
|||
|
|
if (IsBOF() && offset>0)
|
|||
|
|
{
|
|||
|
|
MoveFirst(bSkipDeleted);
|
|||
|
|
offset--;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (IsEOF() && offset<0)
|
|||
|
|
{
|
|||
|
|
MoveLast(bSkipDeleted);
|
|||
|
|
offset++;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (long i=offset; i!=0L; i-=nStep)
|
|||
|
|
{
|
|||
|
|
if (nStep > 0)
|
|||
|
|
MoveNext(bSkipDeleted);
|
|||
|
|
else
|
|||
|
|
MovePrev(bSkipDeleted);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MoveTo(long nRecNo)
|
|||
|
|
{
|
|||
|
|
CDBFRecordset::Move(nRecNo);
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MoveTo(const TCHAR *szKey, const TCHAR *szValue, int nMethod,
|
|||
|
|
int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
for (MoveFirst(bSkipDeleted); !IsEOF(); MoveNext(bSkipDeleted))
|
|||
|
|
{
|
|||
|
|
CString sValue;
|
|||
|
|
GET_FIELD(this, szKey, sValue);
|
|||
|
|
|
|||
|
|
int bEqual = 0;
|
|||
|
|
if (nMethod == CMP_SENSITIVE)
|
|||
|
|
bEqual = (_tcscmp(szValue, sValue)==0);
|
|||
|
|
else
|
|||
|
|
bEqual = (_tcsicmp(szValue, sValue)==0);
|
|||
|
|
if (bEqual)
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MoveFirst(const TCHAR *szKey, const TCHAR *szValue, int nMethod,
|
|||
|
|
int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
return MoveTo(szKey, szValue, nMethod, bSkipDeleted);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int DbfTable::MoveNext(const TCHAR *szKey, const TCHAR *szValue, int nMethod,
|
|||
|
|
int bSkipDeleted)
|
|||
|
|
{
|
|||
|
|
for (MoveNext(bSkipDeleted); !IsEOF(); MoveNext(bSkipDeleted))
|
|||
|
|
{
|
|||
|
|
CString sValue;
|
|||
|
|
GET_FIELD(this, szKey, sValue);
|
|||
|
|
|
|||
|
|
int bEqual = 0;
|
|||
|
|
if (nMethod == CMP_SENSITIVE)
|
|||
|
|
bEqual = (_tcscmp(szValue, sValue)==0);
|
|||
|
|
else
|
|||
|
|
bEqual = (_tcsicmp(szValue, sValue)==0);
|
|||
|
|
if (bEqual)
|
|||
|
|
return 1;
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DbfTable::EditMode()
|
|||
|
|
{
|
|||
|
|
if (!m_bIsAdd)
|
|||
|
|
Edit();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DbfTable::EditUpdate()
|
|||
|
|
{
|
|||
|
|
if (!m_bIsAdd)
|
|||
|
|
Update();
|
|||
|
|
}
|
|||
|
|
/////////////////////////////////////////////////////////////////
|
|||
|
|
// FieldInfo -- Field Class
|
|||
|
|
FieldInfo::FieldInfo(const TCHAR *n, int t, int l, int d)
|
|||
|
|
{
|
|||
|
|
InitClear();
|
|||
|
|
m_strName = n;
|
|||
|
|
m_chType = t;
|
|||
|
|
m_nLen = l;
|
|||
|
|
m_nDec = d;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldInfo & FieldInfo::operator = (const FieldInfo &src)
|
|||
|
|
{
|
|||
|
|
m_strName = src.m_strName;
|
|||
|
|
m_chType = src.m_chType;
|
|||
|
|
m_nLen = src.m_nLen;
|
|||
|
|
m_nDec = src.m_nDec;
|
|||
|
|
return *this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void FieldInfo::InitClear()
|
|||
|
|
{
|
|||
|
|
m_strName = _T("");
|
|||
|
|
m_chType = _T('\0');
|
|||
|
|
m_nLen = 0;
|
|||
|
|
m_nDec = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void FieldInfo::ReleaseArray(FieldInfo *p)
|
|||
|
|
{
|
|||
|
|
if (p != NULL)
|
|||
|
|
{
|
|||
|
|
delete p;
|
|||
|
|
p = NULL;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
///////////////////////////////////////////////
|
|||
|
|
// FieldContent -- FieldContent Class
|
|||
|
|
CString FieldContent::csValue = _T("");
|
|||
|
|
|
|||
|
|
TCHAR FieldContent::GetFieldType() const
|
|||
|
|
{
|
|||
|
|
return field_type;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int FieldContent::CompareTo(const FieldContent &otherOne) const
|
|||
|
|
{
|
|||
|
|
if (GetFieldType() != otherOne.GetFieldType())
|
|||
|
|
return 0;
|
|||
|
|
|
|||
|
|
TCHAR cType = GetFieldType();
|
|||
|
|
|
|||
|
|
if (cType == FLD_TYPE_NUMERIC)
|
|||
|
|
{
|
|||
|
|
if (len_info.num_size.dec == _T('0')) // int
|
|||
|
|
{
|
|||
|
|
int n1 = *this,
|
|||
|
|
n2 = otherOne;
|
|||
|
|
if (n1 > n2)
|
|||
|
|
return 1;
|
|||
|
|
else if (n1 < n2)
|
|||
|
|
return -1;
|
|||
|
|
else
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
else // double
|
|||
|
|
{
|
|||
|
|
double n1 = *this,
|
|||
|
|
n2 = otherOne;
|
|||
|
|
if (n1 > n2)
|
|||
|
|
return 1;
|
|||
|
|
else if (n1 < n2)
|
|||
|
|
return -1;
|
|||
|
|
else
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
else if (cType==FLD_TYPE_CHARACTER || cType==FLD_TYPE_DATE || cType==FLD_TYPE_LOGICAL) // string、date、bool
|
|||
|
|
{
|
|||
|
|
const TCHAR *s1 = *this,
|
|||
|
|
*s2 = otherOne;
|
|||
|
|
return _tcscmp(s1, s2);
|
|||
|
|
}
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent::operator int () const
|
|||
|
|
{
|
|||
|
|
return _ttoi(csValue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent::operator double () const
|
|||
|
|
{
|
|||
|
|
#if ADS == 15
|
|||
|
|
return atof(csValue);
|
|||
|
|
#else
|
|||
|
|
return _tstof(csValue);
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent::operator float () const
|
|||
|
|
{
|
|||
|
|
#if ADS == 15
|
|||
|
|
double dValue = atof(csValue);
|
|||
|
|
#else
|
|||
|
|
double dValue = _tstof(csValue);
|
|||
|
|
#endif
|
|||
|
|
return (float)dValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent::operator const TCHAR * () const
|
|||
|
|
{
|
|||
|
|
return (const TCHAR *)csValue;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent & FieldContent::operator = (int i)
|
|||
|
|
{
|
|||
|
|
csValue.Format(_T("%d"), i);
|
|||
|
|
return *this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent & FieldContent::operator = (double d)
|
|||
|
|
{
|
|||
|
|
csValue.Format(_T("%f"), d);
|
|||
|
|
return *this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent & FieldContent::operator = (const TCHAR *str)
|
|||
|
|
{
|
|||
|
|
csValue = str;
|
|||
|
|
return *this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#ifdef __AFXDISP_H__
|
|||
|
|
// 能正确转换的类型: int, double, string, date
|
|||
|
|
COleVariant FieldContent::AsVariant() const
|
|||
|
|
{
|
|||
|
|
COleVariant res;
|
|||
|
|
|
|||
|
|
TCHAR cType = GetFieldType();
|
|||
|
|
|
|||
|
|
if (cType == FLD_TYPE_NUMERIC) // int、double
|
|||
|
|
{
|
|||
|
|
if (len_info.num_size.dec == _T('0')) // int
|
|||
|
|
{
|
|||
|
|
res = (long)_ttoi(csValue);
|
|||
|
|
}
|
|||
|
|
else // double
|
|||
|
|
{
|
|||
|
|
#if ADS == 15
|
|||
|
|
res = atof(csValue);
|
|||
|
|
#else
|
|||
|
|
res = _tstof(csValue);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else if (cType == FLD_TYPE_CHARACTER) // string
|
|||
|
|
{
|
|||
|
|
const TCHAR *s1 = *this;
|
|||
|
|
res = s1;
|
|||
|
|
}
|
|||
|
|
else if (cType == FLD_TYPE_LOGICAL) // int
|
|||
|
|
{
|
|||
|
|
res = (long)_ttoi(csValue);
|
|||
|
|
}
|
|||
|
|
return res;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FieldContent & FieldContent::operator = (const COleVariant &src)
|
|||
|
|
{
|
|||
|
|
int nOleType = V_VT(&src);
|
|||
|
|
switch(nOleType)
|
|||
|
|
{
|
|||
|
|
case VT_BSTR:
|
|||
|
|
{
|
|||
|
|
CString cs = V_BSTR(&src);
|
|||
|
|
const TCHAR *sz = cs;
|
|||
|
|
*this = sz;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case VT_DATE:
|
|||
|
|
{
|
|||
|
|
COleDateTime oleDate = V_DATE(&src);
|
|||
|
|
int nYear = oleDate.GetYear(),
|
|||
|
|
nMonth = oleDate.GetMonth(),
|
|||
|
|
nDay = oleDate.GetDay();
|
|||
|
|
long nDate = nYear*10000 + nMonth*100 + nDay;
|
|||
|
|
|
|||
|
|
CString sDate;
|
|||
|
|
sDate.Format(_T("%ld"), nDate);
|
|||
|
|
*this = (const TCHAR *)sDate;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case VT_I4:
|
|||
|
|
{
|
|||
|
|
long n1 = V_I4(&src);
|
|||
|
|
*this = (int)n1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case VT_I2:
|
|||
|
|
{
|
|||
|
|
short n1 = V_I2(&src);
|
|||
|
|
*this = (int)n1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case VT_R8:
|
|||
|
|
{
|
|||
|
|
double n1 = V_R8(&src);
|
|||
|
|
*this = n1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
case VT_R4:
|
|||
|
|
{
|
|||
|
|
float n1 = V_R4(&src);
|
|||
|
|
*this = (double)n1;
|
|||
|
|
}
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
return *this;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template <class K>
|
|||
|
|
inline int Compare(K n1, K n2)
|
|||
|
|
{
|
|||
|
|
if(n1>n2) return 1;
|
|||
|
|
else if(n1<n2) return -1;
|
|||
|
|
else return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int TDBFUTILITY_IMPEXP CompareVariant(const COleVariant &var1, const COleVariant &var2)
|
|||
|
|
{
|
|||
|
|
int nType1 = V_VT(&var1),
|
|||
|
|
nType2 = V_VT(&var2);
|
|||
|
|
|
|||
|
|
int nRes = 0;
|
|||
|
|
if (nType1 == nType2)
|
|||
|
|
{
|
|||
|
|
if (nType1 == VT_BSTR)
|
|||
|
|
{
|
|||
|
|
CString s1 = V_BSTR(&var1);
|
|||
|
|
CString s2 = V_BSTR(&var2);
|
|||
|
|
nRes = _tcscmp(s1, s2);
|
|||
|
|
}
|
|||
|
|
else if (nType1 == VT_DATE)
|
|||
|
|
{
|
|||
|
|
double d1 = V_DATE(&var1),
|
|||
|
|
d2 = V_DATE(&var2);
|
|||
|
|
int nD1 = (int)d1,
|
|||
|
|
nD2 = (int)d2;
|
|||
|
|
nRes = Compare(nD1, nD2);
|
|||
|
|
}
|
|||
|
|
else if (nType1 == VT_I4)
|
|||
|
|
{
|
|||
|
|
long n1 = V_I4(&var1),
|
|||
|
|
n2 = V_I4(&var2);
|
|||
|
|
nRes = Compare(n1, n2);
|
|||
|
|
}
|
|||
|
|
else if (nType1 == VT_I2)
|
|||
|
|
{
|
|||
|
|
short n1 = V_I2(&var1),
|
|||
|
|
n2 = V_I2(&var2);
|
|||
|
|
nRes = Compare(n1, n2);
|
|||
|
|
}
|
|||
|
|
else if (nType1 == VT_R8)
|
|||
|
|
{
|
|||
|
|
double n1 = V_R8(&var1),
|
|||
|
|
n2 = V_R8(&var2);
|
|||
|
|
nRes = Compare(n1, n2);
|
|||
|
|
}
|
|||
|
|
else if (nType1 == VT_R4)
|
|||
|
|
{
|
|||
|
|
float n1 = V_R4(&var1),
|
|||
|
|
n2 = V_R4(&var2);
|
|||
|
|
nRes = Compare(n1, n2);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nRes;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 比较两行的大小
|
|||
|
|
int TDBFUTILITY_IMPEXP CompareBookmark(COleVariant *g_lstSortFieldContents,
|
|||
|
|
const long *bookmark1, const long *bookmark2)
|
|||
|
|
{
|
|||
|
|
COleVariant &var1 = g_lstSortFieldContents[(int)(*bookmark1)],
|
|||
|
|
&var2 = g_lstSortFieldContents[(int)(*bookmark2)];
|
|||
|
|
return CompareVariant(var1, var2);
|
|||
|
|
}
|
|||
|
|
#endif
|