Sql server Excel vba xml解析性能
我正在excel中获取一些输入数据,将其解析为xml并使用它运行SQL存储过程,但在xml解析方面遇到了性能问题。输入表如下所示:Sql server Excel vba xml解析性能,sql-server,xml,vba,excel,Sql Server,Xml,Vba,Excel,我正在excel中获取一些输入数据,将其解析为xml并使用它运行SQL存储过程,但在xml解析方面遇到了性能问题。输入表如下所示: Dates_|_Name1_Name2_Name3_..._NameX Date1 | Date2 | . . . | Date1Y| 我有一些代码可以循环遍历每个单元格,并将数据解析为xml字符串,但即使对于大约300 x 300的网格,执行也需要大约5分钟的时间,我希望使用可能有数千列长的数据集。我尝试了几件事情来帮助加快速度,比如将数据读入变量,然后迭代,或
Dates_|_Name1_Name2_Name3_..._NameX
Date1 |
Date2 |
. . . |
Date1Y|
我有一些代码可以循环遍历每个单元格,并将数据解析为xml字符串,但即使对于大约300 x 300的网格,执行也需要大约5分钟的时间,我希望使用可能有数千列长的数据集。我尝试了几件事情来帮助加快速度,比如将数据读入变量,然后迭代,或者排除DoEvents,但我一直无法加快速度。以下是问题所在的代码:
Dim lastRow As Long
lRows = (oWorkSheet.Cells(Rows.Count, 1).End(xlUp).Row)
Dim lastColumn As Long
lCols = (oWorkSheet.Cells(1, Columns.Count).End(xlToLeft).Column)
Dim sheet As Variant
With Sheets(sName)
sheet = .Range(.Cells(1, 1), .Cells(lRows, lCols))
End With
ReDim nameCols(lCols) As String
resultxml=“”
对于i=2到行
resultxml=resultxml&“”
对于j=1到cols
如果修剪(活页(i,j))”,则
lResult=“”
rResult=“”
TMP值=修剪(活页(i,j))
如果IsDate(tmpValue)而非IsNumeric(tmpValue),则
如果Len(tmpValue)>=8,则
tmpValue=格式(tmpValue,“yyyy-mm-dd”)
如果结束
如果结束
resultxml=resultxml&lResult&tmpValue&rResult
多芬特
如果结束
下一个j
resultxml=resultxml&“”
接下来我
resultxml=resultxml&“”
任何关于降低运行时间的建议都将不胜感激。考虑使用一个全面的W3C兼容的XML API库,您可以使用该库使用DOM方法(createElement
,appendChild
,setAttribute
)来构建XML,而不是连接文本字符串。XML不是一个完全的文本文件,而是一个具有编码和树结构的标记文件。Excel配备了MSXML COM对象(通过引用或后期绑定),可以从Excel数据迭代构建树,如下所示
对于300行12列的随机日期,下面甚至不需要一分钟(单击宏后的几秒钟)就可以打印出原始输出,使用嵌入的XSLT样式表进行换行和缩进(如果不进行打印,MSXML会将文档输出为一条长而连续的行)
输入
VBA(当然要与实际数据对齐)
Sub-xmlExport()
关于错误转到错误句柄
“VBA参考MSXML,v6.0”
Dim doc作为新的MSXML2.DOMDocument60,xslDoc作为新的MSXML2.DOMDocument60,newDoc作为新的MSXML2.DOMDocument60
Dim root作为IXMLDOMELENT,dataNode作为IXMLDOMELENT,datesNode作为IXMLDOMELENT,namesNode作为IXMLDOMELENT
我和我一样长,我和我一样长
Dim TMP值作为变量
'声明XML文档对象'
Set root=doc.createElement(“数据集”)
doc.appendChild根目录
“遍历行”
对于i=2到图纸(1)。使用drange.Rows.Count
“数据行节点”
设置dataNode=doc.createElement(“DataRow”)
root.appendChild数据节点
“日期节点”
Set datesNode=doc.createElement(“日期”)
datesNode.Text=Sheets(1).Range(“A”和“i”)
dataNode.appendChild日期节点
“名称节点”
对于j=1到12
tmpValue=表(1)。单元格(i,j+1)
如果IsDate(tmpValue)而非IsNumeric(tmpValue),则
Set namesNode=doc.createElement(“Name”&j)
namesNode.Text=格式(tmpValue,“yyyy-mm-dd”)
dataNode.appendChild名称节点
如果结束
下一个j
接下来我
“漂亮的打印原始输出”
xslDoc.LoadXML“”_
& "" _
& "" _
& "" _
& " " _
& " " _
& " " _
& " " _
& " " _
& ""
xslDoc.async=False
doc.transformNodeToObject xslDoc,newDoc
newDoc.Save ActiveWorkbook.Path&“\Output.xml”
MsgBox“已成功将Excel数据导出为XML!”,vbInformation
出口接头
错误句柄:
MsgBox错误编号&“-”&错误说明,VBC
出口接头
端接头
输出
<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
<DataRow>
<Dates>Date1</Dates>
<Name1>2016-04-23</Name1>
<Name2>2016-09-22</Name2>
<Name3>2016-09-23</Name3>
<Name4>2016-09-24</Name4>
<Name5>2016-10-31</Name5>
<Name6>2016-09-26</Name6>
<Name7>2016-09-27</Name7>
<Name8>2016-09-28</Name8>
<Name9>2016-09-29</Name9>
<Name10>2016-09-30</Name10>
<Name11>2016-10-01</Name11>
<Name12>2016-10-02</Name12>
</DataRow>
<DataRow>
<Dates>Date2</Dates>
<Name1>2016-06-27</Name1>
<Name2>2016-08-14</Name2>
<Name3>2016-07-08</Name3>
<Name4>2016-08-22</Name4>
<Name5>2016-11-03</Name5>
<Name6>2016-07-28</Name6>
<Name7>2016-08-23</Name7>
<Name8>2016-11-01</Name8>
<Name9>2016-11-01</Name9>
<Name10>2016-08-11</Name10>
<Name11>2016-08-18</Name11>
<Name12>2016-09-23</Name12>
</DataRow>
...
日期1
2016-04-23
2016-09-22
2016-09-23
2016-09-24
2016-10-31
2016-09-26
2016-09-27
2016-09-28
2016-09-29
2016-09-30
2016-10-01
2016-10-02
日期2
2016-06-27
2016-08-14
2016-07-08
2016-08-22
2016-11-03
2016-07-28
2016-08-23
2016-11-01
2016-11-01
2016-08-11
2016-08-18
2016-09-23
...
考虑使用一个全面的W3C兼容XML API库,您可以使用它来使用DOM方法(createElement
,appendChild
,setAttribute
)构建XML,而不是连接文本字符串。XML不是一个完全的文本文件,而是一个具有编码和树结构的标记文件。Excel配备了MSXML COM对象(通过引用或后期绑定),可以从Excel数据迭代构建树,如下所示
对于300行12列的随机日期,下面甚至不需要一分钟(单击宏后的几秒钟)就可以打印出原始输出,使用嵌入的XSLT样式表进行换行和缩进(如果不进行打印,MSXML会将文档输出为一条长而连续的行)
输入
VBA(当然要与实际数据对齐)
Sub-xmlExport()
关于错误转到错误句柄
“VBA参考MSXML,v6.0”
Dim doc作为新的MSXML2.DOMDocument60,xslDoc作为新的MSXML2.DOMDocument60,newDoc作为新的MSXML2.DOMDocument60
Dim root作为IXMLDOMELENT,dataNode作为IXMLDOMELENT,datesNode作为IXMLDOMELENT,namesNode作为IXMLDOMELENT
我和我一样长,我和我一样长
Dim TMP值作为变量
'声明XML文档对象'
Set root=doc.createElement(“数据集”)
doc.appendChild根目录
'遍历R
<?xml version="1.0" encoding="UTF-8"?>
<DataSet>
<DataRow>
<Dates>Date1</Dates>
<Name1>2016-04-23</Name1>
<Name2>2016-09-22</Name2>
<Name3>2016-09-23</Name3>
<Name4>2016-09-24</Name4>
<Name5>2016-10-31</Name5>
<Name6>2016-09-26</Name6>
<Name7>2016-09-27</Name7>
<Name8>2016-09-28</Name8>
<Name9>2016-09-29</Name9>
<Name10>2016-09-30</Name10>
<Name11>2016-10-01</Name11>
<Name12>2016-10-02</Name12>
</DataRow>
<DataRow>
<Dates>Date2</Dates>
<Name1>2016-06-27</Name1>
<Name2>2016-08-14</Name2>
<Name3>2016-07-08</Name3>
<Name4>2016-08-22</Name4>
<Name5>2016-11-03</Name5>
<Name6>2016-07-28</Name6>
<Name7>2016-08-23</Name7>
<Name8>2016-11-01</Name8>
<Name9>2016-11-01</Name9>
<Name10>2016-08-11</Name10>
<Name11>2016-08-18</Name11>
<Name12>2016-09-23</Name12>
</DataRow>
...
Sub XMLFromRange()
Dim Start: Start = Timer
Const AVGCELLLENGTH As Long = 100
Dim LG As Long, index As Long, x As Long, y As Long
Dim data As Variant, Headers As Variant
Dim result As String, s As String
data = getDataArray
Headers = getHeaderArray(data)
result = Space(UBound(data, 1) * UBound(data, 2) * AVGCELLLENGTH)
index = 1
Mid(result, index, 11) = "<DataSet>" & vbCrLf
index = index + 11
For x = 2 To UBound(data, 1)
Mid(result, index, 11) = "<DataRow>" & vbCrLf
index = index + 11
For y = 1 To UBound(data, 2)
LG = Len(Headers(1, y))
Mid(result, index, LG) = Headers(1, y)
index = index + LG
s = RTrim(data(x, y))
LG = Len(s)
Mid(result, index, LG) = s
index = index + LG
LG = Len(Headers(2, y))
Mid(result, index, LG) = Headers(2, y)
index = index + LG
Next
Mid(result, index, 12) = "</DataRow>" & vbCrLf
index = index + 12
Next
Mid(result, index, 12) = "</DataSet>" & vbCrLf
index = index + 12
result = Left(result, index)
MsgBox (Timer - Start) & " Second(s)" & vbCrLf & _
(UBound(data, 1) - 1) * UBound(data, 2) & " Data Cells", vbInformation, "Execution Time"
Dim myFile As String
myFile = ThisWorkbook.Path & "\demo.txt"
Open myFile For Output As #1
Print #1, result
Close #1
Shell "Notepad.exe " & myFile, vbNormalFocus
End Sub
Function getDataArray()
With Worksheets("Sheet1")
getDataArray = .Range(.Range("A" & .Rows.Count).End(xlUp), .Cells(1, .Columns.Count).End(xlToLeft))
End With
End Function
Function getHeaderArray(DataArray As Variant)
Dim y As Long
Dim Headers() As String
ReDim Headers(1 To 2, 1 To UBound(DataArray, 2))
For y = 1 To UBound(DataArray, 2)
Headers(1, y) = "<" & DataArray(1, y) & ">"
Headers(2, y) = "</" & DataArray(1, y) & ">" & vbCrLf
Next
getHeaderArray = Headers
End Function