VBA按行读取csv文件与分割合并

'2017年2月1日05:43:35 '16年想开发的最后一个Excel代码经过漫长的酝酿与研究终于编写完毕,解决了超过一百万行的csv文件Excel打不开的问题,自动分割为多个sheet,并且数字超过15位不会后面全是0。 '也可以用于平常打开csv文件,速度比直接打开快一倍,还可以用于指定行数分割,多文件合并,csv批量转Excel。 ' '顺道普及:csv文件就是用逗号分隔的数据表,有回车或逗号的文本还有长数字用两个"包围(连续两个表示"本身) 'xlsx文件大小约csv的50%,打开时间约csv的30%,xlsx压缩可能变大,csv压缩后不到10%。

Sub csv分割合并() selectfiles = Application.GetOpenFilename("," & ".", , "打开", , True) '选择文件 If TypeName(selectfiles) = "Boolean" Then '若未选择则结束程序运行 Exit Sub End If

关闭功能
st = Time

spt = [A5]
Ln = [B5]
If spt = "" Then spt = ","
If Not (Ln > 0) Then Ln = 1048576 '用Not是为了包括非数值

Workbooks.Add
li = 2

For Each fp In selectfiles
    
    Set FileObj = CreateObject("Scripting.FileSystemObject")
    Set TextObj = FileObj.OpenTextFile(fp) '定义对象,不耗时
    
    If Not TextObj.AtEndOfLine Then '记录并写入第一个标题行
        TitleText = Split(TextObj.Readline, spt)
        [A1].Resize(1, UBound(TitleText)) = TitleText '在合并工作表时也只是替代第一行
    End If
    
    Do While Not TextObj.AtEndOfLine
        If li > Ln Then '达到一定值新建表
            Sheets.Add
            [A1].Resize(1, UBound(TitleText)) = TitleText
            li = 2
        End If
        Text = Split(TextObj.Readline, spt) '读取行并分割
        Cells(li, 1).Resize(1, UBound(Text)) = Text '测试15位以上数值会保留
        '用时:UBound()<变量<数字,用数组给区域赋值比循环快五六倍左右
        '原先有数值会增加一倍时间,跟直接打开相等
        li = li + 1
    Loop
Next
Debug.Print (Time - st) * 24 * 60 * 60
开启功能

End Sub

Sub csv转xlsx() selectfiles = Application.GetOpenFilename("," & ".", , "打开", , True) '选择文件 If TypeName(selectfiles) = "Boolean" Then '若未选择则结束程序运行 Exit Sub End If

关闭功能
st = Time

spt = [A5]
Ln = 1048576
If spt = "" Then spt = ","
If Not (Ln > 0) Then Ln = 1048576 '用Not是为了包括非数值

For Each fp In selectfiles
    
    Set FileObj = CreateObject("Scripting.FileSystemObject")
    Set TextObj = FileObj.OpenTextFile(fp) '定义对象,不耗时
    
    Workbooks.Add
    li = 2
    
    If Not TextObj.AtEndOfLine Then '记录并写入第一个标题行
        TitleText = Split(TextObj.Readline, spt)
        [A1].Resize(1, UBound(TitleText)) = TitleText '在合并工作表时也只是替代第一行
    End If
    
    Do While Not TextObj.AtEndOfLine
        If li > Ln Then '达到一定值新建表
            Sheets.Add
            [A1].Resize(1, UBound(TitleText)) = TitleText
            li = 2
        End If
        Text = Split(TextObj.Readline, spt) '读取行并分割
        Cells(li, 1).Resize(1, UBound(Text)) = Text '测试15位以上数值会保留
        '用时:UBound()<变量<数字,用数组给区域赋值比循环快五六倍左右
        '原先有数值会增加一倍时间,跟直接打开相等
        li = li + 1
    Loop
    Debug.Print (Time - st) * 24 * 60 * 60
    ActiveWorkbook.SaveAs Left(fp, InStrRev(fp, ".") - 1) & ".xlsx" '保存需要一倍的时间
    ActiveWorkbook.Close 0
Next
Debug.Print (Time - st) * 24 * 60 * 60
开启功能

End Sub

Function 文件打开计时器() selectfiles = Application.GetOpenFilename("," & ".", , "打开", , True) '选择文件 If TypeName(selectfiles) = "Boolean" Then '若未选择则结束程序运行 Exit Function End If 关闭功能 st = Time

