arrays - 加快我的字符串文本替换代码

标签 arrays excel vba string

作为我之前得到答复的问题的补充,它帮助我在超快的时间内完成了该项目,我现在有一个类似的项目,原始代码已经可以运行并且运行良好,但是,我有两列,其中包含如下内容:

K 列 - ws 和服务器的名称及其 IP 地址(以逗号分隔) L 列 - 仅 IP 地址

在每批名称和 IP 中,或者只是 IP 中,由于各种原因,我不希望出现在最终输出中的范围。

遗憾的是,我无法给出字符串的真实示例,但以下是您可能会发现的示例:

K - Mike [10.6.3.4]、Mike1 [10.2.3.4]、Mike3 [10.165.75.3]......(数量不同) L-10.6.3.4、10.2.3.4、10.165.75.3…………

L 中的 IP 与 K 中的 IP 相同,但顺序不一定相同。

这并不重要。

我编写了以下子程序,它遍历 Excel ws 中的所有行,读取字符串,然后写出相同的字符串,但不包含我不想要的范围(您将看到这些是 10.6. 和 192.168.

正如您将看到的,我为一行中的第一个字符串编写了一个循环,然后根据列为同一行中的第二个字符串编写了第二个循环,我清除了训练逗号(我不知道如何设置新数组,该数组将保存“干净”字符串的结束长度,这样我就会得到一些必须清除的额外逗号),然后我转到下一行直到结束。

效果很好。

我只是有一种感觉,它可以更快、更干净地完成,并且可以在一个循环而不是两个循环中完成,并且可能不会获得需要清理的额外逗号。

如果有人提出任何意见或修复,我将不胜感激。

再说一次,它工作得很好,但如果你明白我的意思的话,感觉“不干净”。

'Sub to remove unwanted IP ranges from both columns
Sub CleanNamesIPsfromList()

    Const Col_Names = "J"
    Const Col_IPs = "K"
    Const ROW_NamesIPs = 5 'First line of Names and IP's

    Dim wb As Workbook
    Dim wsMain As Worksheet
    Dim arHoldNames() As String, arHoldIPs() As String
    Dim arPutNames() As String, arPutIPs() As String
    Dim strHoldNames As String, strHoldIPs As String
    Dim txt106 As String, txt192168 As String
    Dim rn As Long, rhn As Long, ri As Long, rhi As Long, lastrowN As Long, lastrowI As Long, i As Long
    
    txt106 = "10.6."
    txt192168 = "192.168."

    Set wb = ActiveWorkbook
    With wb
        Set wsMain = .Sheets("Main")
    End With

    With wsMain
        lastrowN = .Cells(.Rows.Count, Col_Names).End(xlUp).Row
        lastrowI = .Cells(.Rows.Count, Col_IPs).End(xlUp).Row
        If lastrowN < ROW_NamesIPs Or lastrowI < ROW_NamesIPs Then
            MsgBox "No text found in Columns " & Col_Names & " " & Col_IPs, vbCritical
            Exit Sub
        End If

        'Run through whole ws row by row in both columns
        For i = ROW_NamesIPs To lastrowN
            rhn = 0
            'Load list of names into string holder
            strHoldNames = .Cells(i, Col_Names).Value
            'Split the string into the holding array based on the comma
            arHoldNames = Split(strHoldNames, ",")
            'Loop through the array to find those names not containg unwanted data
            ReDim arPutNames(0 To UBound(arHoldNames))
            For rn = 0 To UBound(arHoldNames)
                If InStr(1, arHoldNames(rn), txt106, vbTextCompare) > 0 Or InStr(1, arHoldNames(rn), txt192168, vbTextCompare) > 0 Then
                    'If it contains unwanted string, increment rn to next array cell and move on
                    rn = rn + 1
                Else
                    'I want this string so put in new array holder and increment array counter
                    arPutNames(rhn) = arHoldNames(rn)
                    rhn = rhn + 1
                End If
            Next 'Loop through array holding origional string
            'I have what I want, so put it back in relevant cell in ws
            .Cells(i, Col_Names).Value = Join(arPutNames, ",")
            'Remove all trailing commas
            While Right(.Cells(i, Col_Names).Value, 1) = ","
                .Cells(i, Col_Names).Value = Left(.Cells(i, Col_Names).Value, Len(.Cells(i, Col_Names).Value) - 1)
            Wend

            rhi = 0
            'Load list of names into string holder
            strHoldIPs = .Cells(i, Col_IPs).Value
            'Split the string into the holding array based on the comma
            arHoldIPs = Split(strHoldIPs, ",")
            'Loop through the array to find those names not containg unwanted data
            ReDim arPutIPs(0 To UBound(arHoldIPs))
            For ri = 0 To UBound(arHoldIPs)
                If InStr(1, arHoldIPs(ri), txt106, vbTextCompare) > 0 Or InStr(1, arHoldIPs(ri), txt192168, vbTextCompare) > 0 Then
                    'If it contains unwanted string, increment ri to next array cell and move on
                    ri = ri + 1
                Else
                    'I want this string so put in new array holder and increment array counter
                    arPutIPs(rhi) = arHoldIPs(ri)
                    rhi = rhi + 1
                End If
            Next 'Loop through array holding origional string
            'I have what I want, so put it back in relevant cell in ws
            .Cells(i, Col_IPs).Value = Join(arPutIPs, ",")
            'Remove all trailing commas
            While Right(.Cells(i, Col_IPs).Value, 1) = ","
                .Cells(i, Col_IPs).Value = Left(.Cells(i, Col_IPs).Value, Len(.Cells(i, Col_IPs).Value) - 1)
            Wend
        
        Next 'Move to next row and repeat untill end
    End With 'End main

End Sub

新代码

好吧,基于将所有数据读入数组,我写了这一段代码(当然是借用betters的)。

    Dim Lastcell As Range
    Set LastCell = .Range("K5:L5").End(xlDown)
    
    'capture all of the data at once with a range-array copy
    Dim arHoldAllNames As String, ArHoldAllIPs As String
    arHoldAllNames = .Range("K5", LastCell).Value
    ArHoldAllIPs = .Range("L5", LastCell).Value

    for i = 0 to UBound(arHoldAllNames, 1)
        'Code for Names
    Next
    for i = 0 to UBound(ArHoldAllIPs, 1)
        'Code for IPs
    Next

    temp = 0
    For i = 5 To LastCell
        .Cells(i, Col_Names).Value = arHoldAllNames(temp)
        .Cells(i, Col_IPs).Value = ArHoldAllIPs(temp)
        i = i + 1
        temp = temp + 1
    Next

这就是你们的意思吗?

此外,我发现我可以将一系列数据读取到数组中,这肯定会加快速度。

这就是这段代码:

    arHoldAllNames = .Range("K5", LastCell).Value
    arHoldAllIPs = .Range("L5", LastCell).Value

然后我可以反转并执行以下操作:

.Range("K5", LastCell).Value = arHoldAllNames 
.Range("L5", LastCell).Value = arHoldAllIPs

并且让 ws 中的所有单元格与数组中的内容进行传播?

或者我还需要执行 For 循环吗:

    temp = 0
    For i = 5 To LastCell
        .Cells(i, Col_Names).Value = arHoldAllNames(temp)
        .Cells(i, Col_IPs).Value = ArHoldAllIPs(temp)
        i = i + 1
        temp = temp + 1
    Next

最佳答案

以下是如何使用范围数组复制进行操作的示例:

'Sub to remove unwanted IP ranges from both columns
Sub CleanNamesIPsfromList()

    Const Col_Names = "J"
    Const Col_IPs = "K"
    Const ROW_NamesIPs = 5 'First line of Names and IP's

    Dim wb As Workbook
    Dim wsMain As Worksheet
    Dim arHoldNames() As String, arHoldIPs() As String
    Dim arPutNames() As String, arPutIPs() As String
    Dim strHoldNames As String, strHoldIPs As String
    Dim txt106 As String, txt192168 As String
    Dim rn As Long, rhn As Long, ri As Long, rhi As Long, lastrowN As Long, lastrowI As Long, i As Long
    
    txt106 = "10.6."
    txt192168 = "192.168."

    Set wb = ActiveWorkbook
    With wb
        Set wsMain = .Sheets("Main")
    End With
    
    Dim NamCel As Variant
    Dim IpCal As Variant

    With wsMain
        lastrowN = .Cells(.Rows.Count, Col_Names).End(xlUp).Row
        lastrowI = .Cells(.Rows.Count, Col_IPs).End(xlUp).Row
        If lastrowN < ROW_NamesIPs Or lastrowI < ROW_NamesIPs Then
            MsgBox "No text found in Columns " & Col_Names & " " & Col_IPs, vbCritical
            Exit Sub
        End If
        
        ' Range-array copy the data into VBA
        NamCel = .Range(Col_Names & "1:" & Col_Names & lastrowN)
        IpCel = .Range(Col_IPs & "1:" & Col_IPs & lastrowI)

        'Run through whole ws row by row in both columns
        For i = ROW_NamesIPs To lastrowN
            rhn = 0
            'Load list of names into string holder
            'strHoldNames = .Cells(i, Col_Names).Value
            strHoldNames = NamCel(i, 1)
            'Split the string into the holding array based on the comma
            arHoldNames = Split(strHoldNames, ",")
            'Loop through the array to find those names not containg unwanted data
            ReDim arPutNames(0 To UBound(arHoldNames))
            For rn = 0 To UBound(arHoldNames)
                If InStr(1, arHoldNames(rn), txt106, vbTextCompare) > 0 Or InStr(1, arHoldNames(rn), txt192168, vbTextCompare) > 0 Then
                    'If it contains unwanted string, increment rn to next array cell and move on
                    rn = rn + 1
                Else
                    'I want this string so put in new array holder and increment array counter
                    arPutNames(rhn) = arHoldNames(rn)
                    rhn = rhn + 1
                End If
            Next 'Loop through array holding origional string
            'I have what I want, so put it back in relevant cell in ws
            '.Cells(i, Col_Names).Value = Join(arPutNames, ",")
            NamCel(i, 1) = Join(arPutNames, ",")
            'Remove all trailing commas
            While Right(NamCel(i, 1), 1) = ","
                NamCel(i, 1) = Left(NamCel(i, 1), Len(NamCel(i, 1)) - 1)
            Wend

            rhi = 0
            'Load list of names into string holder
            strHoldIPs = IpCel(i, 1)
            'Split the string into the holding array based on the comma
            arHoldIPs = Split(strHoldIPs, ",")
            'Loop through the array to find those names not containg unwanted data
            ReDim arPutIPs(0 To UBound(arHoldIPs))
            For ri = 0 To UBound(arHoldIPs)
                If InStr(1, arHoldIPs(ri), txt106, vbTextCompare) > 0 Or InStr(1, arHoldIPs(ri), txt192168, vbTextCompare) > 0 Then
                    'If it contains unwanted string, increment ri to next array cell and move on
                    ri = ri + 1
                Else
                    'I want this string so put in new array holder and increment array counter
                    arPutIPs(rhi) = arHoldIPs(ri)
                    rhi = rhi + 1
                End If
            Next 'Loop through array holding origional string
            'I have what I want, so put it back in relevant cell in ws
            IpCel(i, 1) = Join(arPutIPs, ",")
            'Remove all trailing commas
            While Right(.Cells(i, Col_IPs).Value, 1) = ","
                IpCel(i, 1) = Left(IpCel(i, 1), Len(IpCel(i, 1)) - 1)
            Wend
        
        Next 'Move to next row and repeat untill end
    
        ' Range-array copy the data back out to Excel
        .Range(Col_Names & "1:" & Col_Names & lastrowN) = NamCel
        .Range(Col_IPs & "1:" & Col_IPs & lastrowI) = IpCel
    End With 'End main

End Sub

关于arrays - 加快我的字符串文本替换代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70293218/

相关文章:

python - numpys张量点的向量化计算

vba - 使用VBA在Excel中选择多行

excel - 错误处理减法涉及字符串和数字

java - java中如何判断元素是否在数组中?

c - 如何检查字符串是否包含特定字符?

c - K&R - 第 1.9 节 : understanding character arrays (and incidentally buffers)

java - 在 VBA/Excel 中使用 IKVM 编译的 Java .dll?

regex - 使 Excel 公式将字符串视为正则表达式

vb.net - 从 VB.NET 查找 Excel 中的最后一行

excel:mid:找不到项目或库