我正在尝试编写查看数组“arr”的代码,然后循环遍历该数组中的每个值以与新创建的字典进行比较。如果密钥已经存在,则密钥的值(计数)应该增加1,否则密钥应该添加值1。
但是,下面的行是抛出一个Object Required错误:
If dic.Exists(c.Value) Then ' Runtime Error 424: Object Required
整个子目录如下:
Private Sub PODic()
Dim arr As Variant
Dim Counter As Long
Dim dic As Object
Dim lrow As Long
Dim c As Variant
Set dic = CreateObject("Scripting.Dictionary") ' late bind
dic.CompareMode = vbTextCompare
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
lrow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 4).End(xlUp).row
lrow = lrow - 1
Debug.Print lrow
arr = ActiveSheet.Range("d2", ActiveSheet.Cells(lrow, "d")).Value
For Each c In arr
Debug.Print c
If dic.Exists(c.Value) Then ' Runtime Error 424: Object Required
dic(c.Value) = dic(c.Value) + 1
Else
dic.Add c.Value, 1
End If
Next
For Each k In dic
Debug.Print k & "," & dic(k)
Next k
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "Populate dictionary macro complete."
End Sub
我相信这可能与用于c的变量类型(或者可能是dic)有关,但我无法弄清楚问题出在哪里。我也尝试通过创建On Error GoTo来解决这个问题,但是遇到了同样的问题。
On Error GoTo ERRINCVAL
dic.Add cell.Value, 1
On Error GoTo 0
ERRINCVAL:
dic(c.Value) = dic(c.Value) + 1 ' Same error thrown on this line, if I try to use GoTo instead of If
Resume Next
非常感谢帮助。
c.value
在这里没有意义。 c
这里是item
的array
所以你可以直接参考它。
你应该这样试试......
For Each c In arr
Debug.Print c
If dic.Exists(c) Then
dic(c) = dic(c) + 1
Else
dic.Add c, 1
End If
Next
或者你也可以使用以下方法来获得所需的输出......
Dim i As Long
arr = ActiveSheet.Range("d2", ActiveSheet.Cells(lrow, "d")).Value
For i = 1 To UBound(arr, 1)
Debug.Print arr(i, 1)
If dic.Exists(arr(i, 1)) Then ' Runtime Error 424: Object Required
dic(arr(i, 1)) = dic(arr(i, 1)) + 1
Else
dic.Add arr(i, 1), 1
End If
Next
@sktneer有正确的答案。我只是想展示一种更清晰的写作方式。
使用With语句可以使代码更具可读性并且更高效。
没有理由拥有Last Row变量。
范围(“D2”,单元格(Rows.Count,“D”)。结束(xlUp))。值
没有必要使用临时数组变量在For Each循环中使用。 VBA将在初始化循环时自动创建一个。
对于每个键入.Range(“D2”,。细胞(.Rows.Count,“D”)。结束(xlUp))。值
无需测试密钥是否存在,然后添加值为1的密钥或增加现有密钥。 VBA将自动创建它不存在的密钥。
dic(Key)= dic(Key)+ 1
添加键/值对或迭代字典时重用相同的Key变量。
dic.Add Key,1
对于dic中的每个键
您可以使用“连接”将所有键和项目打印到即时窗口。
Debug.Print“Keys:”;加入(dic.Keys(),“,”)
Debug.Print“Items:”;加入(dic.Items(),“,”)
Private Sub PODic()
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
Dim dic As Object, Key As Variant
Set dic = CreateObject("Scripting.Dictionary")
dic.CompareMode = vbTextCompare
With ActiveSheet
For Each Key In .Range("D2", .Cells(.Rows.Count, "D").End(xlUp)).Value
dic(Key) = dic(Key) + 1
Next
End With
Debug.Print "Keys: "; Join(dic.Keys(), ",")
Debug.Print "Items: "; Join(dic.Items(), ",")
For Each Key In dic
Debug.Print Key & "," & dic(Key)
Next
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
MsgBox "Populate dictionary macro complete."
End Sub
您需要声明字典对象。
我们声明字典如下:
Dim dict As New Scripting.Dictionary
要么
Dim dict As Scripting.Dictionary Set dict = New Scripting.Dictionary
有关在VBA at this site中设置和使用词典的更多信息。
另外,根据经验,在每个模块的顶部使用Option Explicit
(特别是在排除故障时),以确保您的变量和对象都已正确设置。
您可以使用简化的形式为字典赋值:
dic("key1") = dic("key1") + 1
最终代码最终:
Private Sub PODic()
Dim arr As Variant
Dim Counter As Long
Dim lrow As Long
Dim c As Variant
Dim dic As Object
Set dic = CreateObject("Scripting.Dictionary") ' late bind
dic.CompareMode = vbTextCompare
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
lrow = ActiveSheet.Cells(ActiveSheet.Rows.Count, 4).End(xlUp).row
lrow = lrow
Debug.Print lrow
Dim i As Long
arr = ActiveSheet.Range("d2", ActiveSheet.Cells(lrow, "d")).Value
For i = 1 To UBound(arr, 1)
Debug.Print arr(i, 1)
If dic.Exists(arr(i, 1)) Then
dic(arr(i, 1)) = dic(arr(i, 1)) + 1
Else
dic.Add arr(i, 1), 1
End If
Next
For Each k In dic
Debug.Print k & "," & dic(k)
Next k
Debug.Print dic.Count
With Application
.ScreenUpdating = True
.Calculation = xlCalculationAutomatic
End With
结束子
使用c.value意味着你将它视为一个范围对象并访问它的'value'属性 - 你的代码将允许你这样做,因为c被声明为variant。
但是,我认为你正在做的是循环遍历数组中的每个元素 - 在这种情况下你不应该使用c.value,只能使用c。
我认为最好使用数组的ubound和lbound之间的for-next循环遍历数组。
所以尝试:
Dim Index as Long
For Index = lbound(arr,1) to ubound(arr,1)
If dic.Exists(arr(Index,1)) Then
' Array arr is 1-based but items in dic might be 0-based, so adjust if necessary'
dic(arr(Index-1,1)) = dic(arr(Index-1,1)) + 1
' if dic is not 0-based, get rid of the -1 above.'
Else
dic.Add arr(Index,1), 1
End If
Next index
未经测试,写在手机上。