【问题标题】:Removing consecutive duplicate values from CSV in Excel Visual Basic在 Excel Visual Basic 中从 CSV 中删除连续的重复值
【发布时间】:2015-03-26 21:09:50
【问题描述】:

在 Excel 2007 VB 宏中,我尝试使用逗号分隔的字符串,将其拆分,然后对其进行缩减,从而删除重复的连续值。所以“2,2,2,1,1”会变成“2,1”,或者“3,3,3,2,3,3,3”会变成“3,2,3”。

看起来它应该可以工作,但是当它到达“If currentVal.equals(prevVal) = False Then”时,它是一个运行时错误 424,“需要对象”。

自从我做任何 VB 以来,这已经是永远,那就是 VP6。

Sheets("Sheet1").Select
Range("I1").Select

Dim data() As String
Dim currentVal, prevVal As String
Dim output As String
Dim temp As Boolean

Do Until Selection.Value = ""
        data = Split(Selection, ",")
        output = ""
        prevVal = ""
        For Each elem In data
            currentVal = CStr(elem)
            If currentVal.equals(prevVal) = False Then
            output = output + elem + ","
            End If
        Next elem
        Selection.Value = output
        Selection.Offset(1, 0).Select
Loop

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    有一些问题。首先,你不能使用:

    Dim currentVal, prevVal As String
    

    你必须使用:

    Dim currentVal as String
    Dim prevVal As String
    

    或:

    Dim currentVal as String, prevVal as String
    

    ...不幸的是,您不能在 VBA 中使用快捷方式类型。其次,字符串不是 VBA 中的对象,因此没有 .equals (或任何其他方法)。你想要:

    If currentVal <> prevVal Then
    

    最后,您需要在循环结束时设置 prevVal,否则您的代码将无法按预期工作。

    编辑这是一些工作代码:

    Dim data() As String
    Dim currentVal As String, prevVal As String
    Dim output As String
    Dim temp As Boolean
    
    Do Until Selection.Value = ""
            data = Split(Selection, ",")
            output = ""
            prevVal = ""
            For Each elem In data
                currentVal = CStr(elem)
                If currentVal <> prevVal Then
                    output = output + elem + ","
                End If
                prevVal = currentVal
            Next elem
            Selection.Value = output
            Selection.Offset(1, 0).Select
    Loop
    

    【讨论】:

    • 是的,意识到最后一点,修复它。还从 IRC chan 获得了 currentVal = prevVal,谢谢。但是,它看起来(在我看来)String 应该是一个对象,并且有 .equals() 方法msdn.microsoft.com/en-us/library/… 当然,这是 VBA,而不是 VB.NET,所以这可能会有所不同。
    • 哦,是的,一切都不同了。 VBA 基于 VB6,与 VB.NET 几乎没有什么共同之处,只是语法有一些相似之处。字符串、布尔值、整数、长整数等数据类型不是 VBA 中的对象,而是将实际数据值保存在内存中,因此没有关联的属性或方法,可以直接比较和操作它们。 String.equals() 在字符串是对象的语言中是必需的,因为变量指向内存地址而不是保存实际值。
    【解决方案2】:

    我建议使用带有正则表达式的变体数组,以最大限度地提高方法的效率和速度。像这样的

    更新:根据我自己的建议,代码现在在应用变量数组之前测试超过 1 个单元格

       Sub Clear()
        Dim ws As Worksheet
        Dim rng1 As Range
        Dim X
        Dim lngRow As Long
        Dim objRegex
        Set objRegex = CreateObject("vbscript.regexp")
        Set ws = Sheets("Sheet1")
        Set rng1 = ws.Range(ws.[i1], ws.Cells(Rows.Count, "I").End(xlUp))
        With objRegex
            .Global = True
            .Pattern = "(\d)(,(\1))+"
            If rng1.Cells.Count > 1 Then
                X = rng1
                For lngRow = 1 To UBound(X)
                    X(lngRow, 1) = .Replace(X(lngRow, 1), "$1")
                Next lngRow
                rng1 = X
            Else
                rng1.Value = .Replace(rng1.Value, "$1")
            End If
        End With
    End Sub
    

    【讨论】:

      【解决方案3】:

      您可以使用字典对象,尤其是因为您要将数字移动到文本文件中,因此它们本身不被视为数字并不重要。见this question

      【讨论】:

      • 是的,我最终修改了代码以使用字典,然后将聚合数据输出到第二张表。实际上,我为自己在 4-5 小时内完成它感到非常自豪!第一次做VBA。
      • 酷。是的,那些字典对象非常方便。加油!
      猜你喜欢
      • 2018-12-01
      • 2015-10-03
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 2017-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多