是否有一种快速的方法来处理Windows脚本宿主的现有 XLS文件的内容?
我们有从客户那里收到的Excel模板。我们的任务是用从Oracle数据库中获取的数据填充这些模板。
当前方法是使用Windows Scripting Host和VBScript:
[使用ADODB从Oracle获取数据:
Set db = CreateObject("ADODB.Connection")
SQL = "SELECT ..."
Set rs=db.execute(SQL)
使用VBScript在Windows脚本宿主中创建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
我建议您先尝试。
看看这个。http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=49926如果您使用ADODB(而不是操纵Excel)连接到excel,这也可能会有所帮助。如果您需要帮助,请阅读此文章。http://support.microsoft.com/kb/257819
一种可能是使其成为两个阶段的过程,但这取决于瓶颈在哪里。
如果是Excel,则只需将记录集的行转换为CSV类型的文件,然后完成操作,创建Excel对象并将整个文件导入到固定位置。
这可能比逐个单元的操作要快。
如果无法将CSV导入到工作表上的固定位置(所有单元格不在连续的行或列中),我会将CSV导入到新工作表中,然后从那里将其批量复制到模板工作表中。
移动范围也应该比逐个单元的操作更快。
这是批量导入和批量复制,应该可以给您带来一些改善。我有工作表处理的单个单元格,当您使用更复杂的Excel功能时(考虑使用= sum(a1..a999)而不是在VBA中添加每个单个单元格并将该值放在某个地方,这些单元格的速度提高了10倍)。
关于如何从VBA进行导入,我始终依靠"Record Macro"
功能来获得可以修改的基线(对于我不十分熟悉的基线)。这将c:\x.csv
导入到当前工作表的C7
:
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连接访问它,并且速度无限快。
以下是脚本中的一些代码,我使用这些脚本将电子表格中的数据导入数据库。显然,您将需要更改游标类型和锁定类型,但是您会明白这一点。
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