For i = 1 To UBound(selectfiles)
Set wb = Workbooks.Open(selectfiles(i))
wb.Close 0 '不保存关闭约1.4e-11s可忽略不计
Next

Debug.Print (Time - st) * 24 * 60 * 60
开启功能

End Function

Sub 关闭功能() '关闭一些功能加快 VBA 宏的运行速度 ' On Error Resume Next '出错继续运行 ' Application.DisplayAlerts = False '禁用警告信息 ' Application.DisplayAlerts = True '启用警告信息 Application.ScreenUpdating = False '禁用屏幕更新 Application.DisplayStatusBar = False '禁用状态栏 Application.Calculation = xlCalculationManual '切换到手动计算-4135,如果中途需要计算时用Calculate Application.EnableEvents = False '禁用事件 ActiveSheet.DisplayPageBreaks = False '禁用本表分页符 End Sub

Sub 开启功能() '开启关闭的功能,调试中断可运行开启功能 Application.ScreenUpdating = True '启用屏幕更新 Application.DisplayStatusBar = True '启用状态栏 Application.Calculation = xlCalculationAutomatic '切换到自动计算-4105 Application.EnableEvents = True '启用事件 'ActiveSheet.DisplayPageBreaks = displayPageBreaksState '启用本表分页符 End Sub

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏葡萄城控件技术团队

ASP.NET MVC 5 - 给数据模型添加校验器

在本节中将会给Movie模型添加验证逻辑。并且确保这些验证规则在用户创建或编辑电影时被执行。 拒绝重复 DRY ASP.NET MVC 的核心设计信条之一是DR...

1867
来自专栏葡萄城控件技术团队

七天学会ASP.NET MVC (三)——ASP.Net MVC 数据处理

? 第三天我们将学习Asp.Net中数据处理功能,了解数据访问层,EF,以及EF中常用的代码实现方式,创建数据访问层和数据入口,处理Post数据,以及数据验...

21310
来自专栏哲学驱动设计

asp.net MVC 应用程序的生命周期

  首先我们知道http是一种无状态的请求,他的生命周期就是从客户端浏览器发出请求开始,到得到响应结束。那么MVC应用程序从发出请求到获得响应,都做了些什么呢?...

1689
来自专栏郭霖

Android Volley完全解析(四),带你从源码的角度理解Volley

经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了,但是对于Volley的工作原理,恐怕有很多朋友还不是很清楚。因此,本篇文章中我们就来一起阅读一下...

2398
来自专栏分布式系统和大数据处理

HttpHandler介绍

在 Http请求处理流程 一文中,我们了解了Http请求的处理过程以及其它一些运作原理。我们知道Http管道中有两个可用接口,一个是IHttpHandler,一...

822
来自专栏前端黑板报

HTTP2基础教程-读书笔记(四)

? 记录一下HTTP/2的底层原理,帮助理解协议实现细节。 连接 每个端点都需要发送一个连接作为最终确认使用的协议,并建立http/2连接的初始设置。客户端和...

3356
来自专栏哲学驱动设计

asp.net MVC 应用程序的生命周期

  首先我们知道http是一种无状态的请求,他的生命周期就是从客户端浏览器发出请求开始,到得到响应结束。那么MVC应用程序从发出请求到获得响应,都做了些什么呢?

833
来自专栏Android研究院

彻底理解OkHttp - OkHttp 源码解析及OkHttp的设计思想

在OKhttp 源码解析之前,我们必须先要了解http的相关基础知识,任何的网络请求都离不开http。

1352
来自专栏恰同学骚年

自己动手写工具:百度图片批量下载器

开篇:在某些场景下,我们想要对百度图片搜出来的东东进行保存,但是一个一个得下载保存不仅耗时而且费劲,有木有一种方法能够简化我们的工作量呢,让我们在离线模式下也能...

1531
来自专栏偏前端工程师的驿站

线程间通讯:WaitHandler使用实例及分析

实例效果: ? 1.点击“启动线程”会启动一个线程t每隔2秒在listbox上插入一条新记录。 2.点击“关闭线程”会停止线程t,但不是马上停止而是等待线程t当...

1735

扫码关注云+社区