vfp导出excel的方法探讨
方法一:
Use**.dbf
Copy To Excel333.Xls Type Xl5
方法二:
local myfield
yfilename=getfile("**.dbf")&&得到源表
myoleapp=createobject("excel.application") &&创建OLE对象
myoleapp.visible=.t.
myoleapp.workbooks.add
use 1.dbf &&myfilename
for i=1 to fcount()
myoleapp.cells(1,i).value=field(i)
endfor
scan
for i=1 to fcount()
myfield=fields(i)
myoleapp.cells(recno()+1,i).value=&myfield
endfor
endscan
myoleapp.quit
还有没有其他的方法!
[解决办法]
1、
_CLIPTEXT=''
SELECT bh,xm FROM h:\gzkd\jzg INTO CURSOR dd
SELECT dd
COPY TO dd1.txt sdf
_CLIPTEXT =FILETOSTR('dd1.txt')
2、
SELECT qq,bh,xmold,dwold,xfgzold,zfgzold,bfold,xm,dw,xfgz,zfgz,bf FROM r:\temp\qwe INTO CURSOR dd
_vfp.DataToClip('dd',,3)
ZX = CREATEOBJECT('excel.application',' ')
zx.ActiveSheet.Paste
[解决办法]
3
Set oConnection = CreateObject("adodb.connection")
Set dd = CreateObject("adodb.recordset")
With oConnection
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ThisWorkbook.FullName + ";Extended Properties='excel 8.0;HDR=YES;IMEX=1';Persist Security Info=False"
.Open
End With
dd.Open "select trim(订单号) as 订单号,count(*) as gs from [sheet1$] group by trim(订单号)", oConnection
"select * from (select trim(订单号) as 订单号,count(*) as gs from [sheet1$] group by trim(订单号)) where gs=1", oConnection
Sheets.Add
Sheets(1).Range("a1").CopyFromRecordset dd
[解决办法]
VFP与EXCEL的几种交互编程方法
一、EXECL驱动VFP
EXECL内置的VBA语言(Visual Basic For Application)为EXECL功能的扩展提供了便利的手段,用户可使用该语言直接驱动VFP完成数据检索等功能。
程序首先生成一个VFP对象,然后用VFP的DoCmd方法执行VFP摸索命令串,其摸索结果再借助于VFP的DateToClip方法拷贝至剪切板,最后VBA将其粘贴至工作表的正确位置。
Sub FoxTest()
Dim oFox As Object
Dim Slesson As String
Dim Scommand As String
Set oFox = CreateObject("VisualFoxPro.Application") '启动VFP,生成VFP对象
Sheets("查询").Select
Slesson = Range("课程名") '在名为“课程名”的单元格中得到欲查询的课程名称
Sheets.Add '产生新的工作表单
ActiveSheet.Name = Slesson '指定工作表单的名称与课程名称相同
Scommand = "SELECT 学号,语文,数学 FROM d:\vfp\学生成绩表 WHERE "+ Slesson + "<60 INTO CURSOR TEMP" '形成VFP查询命令串
oFox.DoCmd Scommand '执行VFP命令串
oFox.DataToClip "temp", , 3 '将搜索结果以文本方式拷贝至剪切板
Range("a1:a1").Select '指向拷贝目标区域左上角单元
ActiveSheet.Paste '粘贴搜索结果
End Sub
为便于使用,作者在EXECL中自制了一名为“搜索”的工具栏及一名为“开始搜索”的按钮,并将上述宏程序段与自制按钮相关联,按下此按钮即可运行程序并在EXCEL中得到要求的数据。
制作工具栏及按钮的方法如下:
1. 选“工具”/“自定义”菜单,出现自定义对话框;
2. 选择“工具栏”页框,然后按下“新建”按钮;
3. 在工具栏对话框中输入“搜索”作为新建工具栏的名称;
4. 选择“命令”页框,在“类别”列表中选“宏”,在“命令”列表中选“自定义按钮”并将其拖放至新建的“搜索”工具栏;
5. 按下“更新所选内容”按钮,首先在“命名”栏中填入按钮名称“开始搜索”,然后选择“指定宏”,在随后出现的“指定宏”列表中选择上述宏程序FoxTest()即可实现为该宏指定一个工具栏按钮。
二、VFP使用OLE功能驱动EXECL
OLE(Object Linking and Embedding)对象链接与嵌入,是WINDOWS应用程序间相互传递和共享数据的一种有效方法。VFP借助于OLE不仅可共享其它应用程序的数据,而且还能以对象方式直接控制其它应用程序的运行,从而进一步扩展VFP的功能。VFP支持直接在程序中创建、使用和控制OLE对象,实现OLE自动化。作为OLE客户VFP与作为OLE服务器的EXCEL具有良好的编程接口,下述程序段用OLE方式实现所要求的功能。
程序首先生成一个EXCEL的OLE对象OleApp以便对其进行操作,然后利用OLE功能从EXCEL表单中获取欲查询的课程名,并控制EXCEL生成新的工作表,VFP的查询结果仍然使用剪切板的方式传递至EXCEL工作表。
OleApp=CREATEOBJECT("Excel.Application") && 打开EXCEL,产生OLE对象
OleApp.Application.Caption="VFP交互编程" && 指定标题栏名称
OleApp.Application.Visible=.T. && 置EXCEL可见
OleApp.Application.WorkBooks.Open("d:\vfp\VFP交互.xls") && 打开EXCEL工作簿
DO WHILE .T.
WITH OleApp.Application
nAnswer = MESSAGEBOX("开始搜索?", 32+4, "搜索指定数据") &&产生信息框
IF (.NOT.(nAnswer=6)) && 如按下“Yes"按钮,则开始搜索,反之退出
EXIT
ENDIF
.Sheets("查询").Select && 选择“查询”工作表单
Slesson = OleApp.Application.Range("课程名").value && 得到欲查询的课程名称
.Sheets.Add && 新建一工作表单
.ActiveSheet.Name = Slesson && 指定工作表单的名称
Scommand = "SELECT 学号,语文,数学 FROM d:\vfp\学生成绩表 WHERE " +ALLTrim(Slesson) + "<60 INTO CURSOR TEMP" && 形成VFP查询命令串
&Scommand && 执行VFP命令串
_VFP.DataToClip("TEMP",,3) && 将搜索结果以文本方式拷贝至剪切板
.Range("a1:a1").Select && 指向拷贝目标区域左上角单元
.ActiveSheet.Paste && 粘贴搜索结果
ENDWITH
ENDDO
OleApp.Quit && 关闭EXCEL,保存更新后的工作簿文件
三、VFP使用DDE功能驱动EXECL
DDE(Dynamic Data Exchange)动态数据交换,是WINDOWS应用程序间相互传递和共享数据的另一种有效方法,DDE用共享存储器在应用程序间交换数据。DDE会话发生在DDE客户与DDE服务器应用程序之间,客户应用程序向服务器应用程序请求数据和服务,而服务器响应客户应用程序对数据与服务的请求。DDE的数据交换可分三种方式:
* 冷链接:客户应用程序请求数据时,服务器应用程序才发送数据给客户应用程序;
* 暖链接:服务器应用程序在每次数据项的值变化时都向客户应用程序发送通告,但它并不直接发送值给客户应用程序,而由客户应用程序决定是否取得该数据;
* 热链接:服务器应用程序在每次值变化时都发送数据项的新值给客户应用程序。
VFP与EXCEL均支持DDE客户与服务器。下述程序段由作为DDE客户的VFP应用程序与作为DDE服务器的EXCEL用DDE方式实现所要求的功能。
程序首先启动EXCEL,然后在VFP应用程序与“查询”工作表单的“课程名”单元格之间形成“热链接”,当“课程名”单元格内容改变时,将自动执行
“GetData”过程。在该过程中首先直接获取DDE数据,如果该数据为“空”,则关闭EXCEL,程序结束;反之,利用DDEPOKE功能向EXCEL发送键盘命令串,以形成新的工作表,最后VFP将查询结果通过剪切板送EXCEL形成要求的工作表。
PUBLIC ExcelChan
PUBLIC SheetChan
RUN /N3 C:\Program Files\Microsoft Office\Office\EXCEL.EXE && 以“活动”与“最大化方式启动EXCEL
ExcelChan = DDEInitiate("Excel",'SYSTEM') && 初始化DDE通道ExcelChan
= DDEExecute(ExcelChan,'[Open("d:\vfp\VFP交互.xls")]') && 打开“VFP交互.xls”
SheetChan = DDEInitiate('Excel', '查询') && 初始化DDE通道SheetChan
= DDEAdvise(SheetChan, '课程名', 'GetData', 2) && 在VFP应用程序与“查询”工作表单的“课程名”单元格之间形成“热链接”!如果该单元数值改变,则执行“GetData”过程。
PROCEDURE GetData
PARAMETERS Channel, Action, Item, Data, Format, Advise
IF Action = 'ADVISE' .AND. Item = '课程名' && 服务器提供的链接名为“课程名”
Slesson = Data && 直接获取DDE服务器提供的数据
Slesson = LEFT(Slesson,LEN(Slesson)-2) && 去掉原始数据尾部的格式字符
IF (LEN(Slesson)=0) && 如果指定单元格内容为“空”,则退出
= DDETerminate(SheetChan) && 终止DDE通道SheetChan
= DDEExecute(ExcelChan,'[Quit]') && 退出EXCEL
= DDETerminate(ExcelChan) && 终止DDE通道ExcelChan
ELSE
= DDEExecute(ExcelChan,'[Formula.Goto("课程名")]') && 指定名为“课程名”
的单元格为活动单元格
= DDEExecute(ExcelChan,'[Copy]') && 将指定单元格内容拷贝至剪切板
Skey="'%IW%OHR^V{enter}'" && 键盘命令字符串,表示“插入(I)|工作表(W);格式(O)|工作表(H)|重命名?;粘贴”
= DDEExecute(ExcelChan,&Skey) && 通过DDE通道将命令串送EXCEL
WAIT WINDOW TIMEOUT 2 && 等待2秒钟以实现上述命令串
Scommand = "SELECT 学号,语文,数学 FROM d:\vfp\学生成绩表 WHERE " +ALLTRIM(Slesson) + "<60 INTO CURSOR TEMP" && 形成VFP查询命令串
&Scommand && 执行VFP命令串
_VFP.DataToClip("TEMP",,3) && 将搜索结果以文本方式拷贝至剪切板
SheetChan1 = DDEInitiate("Excel",'&Slesson') && 初始化DDE通道SheetChan1
指向新生成的工作表
= DDEExecute(SheetChan1,'[Paste]') && 粘贴搜索结果
= DDETerminate(SheetChan1) && 终止DDE通道SheetChan1
ENDIF
[解决办法]
3
oconnection = CREATEOBJECT("adodb.connection")
oconnection.connectionstring = 'Provider=VFPOLEDB.1;Data Source=d:\zz;Password="";Collating Sequence=MACHINE'
oconnection.open
oRecordSet = CreateObject("adodb.recordset")
FGR='SELECT * FROM 10152907738.DBF'
oRecordSet.open(FGR,oconnection,1,3,1)
zx.sheets(1).select
ZX.RANGE("a1:a1").CopyFromRecordset(oRecordSet)
zx.sheets(1).Activate
zx.ActiveSheet.Name='市内'
[解决办法]
VFP导出Excel数据的3种方式
作者:元秋
*--最近大家对导出Excel数据比较感兴趣,究竟用哪种方式导出速度快呢?
*--以下是我给大家提供的一个实例,大家比较以下就可以得知。
*--由于时间关系,写的非常粗糙,意在给大家一个比较的途径,大家在实际
*--写程序的时候可以根据实际情况来选择使用。
*--表单运行说明:
*--第一步:打开表
*--第二步:导出Excel
*--以下是核心函数内容
*--在发布有,感谢dupeiji版主的修改,为其增加了第四种方式:*--QueryTables.add方式,但在我这里没有成功,不知道是什么原因。
Lparameters nLx
Local lcFileName As String,lcTitle As String
Local i As Integer,lnFcnt As Integer
lnFnt=Fcount()
lcFileName =Sys(5)+Sys(2003)+"\报表.xls"
lcTitle="导出报表演示"
Do Case
Case nLx=1 &&记录循环方式
oExcel=Createobject('Excel.Application')
If Vartype(oExcel)<>"O"
Messagebox("生成Excel出错,您可能没有安装Excel!",48,"提示")
Return
Endif
oExcel.DisplayAlerts= .F.
oExcel.Visible= .T.
oExcel.Workbooks.Add()
For i=1 To lnFnt
oExcel.Cells(1,i).Value=Fields(i)
oExcel.Cells(1,i).Font.Bold =.T. &&加粗
oExcel.Cells(1,i).HorizontalAlignment=-4108 &&居中
Endfor
Copy To Array aPrintArray &&需打印数据拷贝到数组aPrintArray
N=2 &&明细数据起始打印行
For I=1 To Alen(aPrintArray,1) &&行数
For Y=1 To Alen(aPrintArray,2) &&列数
oExcel.Cells(N,Y).Value = aPrintArray(I,Y)
Endfor
N=N+1
Endfor
Case nLx=2 &&用VFP的Copy To命令方式
If Type('oExcel') = "O"&& 如果对象已存在,先释放它
Release oExcel
Endif
Copy To (lcFileName) Type Xl5 &&建立excel表
oExcel=Createobject('Excel.Application')
If Vartype(oExcel)<>"O"
Messagebox("生成Excel出错,您可能没有安装Excel!",48,"提示")
Return
Endif
oExcel.DisplayAlerts= .F.
oExcel.Workbooks.Open(lcFileName)
oExcel.ActiveSheet.PageSetup.CenterHeader=lcTitle && 放入标题到页眉带
oExcel.ActiveSheet.PageSetup.CenterFooter='第&P页' &&页脚
oExcel.ActiveSheet.PageSetup.CenterHorizontally=.T.
oExcel.ActiveSheet.UsedRange.Copy
oExcel.ActiveSheet.Paste
oExcel.Selection.BorderS( -4160 ).LINESTYLE = 1
oExcel.Selection.BorderS( -4107 ).LINESTYLE = 1
oExcel.Selection.BorderS( -4131 ).LINESTYLE = 1
oExcel.Selection.BorderS( -4152 ).LINESTYLE = 1
oExcel.Selection.BORDERAROUND( ,3,-4105)
oExcel.Visible= .T.
Case nLx=3 &&放入内存粘贴方式
If Type('oExcel') = "O"&& 如果对象已存在,先释放它
Release oExcel
Endif
oExcel=Createobject('Excel.Application')
If Vartype(oExcel)<>"O"
Messagebox("生成Excel出错,您可能没有安装Excel!",48,"提示")
Return
Endif
oExcel.DisplayAlerts= .F.
oExcel.Visible= .T.
oExcel.Workbooks.Add()
oExcel.Range("A1").Select
Application.DataToClip(,,3) &&把Cursor中的数据放入内存
oExcel.ActiveSheet.Paste &&马上把内存中的数据粘贴到Excel中
oExcel.Range("A1").Select
Endcase
Release oExcel
[解决办法]
VFP的数据库,记录数为4万多,用文件-导出-选择文件类型为EXCEL,为什么导出的只有16384行;
用换一个数据库,记录数为2万多,用文件-导出-选择文件类型为EXCEL,导出的还是只有16384行
(第一行保留给字段标题,实际导出记录为16383)
---------------------------
方法一:用VFP9.0执行如下语句:
Copy To TEST.Xls Type Xl5
注:可以输出最多 65,536 行(但其中有一行保留给字段标题),因为目前EXCEL最多支持 65,536 行
Excel 8.0 (Excel 97)之前的版本只能显示前 16,384 行,并且不能导入超过 32,767 行的文件。
---------------------------
方法二:
导成 Csv 文件,记录没有限制,用EXCEL一样打开,但EXCEL2003最多能查看65,536行,因为目前EXCEL2003最多支持 65,536行(Excel 2007 最大行列:16384 列 1048576 行)
Copy To test.Csv Type Csv
但导成CSV有如下限制:
- 逻辑字段转换为 F/T 而不是 FALSE/TRUE.
- 如果一个字符字段只包括数值且值中包括前导的零, Excel 转换它为数值型的值 (如 "00000100" => 100).
- 日期型字段导出时要将设为 mm/dd/yy 格式或 mm/dd/yyyy 格式,否则导回时将丢失日期字段内容.
特别是字段是一个专用关键字且你又要在稍后从Excel 文件转换回 VFP 时,这样会有问题。
---------------------------
方法三:
如果你的数据中都是普通的数值和字符串类型,直接用Excel打开表,然后“另存为”一个Excel就可以了。
这样最多可以保存65,536 行(但其中有一行保留给字段标题),因为目前EXCEL最多支持 65,536 行
---------------------------
[解决办法]
方法四:用代码导
* Excel 5 和 Excel 95 有一个限制就是一张工作表只能有 16,383 行.
* 该限制在 Excel 97 和 Excel 2000 是 65,536 行.
* 由于没有 TYPE XL8 命令, VFP 只能复制最初的 16,383 条记录.
* 该程序处理该限制并允许复制用户机器上的 Excel 版本所支持的记录数.
&& DbfToExcel.PRG
&& 记得要安装Excel啊,否则不好用
&& BY Foxer(狐狸)
Close Databases All
Set Date YMD
Set Century On
cDbfFile = Getfile("dbf")
If Empty(cDbfFile)
Return
Endif
Use (cDbfFile) Alias FoxTable In 0
If Not Used("FoxTable")
=Messagebox("打开表失败,程序将中止!", 16, "Error")
Return
Endif
cExcelFile = Putfile("保存为(&N):",Juststem(cDbfFile)+".xls","xls")
If Empty(cExcelFile)
Close Databases All
Return
Endif
Select FoxTable
oExcelSheet = Getobject("","Excel.Sheet") && 产生Excel对象
If Not Type("oExcelSheet") = "O"
=Messagebox("Excel对象创建失败,程序将中止!", 16, "Error")
Return
Endif
oExcelApp = oExcelSheet.Application
oExcelApp.Workbooks.Add()
oExcelApp.ActiveWindow.WindowState=2
oSheet = oExcelApp.ActiveSheet
nFldCount = Afields(aFldList, "FoxTable")
For i = 1 To nFldCount
oSheet.Cells(1,i).Value = aFldList[i, 1]
Endfor
cRecc = Str(Reccount("FoxTable"))
Scan
Wait Window Alltrim(Str(Recno())) + "/" + cRecc Nowait
For i = 1 To nFldCount
vValue = .Null.
If At(aFldList[i, 2], "CDLMNFIBYT") = 0
Loop
Endif
cFldName = aFldList[i, 1]
vValue = Evaluate(cFldName)
Do Case
Case aFldList[i, 2] = "C" && 字符/字符串
vValue = Trim(vValue)
Case aFldList[i, 2] = "D" && 日期
vValue = Dtoc(vValue)
Case aFldList[i, 2] = "T" && 日期时间
vValue = Ttoc(vValue)
Case Inlist(aFldList[i, 2], "N", "F", "I", "B", "Y") && 数值
Case aFldList[i, 2] = "L" && 逻辑
Case aFldList[i, 2] = "M" && 备注型
Otherwise
vValue = .Null.
Endcase
If Vartype(vValue) = "C" And Empty(vValue)
Loop
Endif
If Not Isnull(vValue)
oSheet.Cells(Recno("FoxTable")+1, i).Value = vValue
Endif
Endfor
Endscan
cChrStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
For i = 1 To nFldCount
cColumn = Substr(cChrStr, Int((i-1)/26), 1) + Substr(cChrStr, Iif(Mod(i, 26)= 0, 26, Mod(i, 26)) , 1)
oSheet.Columns(cColumn + ":" + cColumn).ColumnWidth = 12
If aFldList[i, 2] = "M"
oSheet.Columns(cColumn + ":" + cColumn).WrapText = .F.
Endif
Endfor
oExcelApp.ActiveWorkbook.SaveAs(cExcelFile)
oExcelApp.ActiveWorkbook.Close(.F.)
oExcelApp.ActiveWorkbook.Close(.F.)
oExcelApp.Quit
oExcelSheet = .Null.
oExcelApp = .Null.
Wait Clear
=Messagebox("转换完毕!", 64, "OK")
Close Databases All
程序是用VFP8写的,在VFP6中也可以,没有问题。只要能够执行完成,就会是正确的,行数只受你安装的Excel最大行数限制,至少65,536行
这个程序支持所有字段类型(通用型除外),包括MEMO类型字段。
--------------------------
方法五:
xlQuery=exlapp.ActiveSheet.QueryTables.Add("OLEDB;Provider=VFPOLEDB;Data Source="+ipath+";Mode=Share Deny None;Password='';Collating Sequence=MACHINE", exlapp.Range("A2"), "select * from table")
此种方法不支持包含MEMO超长的数据
---------------------------
方法六:
如何复制多于 16,383 条记录到 Excel 中
qxf 于提供, CY 和 rmh 翻译
VFP 的 Copy To Type Xl5 命令只能复制 16,383 条记录. 该限制是由于 Xl5 格式的一张工作表只能有 16,383 行的限制造成的 (参见 MSKB Q103355). 在 Excel 97 和 Excel 2000 中的最大行数是 65,536. 不幸的中在 VFP 中没有 Type Xl8 关键字. 下面的代码提供一种简单的处理办法. 程序 Copy2Xls 可用于替代 VFP 自己的 Copy To Type Xl5 命令. 程序使用了 VFP 6 新增的 Type Csv 关键字. 如果你使用早期版本的 VFP, 用 Fox2x 替换 Csv 关键字. 关于 Csv 与 Fox2x 的区别及一些限制参见程序头中的注释. (以下程序用 UT 上的 Mike Hellands great utility mhHtmlCode 程序格式)
* 程序...........: Copy2xls.prg
* 作者............: Daniel Gramunt
* 项目...........: common
* 创建...........: 11.10.2000 17:25:06
*) 说明.......: 替换 VFP 自己的 COPY TO TYPE XL5 命令.
*) : Excel 5 和 Excel 95 有一个限制就是一张工作表只能有 16,383 行.
*) : 该限制在 Excel 97 和 Excel 2000 是 65,536 行.
*) : 由于没有 TYPE XL8 命令, VFP 只能复制最初的 16,383 条记录.
*) :
*) : 该程序处理该限制并允许复制用户机器上的 Excel 版本所支持的记录数.
*) :
*) : 该方案是非常简单的:
*) : 1. COPY TO TYPE CSV
*) : 2. 打开 CSV 文件并用 Automation 来 SaveAs(tcExcelFile)
*) :
*) : 假定 MS Excel (Excel 97 或以上) 安装在用户的机器上
*) : (好, 它将也可处理 Excel 5.0 和 95, 但将使用 16,383 的限制).
*) :
*) : 返回成功导出的记录数, 否则:
*) : -1 = 缺少参数或参数类型错误
*) : -2 = 当前工作区中未打开表
*) : -3 = 记录数超过最大 Excel 行数
*) : -4 = 用户不想复盖已存在的 Excel 文件 (SET SAFETY = ON)
*) :
*) : 性能注意: 在 VFP 中的 COPY TO 命令比起任何 automation 都要快得多.
*) : 但是, 由于我们只用来打开导出的文件并保存为不同格式, 几乎没有
*) : 性能损失.
*) :
*) :
* 调用示例....: Copy2Xls("c:\temp\bidon.xls")
* 参数列表....: tcExcelFile - 要创建的 Excel 文件的路径\文件名.
* 主要修改....: 26.10.2000: COPY TO FOX2X 和 SaveAs() 代替
* : "组合" 个别的 Excel 文件.
* : 谢谢 UT 的 莈tin Bas鰖 的意见
* : 12.04.2000: COPY TO CSV 代替 FOX2X.
* : FOX2X 有以下限制:
* : - 代码页 850 的问题 (如字符 "?)
* : - 不支持长文件名 (虽然很容易处理)
* : - 不支持 datetime
* : CSV 没有上述问题, 但有其它限制:
* : - 逻辑字段转换为 F/T 而不是 FALSE/TRUE.
* : 这不是一个问题, 但为了保持一致性, 我们
* : 对于记录数没有超过限制的表,
* : 不再使用 VFP 自己的 COPY TO TYPE XL5.
* : - 如果一个字符字段只包括数值且值中包括前导的零,
* : Excel 转换它为数值型的值 (如 "00000100" => 100).
* : 这是一个问题, 特别是字段是一个专用关键字且你又要在稍后从
* : Excel 文件转换回 VFP 时.
*--------------------------------------------------------------
Lparameter tcExcelFile
#INCLUDE FoxPro.h
#Define xlWorkbookNormal -4143 && 被 SaveAs() 用来保存于当前 Excel 版本
#Define ccErrorNoParameter "Parameter : 参数丢失失或类型错误 (非 'C')"
#Define ccErrorNoTableOpen "当前工作区中没有打开表"
#Define ccErrorToManyRows "记录数" + ;
ALLTRIM(Transform(lnRecords, "999,999,999")) +;
") 超过 Excel 最大行数 (" -;
ALLTRIM(Transform(lnXlsMaxNumberOfRows, "999,999,999"))+;
")"
*-- 检查参数
If Vartype(tcExcelFile) <> "C" Or Empty(tcExcelFile)
??Chr(7)
Wait Window Nowait ccErrorNoParameter
Return -1
Else
tcExcelFile = Forceext(tcExcelFile, "XLS")
Endif
*-- 确信在选定的工作区中打开了表或游标
If Empty(Alias())
??Chr(7)
Wait Window Nowait ccErrorNoTableOpen
Return -2
Endif
Local loXls, lnXlsMaxNumberOfRows, lnRecords, lnRetVal, lcTempDbfFile
loXls = Createobject("excel.application")
*-- 抑制 Excel 的警告和信息 (类似于 SET SAFETY OFF)
loXls.DisplayAlerts = .F.
*-- 从 Excel 获取最大行数. 在我们计算工作表中的行数前, 需要添加一个工作簿.
loXls.workbooks.Add()
lnXlsMaxNumberOfRows = loXls.ActiveWorkBook.ActiveSheet.Rows.Count - 1 && 1 头行
lnRecords = Reccount()
*-- 检查记录数是否超过了 Excel 的限制
If lnRecords > lnXlsMaxNumberOfRows
??Chr(7)
Wait Window Nowait ccErrorToManyRows
*-- 关闭 Excel
loXls.Application.Quit()
Return -3
Endif
*-- 维持 SET SAFETY
If Set("SAFETY") = "ON" And File(tcExcelFile)
If Messagebox(tcExcelFile + " 已经存在, 复盖它?",;
MB_YESNO + MB_ICONQUESTION + MB_DEFBUTTON2) = IDNO
*-- 用户选择了 因此退出
*-- 关闭 Excel
loXls.Application.Quit()
Return -4
Endif
Endif
lcTempDbfFile = Addbs(Sys(2023)) + Sys(3) + ".CSV"
Copy To (lcTempDbfFile) Type Csv
lnRetVal = _Tally
*-- 打开导出的 CSV 文件
loXls.Application.Workbooks.Open(lcTempDbfFile)
*-- 保存为 Excel 文件
loXls.ActiveSheet.SaveAs(tcExcelFile, xlWorkbookNormal)
*-- 删除 CSV 文件
If File(lcTempDbfFile)
Delete File (lcTempDbfFile)
Endif
*-- 关闭 Excel
loXls.Application.Quit()
Return lnRetVal
[解决办法]
*-- 关闭 Excel
loXls.Application.Quit()
Return lnRetVal
[解决办法]
*-- 关闭 Excel
loXls.Application.Quit()
Return lnRetVal
[解决办法]
*-- 检查记录数是否超过了 Excel 的限制
If lnRecords > lnXlsMaxNumberOfRows
??Chr(7)
Wait Window Nowait ccErrorToManyRows
*-- 关闭 Excel
loXls.Application.Quit()
Return -3
Endif