简体   繁体   English

使用For Each(Excel VBA)在目标数组中的位置

[英]Position in Target Array using For Each (Excel VBA)

I am trying to trap the changes that a user makes on a sheet. 我试图捕获用户在工作表上所做的更改。

I have my worksheet_change event setup but the issue is what if the Target.Range is larger than a single cell? 我有我的worksheet_change事件设置,但问题是,如果Target.Range大于单个单元格呢?

Basically, I need to evaluate each and every cell change to test for validity using a function. 基本上,我需要评估每个单元格更改以使用功能测试有效性。 My issue is the Target.Range can be any size of course and the function to test for validity looks at the surrounding cells. 我的问题是Target.Range可以是任意大小的课程,用于测试有效性的函数会查看周围的单元格。

I was trying to trap the addresses of the changed cells using something like this: 我正在尝试使用以下方法捕获更改的单元格的地址:

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

That way I can trap the cells' address and then use aCell.Row or aCell.Column, etc. but this fails if the Target.Range is bigger than 2 columns since the i index grows faster than it should. 这样,我可以捕获单元格的地址,然后使用aCell.Row或aCell.Column等,但是如果Target.Range大于2列,则此操作将失败,因为i索引的增长快于其应有的速度。

Is there anyway to find the position of "aCell" in the Target range as it is looped by the For Each? 无论如何,因为For Each循环了“ aCell”在目标范围中的位置? Or is it just best to trust that For Each always goes 1,1 1,2 1,3 2,1 2,2, etc.? 还是最好只相信For Each总是1,1 1,2 1,3 2,1 2,2等?

Any better methods? 有更好的方法吗? Maybe just copy the address of each aCell into a 1D array that is equal to rows*columns of the Target.Range that way the i/j indexes are irrelevant - and then process this 1D array instead of a 2D array? 也许只是将每个aCell的地址复制到与Target的row * columns相等的一维数组中,使i / j索引不相关-然后处理此一维数组而不是二维数组?

Thanks, BT 谢谢,BT

More info about what you need to do with the arrays and how you are doing it would help. 有关您需要对阵列做些什么以及如何做的更多信息将有所帮助。 But as for what you posted... Something like you suggested, using 1D arrays, should do the trick : 但是关于您发布的内容...使用一维数组的类似建议应该可以解决问题:

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

Or you could put the aCell.Address and aCell.Value2 into one 2D array. 或者,您可以将aCell.Address和aCell.Value2放入一个2D数组中。

Thanks to all for the suggestions. 感谢所有的建议。 I just went ahead and took my own advice and went with the 1D array to store the addresses of the changed cells. 我只是继续听取了自己的建议,并使用了1D数组来存储更改后的单元格的地址。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM