globefun.cpp
来自「深入浅出Visual C++入门进阶与应用实例 随书光盘 作者 何志丹」· C++ 代码 · 共 448 行
CPP
448 行
#include "stdafx.h"
#include "GlobeFun.h"
//*********************************************************************
// 函数名称: CreateDBFile
// 函数说明:
// 入口参数:
// HDBType type --
// CString strFileName --
// 返回值 :
// bool --
// 作者 : 何志丹
// 时间 : 2005-01-05 14:21:34
//*********************************************************************
bool CreateDBFile(HDBType type,CString strFileName)
{
CString strResName,strResType;
strResName = pDBTemResID[type];
strResType = pUserResType[type];
//取得资源
HRSRC hmdbFile = ::FindResource(ghInstance, strResName, strResType);
HGLOBAL hRes = ::LoadResource(ghInstance, hmdbFile);
DWORD dwResSize = ::SizeofResource(ghInstance, hmdbFile);
//将资源写进文件
if(NULL == hRes)
return false;
UINT FAR* lpnRes = (UINT FAR*)::LockResource(hRes);
try
{
CFile f( strFileName, CFile::modeCreate | CFile::modeWrite );
f.WriteHuge(lpnRes, dwResSize);
f.Flush();
}
catch( CFileException* e )
{
// afxDump << "File could not be opened " << e->m_cause << "\n";
}
#ifndef WIN32
::UnlockResource(hRes);
#endif
::FreeResource(hRes);
return true;
}
bool GetCreateDBFTableSql(CString strTableName,HFIELDINFOS& fileinfos,CStringArray& arSql)
{
CString strSQLExcute,sFormat;
CString strTemp = "[" + strTableName + "]";
strSQLExcute.Format("create table [%s] (ID char(7) ",strTableName);
const int fieldCount = fileinfos.GetSize();
//通过判断字段的长度来确定字段的类型,大于250就设为备注类型,小于250就设为文本类型
for(int i=0;i<fieldCount ;i++)
{
if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
{
if (fileinfos[i]->sFieldName.GetLength() > 10)
sFormat.Format("%s Memo",fileinfos[i]->sFieldName.Left(10));
else
sFormat.Format("%s Memo",fileinfos[i]->sFieldName);
}
else//字段长度小于250就此字段设为文本类型
{
if (fileinfos[i]->sFieldName.GetLength() > 10)
sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName.Left(10),fileinfos[i]->iFieldLength);
else
sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);
}
sFormat = "," + sFormat;
if(strlen(strSQLExcute) + sFormat.GetLength() > nMaxSql)
{
break;
}
strSQLExcute += sFormat ;
}
strSQLExcute += ")";
arSql.Add(strSQLExcute);
const CString strAlterTableHead = "ALTER TABLE " + strTemp ;
while(i<fieldCount)
{
CString strAddField = strAlterTableHead ;
for( ;i<fieldCount ;i++)
{
if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
{
if (fileinfos[i]->sFieldName.GetLength() > 10)
sFormat.Format("%s Memo",fileinfos[i]->sFieldName.Left(10));
else
sFormat.Format("%s Memo",fileinfos[i]->sFieldName);
}
else//字段长度小于250就此字段设为文本类型
{
if (fileinfos[i]->sFieldName.GetLength() > 10)
sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName.Left(10),fileinfos[i]->iFieldLength);
else
sFormat.Format("%s Char(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);
}
if(strAlterTableHead == strAddField)//避免死循环
{
if(strlen(strAddField) + sFormat.GetLength() > nMaxSql)
{
AfxMessageBox("字段名太长");
i++;
break;
}
}
sFormat = " ADD COLUMN " + sFormat ;
if(strlen(strAddField) + sFormat.GetLength() > nMaxSql)
break;
strAddField += sFormat;
}
arSql.Add(strAddField);
}
return true;
}
bool GetCreateMDBTableSql(CString strTableName,HFIELDINFOS& fileinfos,CStringArray& arSql)
{
CString strFormat;
CString strSQL;
strSQL.Format("create table %s (",strTableName);
//通过判断字段的长度来确定字段的类型,大于250就设为备注类型,小于250就设为文本类型
const int nFieldCount = fileinfos.GetSize();
for(int i=0;i<nFieldCount ;i++)
{
if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
strFormat.Format("%s longchar",fileinfos[i]->sFieldName);
else//字段长度小于250就此字段设为文本类型
strFormat.Format("%s text(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);
if(strlen(strSQL) + strFormat.GetLength() > nMaxSql)
{
break;
}
if(0 != i)
strFormat = "," + strFormat;
strSQL = strSQL + strFormat ;
}
strSQL +=")";
arSql.Add(strSQL);
//把建表时没有建的列加上去
const CString strAlterTableHead = "ALTER TABLE " + strTableName + " ADD";
while(i < nFieldCount )
{
strSQL = strAlterTableHead ;
for( ;i < nFieldCount ;i++)
{
if (fileinfos[i]->iFieldLength>250)//字段长度大于250就此字段设为备注类型
strFormat.Format(" %s longchar",fileinfos[i]->sFieldName);
else//字段长度小于250就此字段设为文本类型
strFormat.Format(" %s text(%d)",fileinfos[i]->sFieldName,fileinfos[i]->iFieldLength);
if(strAlterTableHead == strSQL)//避免死循环
{
if(strlen(strSQL) + strFormat.GetLength() > nMaxSql)
{
AfxMessageBox("字段名太长");
i++;
break;
}
}
else
strFormat = "," + strFormat ;
if(strlen(strSQL) + strFormat.GetLength() > nMaxSql)
break;
strSQL += strFormat;
}
arSql.Add(strSQL);
}
return true;
}
bool GetCreateTableSql(enum HDBType type,CString strTableName,HFIELDINFOS& fileinfos,CStringArray& arSql)
{
switch(type)
{
case HDBType_ACCESS: GetCreateMDBTableSql(strTableName,fileinfos,arSql);
break;
case HDBType_FOXPRO: GetCreateDBFTableSql(strTableName,fileinfos,arSql);
break;
default: return false;
}
return true;
}
bool GetDeleteTableSql(CString strTableName,CString& strSQL)
{
strSQL.Format("drop table %s",strTableName);
return true;
}
enum HDBType GetDBTypeByFileName(CString strFileName)
{
if(strFileName.GetLength() < 4)
return HDBType_UNKNOWN;
CString strFileExt = strFileName.Right(4);
if(".mdb" == strFileExt)
return HDBType_ACCESS;
else if(".xls" == strFileExt)
return HDBType_EXCEL;
else if(".dbf" == strFileExt)
return HDBType_FOXPRO;
return HDBType_UNKNOWN;
};
bool GetTables(CString strDSN,CStringArray & strTableNames)
{
strDSN = "DSN=" + strDSN;
CDatabase database;
int ret= -1;
HSTMT hStmt;
UCHAR szName[256];
SDWORD cbName;
// 缺省取用户表、参数选择视图、系统表
CString type = "'TABLE'";
// 通过ODBC打开数据库
try
{
if( !database.OpenEx(strDSN) )
return false;
}
catch(CDBException * e)
{
AfxMessageBox(e->m_strError);
return false;
}
// 分配Statement句柄
//SQLAllocStmt (database.m_hdbc,&hStmt);
SQLAllocHandle (SQL_HANDLE_STMT,database.m_hdbc,&hStmt);
// 获取表信息(返回一个数据表)
ret = SQLTables(hStmt,
NULL,SQL_NTS,
NULL,SQL_NTS,
NULL,SQL_NTS,
(unsigned char *)type.GetBuffer(0),SQL_NTS);
if(ret == SQL_ERROR)
{
SQLFreeStmt(hStmt,SQL_CLOSE);
database.Close();
if(ret == SQL_INVALID_HANDLE )
{
AfxMessageBox("Invalid handle");
return false;
}
AfxMessageBox("Database Could Not be Open");
return false;
}
while(1)
{
// 取数据到缓冲区
ret = SQLFetch(hStmt);
if(ret == SQL_NO_DATA_FOUND)
break;
// 取某一列数据(第3列为表名,其他还有表属性、数据库名等)
ret = SQLGetData(hStmt, 3, SQL_C_CHAR, szName, TABLE_NAME_LENGTH, &cbName);
strTableNames.Add(szName);
}
// 释放句柄
SQLFreeStmt(hStmt,SQL_CLOSE);
database.Close();
return true;
}
int IsDirectoryOrFile(CString strFileName)
{
strFileName.TrimLeft();
strFileName.TrimRight();
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile(strFileName,&fd);
::FindClose(hFind);
//不存在同名的文件或文件夹
if (hFind == INVALID_HANDLE_VALUE)
{
return 0 ;
}
//判断是否为目录
else if (fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
return 2 ;
}
else//判断为文件
{
return 1;
}
}
bool IsLegalName(CString strFileName,CString& strErr)
{
strErr.Empty();
int nPos1 = strFileName.ReverseFind('\\');
int nPos2 = strFileName.ReverseFind(':');
int nPos = max(nPos1,nPos2);
if(-1 != nPos)//检查文件夹是否存在,不存在就新建
{
CString strPath = strFileName.Left(nPos);
const int nType = IsDirectoryOrFile(strPath) ;
if(1 == nType)//存在同名的文件,无法新建文件夹
{
strErr.Format("存在与〖%s〗同名的文件,无法新建文件夹",strPath);
return 0;
}
else if( 0 == nType)
{
if(IDYES != AfxMessageBox("文件夹不存在,创建此文件夹吗?",MB_YESNO))
{
strErr.Format("文件夹〖%s〗不存在",strPath);
return 0 ;
}
if(!CreateDirectory(strPath,NULL))
{
strErr.Format("文件夹〖%s〗不存在",strPath);
return 0 ;
}
}
strFileName = strFileName.Mid(nPos + 1 );
}
//文件名为空
if(strFileName.IsEmpty())
{
strErr = "文件名不能为空";
return false;
}
//只允许汉字字母数字及下划线
const int nLength = strFileName.GetLength();
for(int i = 0 ; i < nLength ; i ++ )
{
char ch = strFileName[i];
if(ch & 0x80)//半个汉字
{
i++;
continue;
}
if(ch >= 'A' && ch <='Z')//大写字母
continue;
if(ch >='a' && ch <= 'z')//小写字母
continue;
if(ch >= '0' && ch <= '9')//数字
continue;
if('_' == ch)//下划线
continue;
CString strSpeChar = ".";//. 都可以
if(-1 != strSpeChar.Find(ch))
continue;
strErr.Format("文件名中包含非法字符%c",ch);
return false;
}
char ch = strFileName[0] ;
if(ch >= '0' && ch <= '9')//不能以数字开头
{
strErr = "文件名不能以数字开头";
return false;
}
return true;
}
int FindStrFromStrArr(const CStringArray& arDest,CString strSour)
{
for(int i = arDest.GetSize()-1 ; i >= 0 ; i-- )
{
if(strSour == arDest[i])
return i;
}
return i;
}
static CString GetNewColName(HFIELDINFOS& tFieldInfos)
{
const int nColCount = tFieldInfos.GetSize();
for(int nPostFix = 1 ; nPostFix < 10000/*避免死循环*/; nPostFix++)
{
CString strNewColName;
strNewColName.Format("_col%d" , nPostFix);
for(int i = 0 ; i < nColCount ; i++ )
{
if(strNewColName == tFieldInfos[i]->sFieldName)
break;
}
if(nColCount == i)
return strNewColName;
}
return "";
}
void DoIllegalColName(HDBType type,HFIELDINFOS& tFieldInfos)
{
const nColCount = tFieldInfos.GetSize();
for(int i = 0 ; i < nColCount ; i++ )
{
if(HDBType_FOXPRO == type)
{
if(tFieldInfos[i]->sFieldName.GetLength() > 10)
{
tFieldInfos[i]->sFieldName = GetNewColName(tFieldInfos);
continue;
}
}
else
{
}
//看是否有重名的列
for(int j = 0 ; j < i ; j++ )
{
CString str1,str2;
str1 = tFieldInfos[i]->sFieldName;
str2 = tFieldInfos[j]->sFieldName;
if(tFieldInfos[i]->sFieldName == tFieldInfos[j]->sFieldName)
{
tFieldInfos[i]->sFieldName = GetNewColName(tFieldInfos);
break;
}
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?