VBA唯一值数组未获取某些数字

时间:2018-10-04 02:51:09

标签: vba excel-vba

我编写了一些代码,该代码扫描数字列表并将唯一值存储在数组中。数字范围从1到12(它们代表月份,并按顺序排序),如下所示:

A |  10  10  10  11  11 12 12 12 12 1个 1个 1个 2 2 3 3 4 4 4 5 5 等

数字在第一列中,从第2行到每张纸的最后一行。我遇到的问题是数字1和2没有存储在数组中。在我的电子表格上运行以下代码时,该数组存储为:

10 | 11 | 12 | 3 | 4 | 5等等(如果还有更多月份)

我不确定为什么会发生这种情况-我怀疑是因为1和2之前的月份是12,其中包含数字1和2。但是,我不确定代码为什么会跳过它,或者如何跳过要解决这个问题。任何帮助或建议,将不胜感激。

Dim i as integer
Dim tmp as string, msg as string, arr as string
Dim ws as worksheet
Dim lastrow as long

Set ws = ActiveSheet
lastrow = ws.Cells(Rows.Count, 1).End(xlUp).Row

    For Each cell In ws.Range("I2:I" & lastrow)
        If (cell <> "") And (InStr(tmp, cell) = 0) Then
            tmp = tmp & cell & "|"
        End If
    Next cell

If Len(tmp) > 0 Then tmp = Left(tmp, Len(tmp) - 1)
    arr = Split(tmp, "|")
        For i = LBound(arr) To UBound(arr)
            msg = msg & arr(i) & vbNewLine
        Next i

3 个答案:

答案 0 :(得分:1)

我猜您的问题是(如comments中所述),因为您正在构建一个看起来像这样的字符串:

10 | 11 | 12

但是在测试您正在使用的字符串时:

InStr(tmp, cell) = 0

如果cell包含1,则InStr(tmp, cell)将不返回0,因为1已包含在组合字符串中(作为一部分101112中的一个。

您可以通过如下构建字符串来解决此问题:

|10|11|12|

然后检查:

InStr(tmp, "|" & cell & "|") = 0

InStr仅在用竖线字符(|)包围时才匹配单元格值。


但是,我认为一个更简单的解决方案是使用Scripting.Dictionary来建立唯一编号的列表:

Dim ws As Worksheet
Dim lastrow As Long
Dim cell As Variant

' Add a reference (Tools -> References...) to Microsoft Scripting Runtime
Dim dict as New Scripting.Dictionary

Set ws = ActiveSheet
lastrow = ws.Cells(Rows.Count, 1).End(xlUp).Row

For Each cell In ws.Range("I2:I" & lastrow)
    If cell.Value <> "" Then
        dict(cell.Value) = 1 ' dummy value; we're only interested in the dictionary keys
    End If
Next cell

,然后将Join函数与字典的Keys集合一起使用,以创建一个带分隔符的值的字符串:

Dim msg As String
msg = Join(dict.Keys, vbNewLine)

之所以可行,是因为字典仅保留给定键的单个键/值条目。

答案 1 :(得分:0)

尝试一下。

Sub test()
    Dim i As Integer
    Dim tmp As String, msg As String, arr As Variant
    Dim ws As Worksheet
    Dim lastrow As Long
    Dim dic As Object
    Dim s As String
    Set ws = ActiveSheet

    Set dic = CreateObject("Scripting.Dictionary")

    Set ws = ActiveSheet
    lastrow = ws.Cells(Rows.Count, 1).End(xlUp).Row

        For Each cell In ws.Range("I2:I" & lastrow)
            'If (cell <> "") And (InStr(tmp, cell) = 0) Then
            If cell <> "" Then
                s = CStr(cell)
                If dic.Exists(s) Then
                Else
                    dic.Add s, s
                    tmp = tmp & cell & "|"
                End If
            End If
        Next cell

    If Len(tmp) > 0 Then tmp = Left(tmp, Len(tmp) - 1)
        arr = Split(tmp, "|")
            For i = LBound(arr) To UBound(arr)
                msg = msg & arr(i) & vbNewLine
            Next i


End Sub

答案 2 :(得分:0)

或者如果您要使用数组而不是字典对象,则这样...

Option Explicit

Public Sub Process()

    Dim i As Long
    Dim msg As String
    Dim arr() As String
    Dim ws As Worksheet
    Dim lastrow As Long
    Dim cell As Variant
    Dim FoundAt As Long

    Set ws = ActiveSheet
    lastrow = ws.Cells(1048576, "I").End(xlUp).Row

    For Each cell In ws.Range("I2:I" & lastrow)
        If (cell <> "") Then

            FoundAt = -1
            If Len(Join(arr)) > 0 Then
                For i = LBound(arr) To UBound(arr)
                    If arr(i) = cell Then FoundAt = i
                Next
            End If

            If FoundAt = -1 Then
                If Len(Join(arr)) > 0 Then
                    ReDim Preserve arr(UBound(arr) + 1)
                Else
                    ReDim arr(1)
                End If
                arr(UBound(arr)) = cell
            End If

        End If
    Next cell

    For i = LBound(arr) To UBound(arr)
        msg = msg & arr(i) + vbCrLf
    Next

    MsgBox msg

End Sub

enter image description here