注册 登录
编程论坛 VFP论坛

请教如何把EXCEL2016文件导入到VF中来

wjh9390 发布于 2021-06-28 16:56, 5417 次点击
现有一个EXCEL固定的表65列,每列都
只有本站会员才能查看附件,请 登录
是字符型,想导入到VF中来处理,如何用程序导入请大神出个成品,能直接使用的。谢谢
25 回复
#2
sdta2021-06-28 18:04
电脑没有安装EXCEL2016,是在WIN7+VFP9 7423+EXCEL2007环境下测试的。
程序代码:
oExcel = CREATEOBJECT('Excel.Application')
WITH oExcel
    .WorkBooks.Open(SYS(5) + SYS(2003) + "\名册.Xlsx")
    .ActiveSheet.UsedRange.Select
    WITH .Selection
        .Columns.AutoFit
        nRow = .Rows.Count - 1
        nColumn = .Columns.Count - 0
        LOCAL ArrayName[nRow, nColumn]
        ArrayName = .Cells(2, 1).Resize(nRow, nColumn).Value
    ENDWITH
    .DisplayAlerts = .F.
    .WorkBooks.Close
    .Quit   
ENDWITH
lcStr = "序号 N(2)"
FOR lnj = 1 TO 64
    lcStr = lcStr + ", F" + TRANSFORM(lnj) + " C(40)"
ENDFOR
CREATE CURSOR test (&lcStr)
INSERT INTO test FROM ARRAY ArrayName
LOCATE
BROWSE
#3
wjh93902021-06-28 20:19
谢谢,测试一下,正在使用
#4
jiazhefish2021-06-29 08:25
#5
wengjl2021-06-29 13:00
自从数据超过65536后,不能用2003了,只好用高版本,而高版本又没有另存为...DBF格式的功能了。好在VFP能读EXCEL,所以,自用上OFFICE2007后,都是采用读取单元格的方法来解决,虽然速度上损失一点,但还是可以忍受的程度。
#6
reakal2021-07-01 08:29
回复 2楼 sdta
ArrayName = .Cells(2, 1).Resize(nRow, nColumn).Value   
这句是个思路,请教一下,可以反向吗,及批量替换Excel选定区域的内容 替换为VFP的数组内容
#7
sdta2021-07-01 09:00
回复 6楼 reakal
可以
#8
reakal2021-07-01 09:23
回复 7楼 sdta
版主百忙之中还能及时关注啊,谢谢!
我指的不是通过循环哦,就是类似赋值那样 一句就搞定的,目的其实只有一个,就是更高效
比如,通常我们取Excel数据,都是循环读取每个单元格,感觉这种方式,显然没你这句直接把区域 赋值给 数组,一行,来得快。

[此贴子已经被作者于2021-7-1 09:25编辑过]

#9
sdta2021-07-01 09:35
https://blog.bccn.net/sdta/16740
这段代码是由 都市夜猫 大师写的,不知是否符合你的要求
#10
reakal2021-07-01 09:44
回头我试试,谢谢版主!
#11
xuminxz2021-07-01 13:28
用access
#12
jinanshui2021-07-02 09:13
我也有同样的问题,大的EXCEL2016文件导为dbf,大约17000多行,也请各位老师帮忙
只有本站会员才能查看附件,请 登录
#13
wengjl2021-07-02 09:53
@jinanshui
只有本站会员才能查看附件,请 登录
#14
jinanshui2021-07-02 14:25
回复 13楼 wengjl
谢谢老师,您是怎样做的?有代码吗?
#15
xuminxz2021-07-02 16:02
1、建立一个access数据库
2、选择 外部数据+新数据源+从文件+Excel导入表
3、用设计器,将学校代码字段长度改为5(小于254就可以),修改字各段名,使之符合VFP表,字段史规则。(也可以在Excel中修改)。其它字段宽度可以以后改。
4、创建+查询设计。关闭显示表窗口,右击设计器窗口,选择SQL设计器。输入
select distinct * from 导入的表名;
5、点击“生成表”输入表名
6、删除空白记录(第一条)
7、在左侧窗口,右击生成的表,导出+ dBASE 文件。

说明:1、整个过程中,表名最好不要用中文。
    2、字段名不能以数字开头
    3、前面3-6部是为了删除空记录(你的表中空记录太多),也可以Excel中处理。
