Excel 在VBA中编写每条语句的更快方法

Excel 在VBA中编写每条语句的更快方法,excel,vba,Excel,Vba,我正在编写VBA代码,用相同的数据填充三个不同的组合框。我只是想知道是否有一种更有效的写作方式,而不是我现在在做什么 ' Create fac1 cbo For Each c_fac In ws_misc.Range("fac") With Me.cbo_fac1 .AddItem c_fac.Value .List(.ListCount - 1, 1) = c_fac.Offset(0, 1).Value End With Next c_fac ' Creat

我正在编写VBA代码,用相同的数据填充三个不同的组合框。我只是想知道是否有一种更有效的写作方式,而不是我现在在做什么

' Create fac1 cbo
For Each c_fac In ws_misc.Range("fac")
    With Me.cbo_fac1
    .AddItem c_fac.Value
    .List(.ListCount - 1, 1) = c_fac.Offset(0, 1).Value
    End With
Next c_fac

' Create fac2 cbo
For Each c_fac In ws_misc.Range("fac")
    With Me.cbo_fac2
    .AddItem c_fac.Value
    .List(.ListCount - 1, 1) = c_fac.Offset(0, 1).Value
    End With
Next c_fac

' Create fac3 cbo
For Each c_fac In ws_misc.Range("fac")
    With Me.cbo_fac3
    .AddItem c_fac.Value
    .List(.ListCount - 1, 1) = c_fac.Offset(0, 1).Value
    End With
Next c_fac

谢谢你抽出时间

你为什么不能这样做

' Create fac1 cbo
For Each c_fac In ws_misc.Range("fac")
    With Me.cbo_fac1
        .AddItem c_fac.Value
        .List(.ListCount - 1, 1) = c_fac.Offset(0, 1).Value
    End With
    With Me.cbo_fac2
        .AddItem c_fac.Value
        .List(.ListCount - 1, 1) = c_fac.Offset(0, 1).Value
    End With
    With Me.cbo_fac3
        .AddItem c_fac.Value
        .List(.ListCount - 1, 1) = c_fac.Offset(0, 1).Value
    End With
Next c_fac

这将使您在工作表范围内循环所需的时间减少2/3。通常,在Excel VBA代码中,读取和写入实际的Excel工作表对象花费的时间最多。

我个人不喜欢在这种情况下使用
。它将代码行数增加了一倍,几乎没有任何好处。您可以将其缩减到:

' Create fac1 cbo
For Each c_fac In ws_misc.Range("fac")

    Me.cbo_fac1.AddItem c_fac.Value
    Me.cbo_fac1.List(Me.cbo_fac1.ListCount - 1, 1) = c_fac.Offset(0, 1).Value

    Me.cbo_fac2.AddItem c_fac.Value
    Me.cbo_fac2.List(Me.cbo_fac2.ListCount - 1, 1) = c_fac.Offset(0, 1).Value

    Me.cbo_fac3.AddItem c_fac.Value
    Me.cbo_fac3.List(Me.cbo_fac3.ListCount - 1, 1) = c_fac.Offset(0, 1).Value

Next c_fac

更进一步,可能是:

dim lLoop as long
' Create fac1 cbo
For Each c_fac In ws_misc.Range("fac")
    For lLoop=1 to 3
        Me.controls("cbo_fac" & lLoop).AddItem c_fac.Value
        Me.controls("cbo_fac" & lLoop).List(Me.controls("cbo_fac" & lLoop).ListCount - 1, 1) = c_fac.Offset(0, 1).Value
    next lLoop
Next c_fac
这会快得多(假设“fac”是一列)。对于>5个条目,AddItem非常慢:

Dim rng
rng = ws_misc.Range("fac").resize(,2).value
Me.cbo_fac1.List = rng
Me.cbo_fac2.List = rng
Me.cbo_fac3.List = rng

为了获得更好的性能,您可以将
c_fac.Offset(0,1).Value
存储在一个变量中,而不是三次检索它。如果您想从中获取所有可能的性能,您可以将整个范围分配给一个数组,但在大多数情况下,您很难看到任何差异。是的,但是你不需要添加太多的条目,就可以在使用时注意到性能下降。additem,通常最好不要使用additem。很好的回答,我记不起我了。controls~这是我唯一一次动态循环处理像这样的对象,有人将它们构建到工作表中,所以我不得不使用“.OleObjects().Object.`而不是
.Controls()。
除非你真的有很多对象,否则通过这样的循环调用它们是没有意义的,但它已经为我提供了很多次了。很好,但是为什么不把范围值分配给组合框列表呢?Additem非常慢