以下是引用mywisdom88在2018-3-24 10:50:34的发言:
好,刚测试一下,10W记录, I5 3470,8G,WIN7 64,
在有备注字段时,每页1W记录,花45秒
在没备注字段时,每页1W记录,花15秒
能否在有备注字段的时候,优化。。。
写了个类似 VFP.DataToClip() 的_MemToClipCol函数来处理,速度好象较快。
复制数据格式:
列块复制:
     每个单元的内容用双引号表示("单元"),不同单元用回车换行符(0h0D0A)分隔。
备注字段内容包含的双引号“"”要替换成“""”
**
** DBF转EXCEL
**
CREATE CURSOR 测试表 (编号 C(10), 入库单号 C(7), 入库日期 D, 物料名称 C(20), 数量 I,;
    单价 N(14,2), 单位 C(8), 规格 C(30), 付款 L, 日期时间 T, 备注 M)
FOR i=1 To 101
    INSERT INTO 测试表 VALUES (PADL(i,10,"0"), 'C'+PADL(i,6,'0'), {^2018-03-01}+INT(RAND()*10),;
         '物料'+PADL(i,3,'0'), INT(RAND()*1000), INT(RAND()*100)*1.00, '个', '',;
         IIF(i%2=0,.t.,.f.), DATETIME(), '备注_"'+TRANSFORM(i)+'"'+0h0D0A+"_"+TRANSFORM(i)+0h0D0A)
ENDFOR
AFIELDS(aFieldInfo)
FOR i=1 TO ALEN(aFieldInfo,1)
    aFieldInfo[i,7] = aFieldInfo[i,1]    && 可自定义,用作栏目名
    aFieldInfo[i,8] = ICASE(;            && 数据格式
        aFieldInfo[i,2]=="I", '##0;[=0]""',;              && 整数格式
        INLIST(aFieldInfo[i,2],"B","N","F"), '#,##0.'+REPLICATE("0",aFieldInfo[i,4])+';[=0]""',; && 小数格式
        INLIST(aFieldInfo[i,2],"C","V","W","M"), '@',;    && 文本格式
        aFieldInfo[i,2]=="D", 'yyyy-m-d',;                && 日期格式
        aFieldInfo[i,2]=="T", 'yyyy-m-d hh:mm:ss',;       && 日期时间格式
        'G/通用格式')    
