【问题标题】:Position in Target Array using For Each (Excel VBA)使用 For Each (Excel VBA) 在目标数组中定位
【发布时间】:2015-05-08 06:31:13
【问题描述】:

我试图捕捉用户在工作表上所做的更改。

我设置了 worksheet_change 事件,但问题是如果 Target.Range 大于单个单元格怎么办?

基本上,我需要评估每个单元格更改以使用函数测试有效性。我的问题是 Target.Range 当然可以是任何大小,并且测试有效性的功能会查看周围的单元格。

我试图使用类似这样的方法来捕获更改单元格的地址:

i = 1
j = 1

For Each aCell In Target
    DiffAddys(i, j) = aCell.Address
    NewValues(i, j) = aCell.Value2
    If i < Target.Rows.Count Then i = i + 1
    If j < Target.Columns.Count Then j = j + 1
Next

这样我可以捕获单元格的地址,然后使用 aCell.Row 或 aCell.Column 等,但如果 Target.Range 大于 2 列,则会失败,因为 i 索引的增长速度超过了应有的速度。

有没有在目标范围内找到“aCell”的位置,因为它是由 For Each 循环的?还是最好相信 For Each 总是 1,1 1,2 1,3 2,1 2,2 等等?

还有更好的方法吗?也许只需将每个 aCell 的地址复制到等于 Target.Range 的行*列的一维数组中,这样 i/j 索引就无关紧要了——然后处理这个一维数组而不是二维数组?

谢谢, 英国电信

【问题讨论】:

  • 这不是你的问题,但你不能只是if target.cells.count &gt; 1 then ...吗?或使用worksheet_selectionchange(byval target as range
  • 要获得更准确的答案,请显示用于处理更改的单元格并测试有效性的函数代码。在分析它如何查看周围的单元格后,可以选择最合适的数组结构。

标签: arrays vba excel


【解决方案1】:

更多关于你需要对数组做什么以及你是如何做的信息会有所帮助。但是至于您发布的内容...您建议的使用一维数组的方法应该可以解决问题:

Private Sub Worksheet_Change(ByVal Target As Range)

Dim DiffAddys() As String, NewValues() As Variant

Application.EnableEvents = False

ReDim DiffAddys(Target.Cells.Count)
ReDim NewValues(Target.Cells.Count)

i = 1 'it is generaly not recommended to start array indexes on 1

For Each aCell In Target.Cells

    DiffAddys(i) = aCell.Address
    NewValues(i) = aCell.Value2
    i = i + 1

Next aCell

Application.EnableEvents = True

End Sub

或者您可以将 aCell.Address 和 aCell.Value2 放入一个二维数组中。

【讨论】:

    【解决方案2】:

    感谢大家的建议。我只是继续并接受了我自己的建议,并使用一维数组来存储更改单元格的地址。

    If Range("aq" & Target.Row).Value <> "p" And Target.Cells.Count <= 1 Then 
        Range("aq" & Target.Row).Value = 1
        Application.EnableEvents = True
        Exit Sub
    End If
    
    Application.ScreenUpdating = False
    
    ReDim OldValues(1 To (Target.Rows.Count * Target.Columns.Count))
    ReDim NewValues(1 To (Target.Rows.Count * Target.Columns.Count))
    ReDim DiffAddys(1 To (Target.Rows.Count * Target.Columns.Count))
    
    i = 1
    
    For Each aCell In Target
        DiffAddys(i) = aCell.Address
        NewValues(i) = aCell.Value2
        If i < (Target.Rows.Count * Target.Columns.Count) Then i = i + 1
    Next
    
    Application.Undo 'turn back time
    
    For i = 1 To UBound(NewValues, 1) 'rows
            OldValues(i) = Sheet5.Range(DiffAddys(i)).Value
    Next i
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多