使用VBA将数据string拆分为列AND行
我正在尝试加快正在运行的自动化工作簿。
PHP向VBA发送类似于下面的string:
1[|:#:|]text-one[|:#:|]code-one[|:#:|]qty-one[{:#:}] 2[|:#:|]text-two[|:#:|]code-two[|:#:|]qty-two[{:#:}]
哪里
-
[|:#|]
代表“新列” -
[{:#:}]
代表“新行”
当它被VBAparsing时,这是输出:
我目前使用下面的VBA代码来parsing这个工作簿:
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, "[|:#:|]"),"[{:#:}]")
最好的办法是在原生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)
这并不像我原先想象的那么容易。 我可以很容易地摆脱一个循环。 但是还有一个如果testing,所以它不会打破空弦等。我觉得上师可以使这更有效率。
我担心的是,这个过程需要花费很多时间。 如果你正在努力加快速度,你的代码看起来并不是非常低效。 更有可能,如果它运行缓慢,是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