我正在努力加快当前正在运行的自动化工作簿。
PHP将类似于下面的字符串发送到VBA:
1[|:#:|]text-one[|:#:|]code-one[|:#:|]qty-one[{:#:}]
2[|:#:|]text-two[|:#:|]code-two[|:#:|]qty-two[{:#:}]
,其中
[|:#|]
代表“新专栏”[{:#:}]
代表“新行”当VBA解析它时,这是输出:
我目前使用以下VBA代码将其解析为工作簿:
myArray = Split(myReply, "[{:#:}]")
myRow = 1
For Each element In myArray
myRow = myRow + 1
subArray = Split(element, "[|:#:|]")
myCol = 2
For Each subelement In subArray
myCol = myCol + 1
Cells(myRow, myCol).Value = subelement
Next subelement
Next element
我即将开始优化此工作簿中的代码,我知道我可以执行类似(伪代码)的操作:
for each element....
Range("C2:F2").Value = Split(element, "[|:#:|]") 'Example row number would be incremental
但是有没有办法让我可以分成整个范围?
例如,如果我知道返回的数据中有29个“行”,我希望能够使用split
将数据放入所有行。
我认为语法类似于下面的内容,但这似乎不起作用:
Range("C2:F29").Value = Split(Split(element, "[|:#:|]"),"[{:#:}]")
答案 0 :(得分:2)
最佳方法是在本机VBA代码中执行所有操作,并且不要与Excel工作表交互直到结束。写入工作表是一项耗时的操作,因此这个程序只执行一次,一次写入整个二维数组,而不是逐行编写。因此,无需禁用屏幕更新,计算或其他任何操作。
Function phpStringTo2DArray(ByVal phpString As String) As Variant
Dim iRow As Long
Dim iCol As Long
Dim nCol As Long
Dim nRow As Long
Dim nColMax As Long
Dim lines() As String
Dim splitLines() As Variant
Dim elements() As String
lines = Split(phpString, "[{:#:}]")
nRow = UBound(lines) - LBound(lines) + 1
ReDim splitLines(1 To nRow)
For iRow = 1 To nRow
splitLines(iRow) = Split(lines(iRow - 1), "[|:#:|]")
nCol = UBound(splitLines(iRow)) - LBound(splitLines(iRow)) + 1
' in case rows have different number of columns:
If nCol > nColMax Then nColMax = nCol
Next iRow
Erase lines
'We now have a (Variant) array of arrays. Convert this to a regular 2D array.
ReDim elements(1 To nRow, 1 To nColMax)
For iRow = 1 To nRow
nCol = UBound(splitLines(iRow)) - LBound(splitLines(iRow)) + 1
For iCol = 1 To nCol
elements(iRow, iCol) = splitLines(iRow)(iCol - 1)
Next iCol
Next iRow
Erase splitLines
phpStringTo2DArray = elements
End Function
使用示例:
Dim s As String
Dim v As Variant
s = "1[|:#:|]text-one[|:#:|]code-one[|:#:|]qty-one[{:#:}]2[|:#:|]text-two[|:#:|]code-two[|:#:|]qty-two[{:#:}]"
v = phpStringTo2DArray(s)
'Write to sheet
Range("A1").Resize(UBound(v, 1), UBound(v, 2)) = v
如果你想忽略最后的换行符[{:#:}]
,可以在函数的顶部添加这一行:
If Right(phpString, 7) = "[{:#:}]" Then phpString = Left(phpString, Len(phpString) - 7)
答案 1 :(得分:1)
这并不像我原先想象的那么容易。我可以轻松摆脱一个循环。但是还有一个if测试,所以它不会打破空字符串等。我觉得一个大师可以使这个更有效率。
我担心的是,这个过程需要花费很多时间。如果你想加快速度,那么你的代码看起来效率太低了。 更有可能的是,如果它运行缓慢,那就是application.calculation& application.screenUpdating设置设置不正确。
Sub takePHP(myString As String)
'This sub takes specially formatted strings from a PHP script,
'and parses into rows and columns
Dim myRows As Variant
Dim myCols As Variant
Dim subRow As Variant
Application.ScreenUpdating = False
Application.Calculation = xlCalculateManual
myRows = Split(myString, "[{:#:}]")
x = 1
For Each subRow In myRows
bob = Split(subRow, "[|:#:|]")
If UBound(bob) <> -1 Then
Range(Cells(x, 1), Cells(x, UBound(bob) + 1)).Value = bob
x = x + 1
End If
Next
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub