我编写了一些代码,该代码扫描数字列表并将唯一值存储在数组中。数字范围从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
答案 0 :(得分:1)
我猜您的问题是(如comments中所述),因为您正在构建一个看起来像这样的字符串:
10 | 11 | 12
但是在测试您正在使用的字符串时:
InStr(tmp, cell) = 0
如果cell
包含1
,则InStr(tmp, cell)
将不返回0
,因为1
已包含在组合字符串中(作为一部分10
,11
或12
中的一个。
您可以通过如下构建字符串来解决此问题:
|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