解铃还须系铃人:再谈CSV丢零现象


上文中主要谈到如何输出XML的格式,使得Excel在读解数据是不要自作聪明,从而使得用户得到需要的显示格式。

 

文末提到,有人用PL/SQL输出真正的Excel文件。笔者也试过,对于小批量数据还可接受,对于大量数据会出现服务器瓶颈,效率变差,用户难以接受。

除此之外,也有用Java API来解决此类问题的。比如使用 “Apache POI - the Java API for Microsoft Documents”。

其URL:  http://poi.apache.org/

事例: ttp://viralpatel.net/blogs/java-read-write-excel-file-apache-poi/

对此Java API笔者尚未验证,不敢妄加评论。

 

本文将从另一个角度来探讨CSV在Excel中丢零问题。常言说的好,解铃还须系铃人。我们可以借助Excel的内部功能,使用VBA来处理这一问题。

Excel提供了一个ADO Object,QueryTables。通过它,我们可把外部数据读入Excel表单。

(有关详情可参考微软文件:http://msdn.microsoft.com/en-us/library/office/ff837764.aspx

 

  • 基本思路

 这里假设我们已经读入了一个CSV文件,如果我们这时在“Visual Basic for Applications"(VBA)之下执行以下代码(按下F11可呼出VBA,然后,拷贝,粘帖,执行),

我们就可以用ActiveSheet.QueryTables.Add方法再次装入这个CSV文件,所不同的是,这段代码指定了每个列使用文本格式,而不是让Excel自作聪明地设定类型:

   Sub Reform_CSV()
   Dim AllTextFormat(255) As Integer
   Dim i As Long
   For i = 0 To 255
      AllTextFormat(i) = xlTextFormat  ' =2, Array to indicate column's data type
   Next i

    'Clear all cells in the sheet
    Cells.Clear
    
    ' Reload the CSV file
    MyFile = "text;" & ActiveWorkbook.FullName
    
    With ActiveSheet.QueryTables.Add(Connection:=MyFile, Destination:=Range("$A$1"))
       .TextFileCommaDelimiter = True
       .TextFileColumnDataTypes = AllTextFormat
       .Refresh
    End With
    
End Sub

         .TextFileColumnDataTypes = AllTextFormat

 而AllTextFormat是一个所有元素都为2(即Text)的数组。

   

  • 具体实现

Q: 好,这办法不错哦。可,总不能让我每次都贴一段代码到VBA编辑器啊。

A: 当然不用。我们可以把这段程序保存到文件中,每次执行它就成。

Q: 不对啊,CSV不能记忆VBA代码的。再说了,做个Excel文件,在读入CSV文件前先打开这个Excel,然后选择执行其中的代码?这不忒麻烦了点?

A: 是的。我们可以请一个叫做PERSONAL.XLSB的文件出山啊。每次Excel启动时必先打开此文件。

 

PERSONAL.XLSB存在于一个叫做XLSTART的文件夹里。顾名思义,EXCEL在Start时要访问的文件夹。

这其实是一个保存个人宏定义的文件,即个人宏工作簿。你可以把自己常用的宏集中在一起保管,而不是分散在不同的Excel文件之中。

可惜,很多用户不喜欢Excel每次打开这么一个东东,网上常问的问题是如何禁止它。答案是找到它并干掉它。

这里,我们要反其道而行之。探讨如何设置它。

 

如何创建个人宏工作簿,详情可参考以下URL:

http://wenku.baidu.com/view/b7b1887802768e9951e738c2.html

 

因为Windows版本和Office版本很多,可以结合下列vbs代码,检测当前使用的EXCEL默认的PERSONAL.XLSB所在的文件夹。

 

'vbscript to detect the location of PESONAL.XLSB file
'Name: Detect_Personal_XLSB.vbs
'by ZPF, 2013/09/18

Option Explicit

Dim objFileSys, computername, username, tgtFile, msgText, choice, objExcel

' Excel StartupPath check
Set objExcel = CreateObject("Excel.Application")
tgtFile = objExcel.StartupPath 
Set objExcel = Nothing

Set objFileSys = CreateObject("Scripting.FileSystemObject")

if objFileSys.FileExists(tgtFile & "\PERSONAL.XLSB") = False Then
    msgText = "PERSONAL.XLSB is not found."& vbCr 
    msgText = msgText & "But, it should be located in: " & vbCr
    msgText = msgText & tgtFile & vbCr
    msgText = msgText & vbCr
    MsgBox msgText,vbInformation,"Message"
else
    msgText = "PERSONAL.XLSB is found."& vbCr 
    msgText = msgText & "It is located in: " & vbCr
    msgText = msgText & tgtFile & vbCr
    msgText = msgText & vbCr
    MsgBox msgText,vbInformation,"Message"
end if



如果你已经打开了你的PERSONAL.XLSB文件,那么,在VBA编辑器上,加入第一段代码,即“Sub Reform_CSV()”那一段。

这段代码应该位于该文件的"标准模块"的"模块1"之中。

 

这样你就有了可以调用的模块。下一步就是把这个模块添加到Excel的弹出式菜单上。

这需要在PERSONAL.XLSB的ThisWorkbook上键入以下代码。

Private Sub workbook_open()
 
    Dim cmdBr As CommandBar
    Dim cmdBtn As CommandBarButton
 
    'get command bar 
    Set cmdBr = Application.CommandBars("cell")

    'Create an Item in Command bar
    Set cmdBtn = cmdBr.Controls.Add(msoControlButton, , , , True)
 
    'Add properties to the item
     With cmdBtn
       'We need a line above the Item
        .BeginGroup = True
       'Procedure to be called out
        .OnAction = "Reform_Csv"
       'Display name of the Item
        .Caption = "Reform CSV"
     End With
End Sub


然后,保存这个PERSONAL.XLSB文件;关闭EXCEL,再启动EXCEL,在任意单元(Cell)上按右按键,在弹出菜单的最底部,你会发现“Reform CSV”这个新菜单项目。

 

  • 安装包下载

如果你觉得这都麻烦,那就干脆下载一个安装包吧。

 http://download.csdn.net/detail/zhangpingfanyahoocom/6286533

 

不能下载?试试这个。

 https://skydrive.live.com/?cid=906664A6A59FC0DD&id=906664A6A59FC0DD%211023


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值