以下是修改字符字段宽度到最小的代码。
程序代码:
FOR i=1 TO FCOUNT()
    _zdmc=FIELDS(i)
    =MESSAGEBOX(_zdmc)
    IF TYPE(_zdmc)='C'
        CALCULATE MAX(LEN(ALLTRIM(&_zdmc)))  TO ilen
        ALTER  table  hbsj alter &_zdmc. C(ilen)   &&hbsj 为需要修改的dbf表名
    ENDIF
ENDFOR


#16
吹水佬2021-07-02 16:30
以下是引用jinanshui在2021-7-2 09:13:24的发言:

我也有同样的问题,大的EXCEL2016文件导为dbf,大约17000多行,也请各位老师帮忙

先分析这个EXCEL文件,有些内容字符数超过DBF字符型字段的限制,其中:

第296行,2021专业名称,超过300个字节
工科试验班(智慧化工)(化学工程与工艺,油气储运工程,资源循环科学与工程,精细化工)(不招色弱,色盲,嗅觉迟钝。化学工程与工艺(ABET)国家工程教育专业认证),油气储运工程获批国家一流本科专业建设点,资源循环科学与工程(国家特色专业)获批国家一流本科专业建设点。精细化工入选教育部基础学科拔尖学生培养计划2.0基地)

第676行,2020专业名称,超过400个字节
工商管理类(工商管理、人力资源管理、财务管理、会计学、会计学(国际会计)、市场营销、工业工程、物流管理、图书馆学、档案学、旅游管理、会展经济与管理)(国际会计专业与加拿大特许专业会计师协会合作培养,主要专业课双语授课;工商管理专业核心课程采用全英文授课。学生可参与罗格斯大学、格拉斯哥大学等本硕双学位项目,加州大学伯克利分校等海外知名高校交流项目,及美国中佛罗里达大学一迪士尼世界主题公园等教学实习项目)
#17
xuminxz2021-07-02 16:44
这样用另存似乎不好。可以用ODBC+VFP视图。为了偷懒,可以先用长文本,VFP用M型。然后,用下面的代码。改结构。
程序代码:
FOR i=1 TO FCOUNT()
    _zdmc=FIELDS(i)
    =MESSAGEBOX(_zdmc)
    IF TYPE(_zdmc)='M'
        CALCULATE MAX(LEN(ALLTRIM(&_zdmc)))  TO ilen
        if ilen<254
            ALTER  table  hbsj alter &_zdmc. C(ilen)
        endif
    ENDIF
ENDFOR

后台用SQL server 更好。
#18
wjh93902021-07-02 16:59
继续请教,现在已经将《特殊工种市(地)级审核名册》导入VF9.0中,因为我的字段都是字符型的,导入到VF9.0以后,现在我需要判断:档案特殊工种开始时间1,档案特殊工种结束时间1至档案特殊工种开始时间4,档案特殊工种结束时间4,以及  提供台账年月1至提供台账年月10(每提供1年台账即代表全年1月1日到12月31日)所提供 的时间是否交叉,如果交叉就出错了,没交叉再判断工种是否按年月顺序一致,如果一致,我出表的时侯会合到一起。(见附表)求大神指教VF代码或程序。
只有本站会员才能查看附件,请 登录

#19
xuminxz2021-07-02 17:07
把你的VFP表放上来啊
#20
吹水佬2021-07-02 20:49
回复 12楼 jinanshui
用M类型字段存放超长文本
只有本站会员才能查看附件,请 登录

程序代码:
cDefPath = ADDBS(JUSTPATH(SYS(16)))
SET DEFAULT TO (cDefPath)
xlsx = cDefPath + "hb2019sj.xlsx"
oExcel = CREATEOBJECT('Excel.Application')
oExcel.DisplayAlerts = 0
oExcel.WorkBooks.Open(xlsx)
nRow = oExcel.Application.CountA(oExcel.ActiveSheet.Range("A:A")) - 1
nCol = oExcel.Application.CountA(oExcel.ActiveSheet.Range("1:1"))
arrHead = oExcel.ActiveSheet.UsedRange.Cells(1,1).Resize(1,nCol).Value
arrData = oExcel.ActiveSheet.UsedRange.Cells(2,1).Resize(nRow,nCol).Value
oExcel.WorkBooks.Close
oExcel.Quit
cmd = ""
FOR i=1 TO nCol
    f = arrHead[1,i]
    m = 10
    FOR j=1 TO nRow
        IF VARTYPE(arrData[j,i]) != "N"
            n = LEN(arrData[j,i])
            IF n > m
                m = n
            ENDIF
        ENDIF
    ENDFOR
    IF m < 255
        cmd = cmd + ",_" + f + " V(" + TRANSFORM(m) + ")"
    ELSE
        cmd = cmd + ",_" + f + " M"
    ENDIF
