从Windows脚本主机处理Excel文件

有没有一种快速的方法来操纵从Windows脚本宿主现有的 XLS文件的内容?

我们有我们从客户收到的Excel模板。 我们的任务是用这些模板填充从Oracle数据库中获取的数据。

目前的方法是使用Windows脚本主机和VBScript:

  1. 使用ADODB从Oracle获取数据:

    Set db = CreateObject("ADODB.Connection") SQL = "SELECT ..." Set rs=db.execute(SQL) 
  2. 使用VBScript在Windows脚本主机中创build一个Excel对象:

     Set objExcel = CreateObject("Excel.Application") Set objWorkbook = objExcel.Workbooks.Open(xls_final) Set objSheet = objWorkBook.Sheets(1) 
  3. 然后像这样在单元格中填充模板:

     If rs.EOF = False Then rs.MoveFirst Do Until rs.EOF objSheet.Cells(RowNumber, 1).Value = rs("COLUMN1") objSheet.Cells(RowNumber, 2).Value = rs("COLUMN2") objSheet.Cells(RowNumber, 3).Value = rs("COLUMN3") rs.MoveNext Loop End If objWorkbook.Save rs.Close 

    问题是,这些文件中的一些包含大量的数据,并且需要花费数小时来填充它们。 有没有更快的方法来做到这一点?

我认为你很好,在这里:

 Set db = CreateObject("ADODB.Connection") SQL = "SELECT ..." Set rs=db.execute(SQL) Set objExcel = CreateObject("Excel.Application") Set objWorkbook = objExcel.Workbooks.Open(xls_final) Set objSheet = objWorkBook.Sheets(1) 

但是,正如你所发现的,其余的将会非常慢。 与工作表的交互具有很高的开销,您需要为每一行中的每一列付费。 这有一些方法。

最简单的是

 objSheet.Cells(1,1).CopyFromRecordset rs 

我build议你先尝试一下。

看看这个。
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=49926
如果您使用ADODB连接到Excel,而不是操作Excel,这也可能有所帮助。 如果你需要帮助阅读这个文章。
http://support.microsoft.com/kb/257819

一种可能性是将其分为两个阶段,但取决于瓶颈在哪里。

如果是Excel,那么只需将logging集行转换为CSVtypes的文件,然后创buildExcel对象并将整个文件导入到一个固定的位置。

这可能会比单元格操作更快。

如果您不能将CSV导入到工作表上的固定位置(单元格不在连续的行或列中),我会将CSV导入到新工作表中,然后从那里将大量副本复制到模板表中。

移动范围也应该比单元操作更快。

这是批量导入和大量复制,应该给你一些好的改善。 当你使用更复杂的Excelfunction时(例如使用= sum(a1..a999),而不是在VBA中添加每个单独的单元格,并将该值放在某处),我已经有了处理单个单元格的工作表)。

至于如何从VBA导入,我总是依靠"Record Macro"function来获得可以修改的基线(对于我不熟悉的基准)。 这个在C7 c:\x.csv导入到当前表单中:

 With ActiveSheet.QueryTables.Add(Connection:="TEXT;C:\x.csv", _ Destination:= Range("C7")) .Name = "x" .FieldNames = True .RowNumbers = False .FillAdjacentFormulas = False .PreserveFormatting = True .RefreshOnFileOpen = False .RefreshStyle = xlInsertDeleteCells .SavePassword = False .SaveData = True .AdjustColumnWidth = True .RefreshPeriod = 0 .TextFilePromptOnRefresh = False .TextFilePlatform = 850 .TextFileStartRow = 1 .TextFileParseType = xlDelimited .TextFileTextQualifier = xlTextQualifierDoubleQuote .TextFileConsecutiveDelimiter = False .TextFileTabDelimiter = True .TextFileSemicolonDelimiter = False .TextFileCommaDelimiter = True .TextFileSpaceDelimiter = False .TextFileColumnDataTypes = Array(1, 1, 1) .TextFileTrailingMinusNumbers = True .Refresh BackgroundQuery:=False End With 

现在我确信那里的大部分垃圾都可以被删除,但是一次只能做一个明智的做法,确保没有问题出现。

你也可以用下面的东西修改它来使用不同的工作表。

 dim ws as worksheet dim savealert as boolean set ws = Sheets.Add ws.select ' Put all that other code above in here. ' ' Move all that data just loaded into a real sheet. ' savealert = Application.DisplayAlerts Application.DisplayAlerts = False ws.delete Application.DisplayAlerts = savealert 

您可以通过OLEDB连接访问它,并且速度更快。

以下是我用来从电子表格导入数据到数据库的脚本的一些代码。 显然你会想改变游标types和lockingtypes,但你明白了。

 strExcelConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & objFile.Path & ";Extended Properties=""Excel 8.0;HDR=Yes""" strSQL = "SELECT * FROM [RegistrationList$] ORDER BY DateToRegister DESC" objExcel.Open strSQL, strExcelConn, adOpenForwardOnly, adLockReadOnly, adCmdText