从Windows脚本主机处理Excel文件
有没有一种快速的方法来操纵从Windows脚本宿主现有的 XLS文件的内容?
我们有我们从客户收到的Excel模板。 我们的任务是用这些模板填充从Oracle数据库中获取的数据。
目前的方法是使用Windows脚本主机和VBScript:
-
使用ADODB从Oracle获取数据:
Set db = CreateObject("ADODB.Connection") SQL = "SELECT ..." Set rs=db.execute(SQL)
-
使用VBScript在Windows脚本主机中创build一个Excel对象:
Set objExcel = CreateObject("Excel.Application") Set objWorkbook = objExcel.Workbooks.Open(xls_final) Set objSheet = objWorkBook.Sheets(1)
-
然后像这样在单元格中填充模板:
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