ENDFOR
cmd = "CREATE CURSOR tt (" + SUBSTR(cmd,2) + ")"
EXECSCRIPT(cmd)
INSERT INTO tt FROM ARRAY arrData
SELECT * FROM tt


[此贴子已经被作者于2021-7-2 20:58编辑过]

#21
jinanshui2021-07-02 22:44
谢谢各位老师
#22
schtg2021-07-04 06:30
学习啦,谢谢!
#23
lihzh2021-08-13 14:57
以下是引用sdta在2021-6-28 18:04:30的发言:

电脑没有安装EXCEL2016,是在WIN7+VFP9 7423+EXCEL2007环境下测试的。
oExcel = CREATEOBJECT('Excel.Application')
WITH oExcel
    .WorkBooks.Open(SYS(5) + SYS(2003) + "\名册.Xlsx")
    .ActiveSheet.UsedRange.Select
    WITH .Selection
        .Columns.AutoFit
        nRow = .Rows.Count - 1
        nColumn = .Columns.Count - 0
        LOCAL ArrayName[nRow, nColumn]
        ArrayName = .Cells(2, 1).Resize(nRow, nColumn).Value
    ENDWITH

    .DisplayAlerts = .F.
    .WorkBooks.Close
    .Quit   
ENDWITH
lcStr = "序号 N(2)"
FOR lnj = 1 TO 64
    lcStr = lcStr + ", F" + TRANSFORM(lnj) + " C(40)"
ENDFOR
CREATE CURSOR test (&lcStr)
INSERT INTO test FROM ARRAY ArrayName
LOCATE
BROWSE



一句代码就能解决太爽了,我的笨方法是一个一个字段的读出来,然后一个一个字段的写去另一个新excel文件,目的是多个xls文件合并为一个新的xlsx文件,挺耗时的。那么请问,按代码,把excel文件导入到数组后,若需要把数组的内容填入一个新的excel文件如何反向赋值?同时要考虑下一个数组的内容续着填入,字段内容可以沿用题主的数据。谢谢大神!
#24
sdta2021-08-13 19:47
以下是引用lihzh在2021-8-13 14:57:06的发言:




一句代码就能解决太爽了,我的笨方法是一个一个字段的读出来,然后一个一个字段的写去另一个新excel文件,目的是多个xls文件合并为一个新的xlsx文件,挺耗时的。那么请问,按代码,把excel文件导入到数组后,若需要把数组的内容填入一个新的excel文件如何反向赋值?同时要考虑下一个数组的内容续着填入,字段内容可以沿用题主的数据。谢谢大神!

下面代码是否对你有帮助
https://blog.bccn.net/sdta/16740
#25
lihzh2021-08-16 12:41
回复 24楼 sdta
谢谢指导,测试了一下脚本,可能不知道在哪里打开excel的vb的访问,到下面的代码就报错了,
我按之前的代码逆向想当然的执行,但写入新的excel里所有字段内容都是原表最后一行最后一列的内容,代码如下:
v_file=getfile()
v_path=subs(v_file,1,rat('\',v_file))
=adir(a_file,v_path+'*.'+justext(v_file))
oExcel = CREATEOBJECT('Excel.Application')
WITH oExcel
    .WorkBooks.Open(v_path+a_file(1,1))
    .ActiveSheet.UsedRange.Select
    WITH .Selection
        .Columns.AutoFit
        nRow = .Rows.Count - 1
        nColumn = .Columns.Count - 0
        LOCAL ArrayName[nRow, nColumn]
        ArrayName = .Cells(2, 1).Resize(nRow, nColumn).Value
    ENDWITH
    .DisplayAlerts = .F.
    .WorkBooks.Close
    .Quit   
ENDWITH
endxls=createobject('excel.application')
with endxls
   .workbooks.add
   .worksheets('sheet1').activate
   .cells.Resize(nRow, nColumn).Value=ArrayName(nRow, nColumn)
   .DisplayAlerts = .F.
   .visible=.t.
   .WorkBooks.Close
   .Quit   
endwith
估计问题是在红色那句,但不知道参数应该怎么样才对,不过不重要了,刚想到一个问题,我那堆xls,都是24列15000行,记录数太多数组装不下,我还是一个一个字段的读了写到新的xlsx上去,慢就慢点,谢谢大神热心。

[此贴子已经被作者于2021-8-16 17:09编辑过]

#26
haoduoyu2021-11-26 10:00
回复 2楼 sdta
请问 为什么第一个字段要定义为浮点型。改成C或N型,就无法导入数据
1