我正在尝试编写查看数组“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
非常感谢。
答案 0 :(得分:3)
@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
在添加键/值对或迭代词典时重复使用相同的键变量。
dic.Add Key,1
对于dic中的每个键
您可以使用加入将所有键和项打印到即时窗口。
Debug.Print" Keys:&#34 ;;加入(dic.Keys(),",")
Debug.Print" Items:&#34 ;;加入(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
答案 1 :(得分:2)
您需要声明字典对象。
我们声明字典如下:
Dim dict As New Scripting.Dictionary
或
Dim dict As Scripting.Dictionary Set dict = New Scripting.Dictionary
有关在VBA at this site中设置和使用词典的更多信息。
另外,根据经验,在每个模块的顶部使用Option Explicit
(特别是在排除故障时),以确保您的变量和对象都设置正确。
答案 2 :(得分:1)
您可以使用为字典分配值的简化形式:
dic("key1") = dic("key1") + 1
答案 3 :(得分:0)
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
或者你也可以使用以下方法来获得所需的输出......
import javax.swing.*;
import java.awt.*;
public class GridBagTest {
private static JFrame myFrame;
private static JPanel mainPanel;
public static void main(String[] args) {
createFrame();
createPanels();
constructCells();
myFrame.pack();
myFrame.setVisible(true);
}
private static void createFrame() {
myFrame = new JFrame();
myFrame.setPreferredSize(new Dimension(800, 800));
myFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
myFrame.setTitle("Simulator");
myFrame.setResizable(true);
}
private static void createPanels() {
mainPanel = new JPanel(new BorderLayout(10, 10));
myFrame.getContentPane().add(mainPanel);
}
private static void constructCells() {
for (int i = 0; i < 3; i++) {
mainPanel.add(new Cell(i + 1), choosePosition(i + 1));
}
}
private static String choosePosition(int number) {
switch (number) {
case 1:
return BorderLayout.EAST;
case 2:
return BorderLayout.CENTER;
case 3:
return BorderLayout.WEST;
}
return null;
}
}
答案 4 :(得分:0)
最终代码结束了:
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
End Sub
答案 5 :(得分:-1)
使用c.value意味着您将其视为范围对象并访问其“值”属性 - 您的代码将允许您将其作为c声明为变体。
但是,我认为你正在做的是循环遍历数组中的每个元素 - 在这种情况下你不应该使用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
未经测试,写在手机上。