ENDFOR
t1=SECONDS()
_DBF_EXCEL("C:\TEMP\test.xls", "测试表", @aFieldInfo, 20, 4, 1, "数 据 导 出 表", 2)
? SECONDS()-t1
RETURN
**
** DBF转EXCEL
** _DBF_EXCEL(cOutFile, cAlias, aFieldInfo, nPageRows, nStartRow, nStartCol, cTitle, nTitleRow)
**     cOutFile    输出EXCEL文件名
**     cAlias      DBF表工作区别名
**     aFieldInfo  字段信息,用AFIELDS()获取,可自定义栏目名、数据格式等。
**     nPageRows   每页数据行数
**     nStartRow   开始行
**     nStartCol   开始列
**     cTitle      标题
**     nTitleRow   标题行
**
FUNCTION _DBF_EXCEL(cOutFile, cAlias, aFieldInfo, nPageRows, nStartRow, nStartCol, cTitle, nTitleRow)
    LOCAL oExcel
    oExcel = CREATEOBJECT("Excel.Application")   && 创建电子表格
    oExcel.DisplayAlerts = .F.                   && 关闭 Excle 提示对话框
    oExcel.WorkBooks.Add                         && 创建工作簿
        * 如果页数多了,删除多余的
    LOCAL nPageCount
    nPageCount = CEILING(RECCOUNT(cAlias)/nPageRows)    && 页数
    DO WHILE oExcel.Worksheets.Count > nPageCount
        oExcel.Sheets[oExcel.Worksheets.Count].Select
        oExcel.ActiveWindow.SelectedSheets.Delete
    ENDDO
        * 如果页数不够,添加
    FOR i=oExcel.Worksheets.Count+1 TO nPageCount
        oExcel.Sheets.Add
    ENDFOR
        * 页名
    FOR i=1 TO nPageCount
        oExcel.Sheets[i].Name = "第"+TRANSFORM(i)+"页"
    ENDFOR
        * 利用剪贴板把DBF内容复制到EXCEL表
    SELECT (cAlias)
    LOCAL nRow, nCol, nEndRow, nEndCol
    nEndRow = nStartRow + nPageRows                && 结束行,第1行为栏目行
    nEndCol = nStartCol + ALEN(aFieldInfo,1) - 1   && 结束列
    FOR i=1 TO nPageCount    && 处理各页
        WITH oExcel
                * 打开页
            .Sheets[i].Activate
                * 标题格式设置
            .Range(.Cells(nTitleRow,nStartCol), .Cells(nTitleRow,nEndCol)).Select
            .Selection.NumberFormatLocal = "@"        && 文本格式
            .Selection.HorizontalAlignment = -4108    && 居中 xlCenter
            .Selection.VerticalAlignment = -4108
            .Selection.Merge                          && 合并单元格  
                * 栏目行格式设置
            .Range(.Cells(nStartRow,nStartCol), .Cells(nStartRow,nEndCol)).Select
            .Selection.NumberFormatLocal = "@"
            .Selection.HorizontalAlignment = -4108    && 居中 xlCenter
            .Selection.VerticalAlignment = -4108
                * 各列数据格式设置
            FOR nCol=nStartCol TO nEndCol
                .Range(.Cells(nStartRow+1,nCol), .Cells(nEndRow,nCol)).Select
                .Selection.NumberFormatLocal = aFieldInfo[nCol-nStartCol+1, 8]
            ENDFOR
            .Cells(nTitleRow,nStartCol).Value = cTitle    && 标题
            GO (i-1)*nPageRows + 1                   && 每页第一行的数据记录位置
            _VFP.DataToClip(cAlias, nPageRows, 3)    && 复制DBF记录
            _CLIPTEXT = STRTRAN(_CLIPTEXT, '"', '"')
            .Range(.Cells(nStartRow,nStartCol), .Cells(nEndRow,nEndCol)).Select
            .ActiveSheet.Paste                       && 粘贴到EXCEL
            FOR nCol=nStartCol TO nEndCol            && 用自定义栏目名
                .Cells(nStartRow,nCol).Value = ALLTRIM(aFieldInfo[nCol-nStartCol+1, 7])
            ENDFOR
            FOR nCol=nStartCol TO nEndCol    && 处理备注字段
                IF aFieldInfo[nCol-nStartCol+1, 2]=="M"
                    GO (i-1)*nPageRows + 1
                        * 速度较快
                    _MemToClipCol(cAlias, aFieldInfo[nCol-nStartCol+1, 1], nPageRows)
                    .Range(.Cells(nStartRow+1,nCol), .Cells(nEndRow,nCol)).Select
                    .ActiveSheet.Paste        && 粘贴到EXCEL
**                            * 速度较慢
**                        nRow = nStartRow+1
**                        SCAN NEXT nPageRows
**                            .Cells(nRow,nCol).Value = EVALUATE(aFieldInfo[nCol-nStartCol+1, 1])
**                            nRow = nRow + 1
**                        ENDSCAN
                ENDIF
            ENDFOR
            .Cells(1,1).Select
            .Columns.AutoFit    && 自动适应行列宽
            .Rows.AutoFit
        ENDWITH
    ENDFOR
    oExcel.Sheets[1].Activate                    && 打开第1页
**            * 调试观察时用
**        oExcel.ActiveWindow.WindowState = 2          && 最大化窗口
**        oExcel.Caption = cTitle                      && Excel标题
**        oExcel.Visible = .T.
**        MESSAGEBOX("中断预览")
    
        * 保存关闭
    oExcel.ActiveWorkbook.SaveAs(cOutFile, -4143)    && 另存, 常规工作簿格式,xlNormal:-4143
    oExcel.Workbooks.Close                           && 关闭工作簿
    oExcel.Quit                                      && 关闭Excel
    RELEASE oExcel                                   && 释放oExcel
ENDFUNC
FUNCTION _MemToClipCol(cAlias, cFieldName, nRecord)
    LOCAL cMem
    cMem = ""
    SELECT (cAlias)
    IF !EOF()
        cMem = '"' + STRTRAN(EVALUATE(cFieldName), '"', '""') + '"'
        SKIP
        SCAN NEXT nRecord-1
            cMem = cMem + 0h0D0A + '"' + STRTRAN(EVALUATE(cFieldName), '"', '""') + '"'
        ENDSCAN
    ENDIF
    _CLIPTEXT = cMem    
ENDFUNC
[此贴子已经被作者于2018-3-24 23:31编辑过]