是否有一种快速方法可以从Windows Scripting Host操作现有 XLS文件的内容?
我们收到了客户提供的Excel模板。我们的任务是使用从Oracle数据库中提取的数据填充这些模板。
目前的方法是使用Windows Scripting Host和VBScript:
使用ADODB从Oracle获取数据:
Set db = CreateObject("ADODB.Connection")
SQL = "SELECT ..."
Set rs=db.execute(SQL)
使用VBScript在Windows Scripting Host中创建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
问题是这些文件中的一些包含大量数据,并且需要花费数小时来填充它们。 有没有更快的方法呢?
答案 0 :(得分:5)
我觉得你很高兴在这里:
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
我建议你先试试。
答案 1 :(得分:2)
看看这个。
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=49926
如果使用ADODB连接到Excel,而不是操作Excel,它也可能会有所帮助。如果您需要帮助,请阅读本文
http://support.microsoft.com/kb/257819
答案 2 :(得分:1)
一种可能性是将其分为两个阶段,但这取决于瓶颈在哪里。
如果是Excel,则只需将记录集行转换为CSV类型文件,然后完成后,创建Excel对象并将整个文件导入固定位置。
这可能比逐个细胞操作更快。
如果您无法将CSV导入到工作表上的固定位置(或者单元格不在连续的行或列中),我会将CSV导入新工作表,然后从那里执行批量复制到您的模板片材。
移动范围也应该比逐个细胞操作更快。
批量导入和批量复制应该会给你一些很好的改进。当你使用更复杂的Excel功能时,我已经有了处理单个单元格的工作表,这些单元格加速了10个因子(想想使用= sum(a1..a999)而不是在VBA中添加每个单独的单元格并将该值放在某处)。
至于如何从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
答案 3 :(得分:0)
您可以通过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