delphi用文件流从SQL导入数据到excel,请高手帮忙分析下代码
我用delphi7,用了两个数据库组件:adoconnection和adotable已连好数据库和表,请大大们帮们分析下。我已经分析好几天都没怎么有头绪。运行是可以的。但已点击按钮就报错。也没有生成我要的ECCEL表,刚接触文件流。
- Delphi(Pascal) code
unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, ADODB,comobj, StdCtrls, Grids, DBGrids;type TForm1 = class(TForm) Button1: TButton; Label1: TLabel; DBGrid1: TDBGrid; ADOConnection1: TADOConnection; ADOTable1: TADOTable; DataSource1: TDataSource; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;var Form1: TForm1; arXlsBegin : array[0..5] of Word = ($809,8,0,$10,0,0); arXlsEnd : array[0..1] of Word = ($0A,00); arXlsString : array[0..5] of Word = ($204,0,0,0,0,0); arXlsNumber : array[0..4] of Word = ($203,14,0,0,0); arXlsInteger : array[0..4] of Word = ($27E,10,0,0,0); arXlsBlank : array[0..4] of Word = ($201,6,0,0,$17); Procedure ExportExcelFile(FileName : string;bWriteTitle : Boolean);implementation{$R *.dfm}//ㄏノゅンProcedure ExportExcelFile(FileName : string;bWriteTitle : Boolean);var i,j :integer; Col,Row : word; ABookMark :TBookMark; aFileStream :TFileStream; procedure IncColRow;//[C begin if Col = form1.ADOTable1.FieldCount -1 then begin Inc(Row); Col := 0; end else begin Inc(Col); end; end; procedure WriteStringCell(AValue : string); //r才 var L: Word; begin L := Length(AValue); arXlsString[1] := 8 + L; arXlsString[2] := Row; arXlsString[3] := Col; arXlsString[5] := L; aFileStream.WriteBuffer(arXlsString,Sizeof(arXlsString)); aFileStream.WriteBuffer(Pointer(AValue)^,L); IncColRow; end; procedure WriteIntegerCell(AValue : integer);//俱 var V: Integer; begin arXlsString[2] := Row; arXlsString[3] := Col; aFileStream.WriteBuffer(arXlsInteger,Sizeof(arXlsInteger)); V := (AValue shl 2) or 2; aFileStream.WriteBuffer(V,4); IncColRow; end; procedure WriteFloatCell(AValue : double);// begin arXlsString[2] := Row; arXlsString[3] := Col; aFileStream.WriteBuffer(arXlsNumber,Sizeof(arXlsNumber)); aFileStream.WriteBuffer(AValue,8); IncColRow; end; begin if FileExists(FileName) then begin aFileStream := TFileStream.Create(FileName,fmCreate); end; try //ゅン aFileStream.WriteBuffer(arXlsBegin,SizeOf(arXlsBegin));//C Col := 0; Row := 0; if bWriteTitle then begin for i:= 0 to form1.ADOTable1.FieldCount-1 do begin WriteStringCell(form1.ADOTable1.Fields[i].FieldName); //栋い壅u end; end; form1.ADOTable1.DisableControls; ABookMark := form1.ADOTable1.GetBookmark; form1.ADOTable1.First; while not form1.ADOTable1.Eof do begin for i:= 0 to form1.ADOTable1.FieldCount-1 do begin case form1.ADOTable1.Fields[i].DataType of ftSmallint,ftInteger,ftWord,ftAutoInc,ftBytes : WriteIntegerCell(form1.ADOTable1.Fields[i].AsInteger); ftFloat,ftCurrency,ftBCD : WriteFloatCell(form1.ADOTable1.Fields[i].AsFloat) else WriteStringCell(form1.ADOTable1.Fields[i].AsString); end; end; form1.ADOTable1.Next; //application.ProcessMessages; end; //ゅンЮ aFileStream.WriteBuffer(arXlsEnd,SizeOf(arXlsEnd)); if form1.ADOTable1.BookmarkValid(ABookMark) then begin form1.ADOTable1.GotoBookmark(ABookMark); end; Finally aFileStream.Free; form1.ADOTable1.EnableControls; end;end;procedure TForm1.Button1Click(Sender: TObject);var t1,t2 : Int64;begin label1.Caption := '0'; t1 := GetTickCount; adotable1.Open; ExportExcelFile('d:\jiaban.xls',true); adotable1.EnableControls; t2 := GetTickCount; label1.Caption := IntToStr(t2-t1);end;end.
[解决办法]
35 同步命令控制表 TO_PNP_SYN_TAB_SIZE 351 CCU_NULL_LONG 352
TOPNP_SYNC_CB_T 353
UINT32 InitToPnPSynTxTab( VOID ){UINT32 i = 0;g_stSynTxTab.ucTabSize = 351;341 = 352;
g_stSynTxTab.pstTxTab = (353*)CCU_MemAlloc(CCU_MEM_INFO, CCU_MEM_PT_NO, 351 * sizeof(353));
CHECK_PARA1_NULL_RN(g_stSynTxTab.pstTxTab, CCU_ERR_MPI_MEMORY_OUTOFSPACE);
for ( i = 0 ; i < 351 ; i++ ){ 342.ucIsUsed = CCU_FALSE; 342.ulWaitTimer = 0;
342.ulTimeCnt = 0;342.ucCmd = 332;342.ulResId = 352;342.ulSynId = 352;342.ulLen = 0; }221;}
36 .. 扫描异步发送控制表 ucChanNum 361 ucChanTemp 362
VOID ScanToPnPTxTab( UINT8 361 ){UINT32 i = 0;UINT8 362 = 332;CHECK_PARA1_NULL(301);
for ( i = 0 ; i < g_stSendToPnPTxTab.ucTabSize; i++ )
{ /* 这里区分通道是为了防止每个通道线程调用本函数时都加一次记时器 */
362 = Get485ChanNo(301[i].ulResId);if ( (CCU_TRUE == 301[i].ucIsUsed) &&(362 == 361 )){
301[i].ulTimeCnt++;if ( 301[i].ulTimeCnt >= 301[i].ulWaitTimer){FreeToPnPTxCB((UINT8)i);}}}return;}
37 定时扫描发送控制表处理
VOID ScanTxTab(UINT8 361 ){/* 扫描异步发送控制表 */ScanToPnPTxTab(361);return;}
38 获取命令执行结果 g_stSynTxTab.pstTxTab[ucIndex] 381
UINT32 GetCompleteCodeFromPnPSynTab(UINT32 ulResId, UINT8 ucIndex, UINT8 ucCmd,
UINT32 *pucCompleteCode, UINT8 *pucBuf, UINT32 *pulLen){CHECK;
if ( ucIndex >= 351){return 11;}/* 如果命令不匹配,返回 */if ( (381.ulResId != ulResId)
||(381.ucCmd != ucCmd)||(CCU_TRUE != 381.ucIsUsed)){return CCU_ERR_MPI_UNMATCH_RESP;}
*pucCompleteCode = 381.ulComplete;if ( 381.ulLen > *pulLen){return CCU_485_ERR_LENGTH_OVERLOAD;
}*pulLen = 381.ulLen;CCU_MemCpy(pucBuf, 381.pucData, (INT32)381.ulLen);221;}
39 命令域赋值 pstDestInfo 391 pstSrcInfo 392
VOID UpdateCmdInfo(PMANAGE485_CmdT 391, PCCU485_CFG_CmdT 392)
{ CHECK; 391->ucCmd = 392->ucCmd;391->ucDirType = 392->ucDirType;
391->uwlen = 392->uwlen;391->ucIsInitOk = CCU_FALSE;391->ucInitFailCnt = 0;
CCU_MemCpy(391->aucCmdData, 392->aucCmdData, MAX_485_DATA_LEN);return;}
40 ..解析EFUSE子类型 *penSubType 401 ucSubType 402 BOARD_SUBTYPE 403
UINT32 GetEfuseSubType(UINT8 *pucData, 403 401){UINT8 402 = 332;CHECK;402 = pucData[MIN_REG_DATA_LEN];
if ( 0x01 == 402 ){ 401 = EFULSE_PDU_TYPE;}else if ( 0x05 == 402 ){401 = EFULSE_IPDU_TYPE;
} else{401 = EFULSE_PDU_TYPE; /* 如果找不到子类型,默认为EFULSE,不影响注册 */}221;}
41 解析EMU子类型 PMU_UNKNOW_TYPE 411
UINT32 GetEMUSubType(UINT8 *pucData, 403 401){UINT8 402 = 332;CHECK;402 = pucData[1];if ( 0x01 == 402 )
{401 = EMU_NORMAL_TYPE;}else if ( 0x24 == 402 ){401 = EMU_EMUA_TYPE;}else{401 = 411; }221; }
42 .. 解析PMU子类型UINT32 GetPMUSubType(UINT8 *pucData, 403 401){UINT8 402 = 332;CHECK;
402 = pucData[MIN_REG_DATA_LEN - 1];if ( (0x01 == 402) || (0x02 == 402) ){401 = PMU_APM30_TYPE;}
else if ( 0x03 == 402){401 = PMU_OMB_TYPE;}else if ( 0x05 == 402){401 = PMU_SOLAR_TYPE;
}else{401 = PMU_APM30_TYPE; /* 如果找不到子类型,默认为APM30,不影响注册 */}221;}
[解决办法]
43获取部件子类型 enBoardType 431 pucData, &enSubType 432
UINT32 GetSubType(FILE_CABINET_TABLE enShelfType, BOARD_TYPE 431, UINT8 *pucData, UINT32 ulLen, 403 401)
{403 enSubType = 411;UINT32 ulRet = CCU_ERR;CHECK;
/* 目前只需对PMU做子类型区分处理,PMU目前只根据注册信息中设备类型
字节区分子类型 */if ( CCU_485_PMU_TYPE_C9 == 431 )
{ulRet = GetPMUSubType(432);}else if ( CCU_485_EFUSE_TYPE_CB == 431)
{ulRet = GetEfuseSubType(432);}else if ( CCU_485_EMU_TYPE_CF == 431 ){
ulRet = GetEMUSubType(432);}else{enSubType = 411;ulRet = CCU_OK;}401 = enSubType;452;}
44 ..获取部件类型 CCU_NULL_PTR 441 ucBoardType 442 ulRet = IsResIdRight(ulResId 443
CHECK_RET_OK_RN(ulRet, ulRet) 444 ulRet = GetChanNode(ulResId, &pstChan, &pstNode) 445
UINT32 GetBoardType(UINT32 ulResId, BOARD_TYPE *p431)
{UINT8 361 = 332;UINT8 ucAddr = 332;UINT32 ulRet = CCU_ERR;UINT8 442 = 332;
PCCU_CHAN_T pstChan = 441;PRS485_BOARD_T pstNode = 441;CHECK;443, &361, &ucAddr);444; 445;444;
/* 如果节点为空,直接返回,此处不该为空 */
CHECK;if (CCU_RESID == ulResId){*p431 = CCU_485_CCU_TYPE_CE;221; }
/* 如果注册消息长度为0,直接返回,此处不该为0 */CHECK_PARA_RTN_VALUE(pstNode->ulRegLen, 0, 11);
/* 部件类型存储在第一个字节 */442 = pstNode->ucRegInfo[0];
/* 校验部件类型的合法性 */if ( (CCU_485_PMU_TYPE_C9 != 442) &&(CCU_485_TCU_TYPE_CC != 442)
&&(CCU_485_FMU_TYPE_CA != 442)&&(CCU_485_EMU_TYPE_CF != 442)&&(CCU_485_EFUSE_TYPE_CB != 442)
&&(CCU_485_GATM_TYPE_B1 != 442)&&(CCU_485_ELOCK_TYPE_CD != 442)&&(CCU_485_CCU_TYPE_CE != 442))
{*p431 = CCU_485_INVALID_TYPE;return 11;}else{*p431 = (BOARD_TYPE)442;221;}}
45 执行485完整协议命令的API同步接口 FreeToPnPSynTxCB(ucIndex) 451 return ulRet 452
UINT32 Exec485ProtolCmd(UINT32 ulResId, UINT8 ucCmd, UINT8 *pucData, UINT32 ulLen)
{UINT8 ucIndex = 332;
UINT16 uwCmd = 323;UINT8 361 = 332;UINT8 ucAddr = 332;UINT32 ulRet = 352;
UINT32 ucCompleteCode = 352; PCCU_CHAN_T pstChan = 441;PRS485_BOARD_T pstNode = 441;
UINT8 aucBuf[MAX_485_DATA_LEN] = {0};UINT32 ulTempLen = MAX_485_DATA_LEN;
CHECK;443, &361, &ucAddr);444;445;444;/* 如果节点为空,直接返回,此处不该为空 */CHECK;
/* 添加发送控制表 */ulRet = AddToPnPSynTxTab(ulResId, ucCmd, &ucIndex, pucData, ulLen);
if ( CCU_OK != ulRet ){ 451;452;}uwCmd = (UINT16)(((UINT16)pstNode->431 << 8) + ucCmd);
/* 向pnp发送同步消息 */ulRet = SendAsyMsgToPnP(ulResId, uwCmd, (UINT16)ucIndex
, TO_PNP_SYNC_TYPE, pucData, ulLen);if ( CCU_OK != ulRet ){451;452;}
/* P同步信号量等待回应,此处不恒P,暂定2秒返回 */
if ( CCU_OK != ADA_SmP((INT32)381.ulSynId, CCU_5S_TICK) ){ 451;return CCU_ERR_MPI_SEM_TAKE_TIMEOUT;}
ulRet = GetCompleteCodeFromPnPSynTab(ulResId, ucIndex, ucCmd, &ucCompleteCode, aucBuf, &ulTempLen);
if ( CCU_OK != ulRet ){451;452;}/* 释放同步发送控制表 */451;
/* 此处今后还要丰富,因为有些命令应答字节非0时也表示命令执行成功 */return ucCompleteCode;}