简体   繁体   English

Excel VBA工作表更改效率

[英]Excel VBA Worksheet Change Efficiency

I have a worksheet with several worksheet change events. 我有一个带有几个工作表更改事件的工作表。 Unfortunately, I am getting some memory errors due to them. 不幸的是,由于它们,我遇到了一些内存错误。 I was wondering if anyone could look at this code snippet and let me know if it could be written more efficiently? 我想知道是否有人可以看一下此代码片段,并让我知道是否可以更高效地编写它?

This worksheet change event calls another macro if and only if cell K4 = "Event Based" and every one of the following cells have something in them: J12:J15, M12:M14. 当且仅当单元格K4 =“基于事件”并且以下每个单元格中包含某些内容时,此工作表更改事件才调用另一个宏:J12:J15,M12:M14。 I can call the macro if cells J12:J15, M12:M14 are already filled in and K4 is changed to "Event Based" 如果单元格J12:J15,M12:M14已经填写并且K4更改为“基于事件”,则可以调用宏

Private Sub Worksheet_Change(ByVal Target As Range)
If Range("J12") <> "" And _
Range("J13") <> "" And _
Range("J14") <> "" And _
Range("J15") <> "" And _
Range("M12") <> "" And _
Range("M13") <> "" And _
Range("M14") <> "" Then
Dim ZRange As Range
Set ZRange = Range("K4")
If ZRange = "Event Based" Then
If Union(Target, ZRange).Address = ZRange.Address Then
Application.EnableEvents = False
Call EventBasedYes
Application.EnableEvents = True

End If
End If
End If

My problem is, I have written a different worksheet change event for each individual cell. 我的问题是,我为每个单元格编写了一个不同的工作表更改事件。 The following fires if K4="Event Based" and J13:J15 have something in them and then data is addded to J12 如果K4 =“基于事件”和J13:J15中包含某些内容,然后将数据添加到J12中,则会触发以下事件

If Range("K4") = "Event Based" And _
Range("J13") <> "" And _
Range("J14") <> "" And _
Range("J15") <> "" And _
Range("M12") <> "" And _
Range("M13") <> "" And _
Range("M14") <> "" Then
Dim FRange As Range
Set FRange = Range("J12")
If FRange <> "" Then
If Union(Target, FRange).Address = FRange.Address Then
Application.EnableEvents = False
Call EventBasedYes
Application.EnableEvents = True

End If
End If
End If

I don't know how to write ONE event such that if all cells are filled, the macro is called and such that if any one cell is cleared, a macro named EventBasedNo. 我不知道如何编写一个事件,以便如果所有单元格都已填充,则将调用宏,如果清除了任何一个单元格,则将创建一个名为EventBasedNo的宏。 Sorry, I am not very experienced with VBA code. 抱歉,我对VBA代码不是很有经验。 I'm sure there's a way to do this. 我敢肯定有办法做到这一点。

Regarding speed improvements: 关于速度改进:

One thing you could do would be to not execute a lot of tests on cell values unless you know that there is a possibility that you are going to need to do that test. 您可以做的一件事是,不对单元格值执行大量测试,除非您知道有可能需要执行该测试。

So your current code says: 所以您当前的代码说:

If Range("J12") <> "" And _
   Range("J13") <> "" And _
   Range("J14") <> "" And _
   Range("J15") <> "" And _
   Range("M12") <> "" And _
   Range("M13") <> "" And _
   Range("M14") <> "" Then
    Dim ZRange As Range
    Set ZRange = Range("K4")
    If ZRange = "Event Based" Then
        If Union(Target, ZRange).Address = ZRange.Address Then
            Application.EnableEvents = False
            Call EventBasedYes
            Application.EnableEvents = True
        End If
    End If
End If

which means that you are looking up the values of J12 , J13 , J14 , J15 , M12 , M13 , M14 and K4 , and then deciding whether the worksheet change happened in a cell you are interested in. 这意味着您正在查找J12J13J14J15M12M13M14K4然后确定工作表更改是否在您感兴趣的单元格中发生。

By moving the test regarding Target 's location earlier, you can save those lookups: 通过较早移动有关Target位置的测试,可以保存这些查找:

If Not Application.Intersect(Target, Range("K4")) Is Nothing Then
    If Range("J12") <> "" And _
       Range("J13") <> "" And _
       Range("J14") <> "" And _
       Range("J15") <> "" And _
       Range("M12") <> "" And _
       Range("M13") <> "" And _
       Range("M14") <> "" Then
        Dim ZRange As Range
        Set ZRange = Range("K4")
        If ZRange = "Event Based" Then
            Application.EnableEvents = False
            Call EventBasedYes
            Application.EnableEvents = True
        End If
    End If
End If

If a lot of the cells you are checking are likely to be part of the Target of a single Worksheet_Change event then you may be better off testing for all the cells you are interested in first, ie using something like: 如果您要检查的许多单元格可能是单个Worksheet_Change事件的“ Target的一部分,那么最好先对所有您感兴趣的单元格进行测试,即使用类似方法:

If Not Application.Intersect(Target, Range("K4,J12,X47")) Is Nothing Then

and then storing the values of the cells that you are frequently referring to in variables (or a Variant array if they are in a contiguous block?) so that you can refer to the variables multiple times rather than have to access the cell itself multiple times. 然后将您经常引用的单元格的值存储在变量中(如果它们在连续的块中,则存储为Variant数组?),以便您可以多次引用变量,而不必多次访问单元格本身。


PS Union(Target, ZRange).Address = ZRange.Address is equivalent to Target.Address = ZRange.Address . PS Union(Target, ZRange).Address = ZRange.Address等效于Target.Address = ZRange.Address Is it intentional that your code only fires if a single cell is changed (ie you don't want the code to run if cells K2:K6 are changed in a single event, only if K4 is changed by itself)? 是否有意仅在更改单个单元格时才触发代码(即,如果在单个事件中更改了单元格K2:K6,并且仅在K4自身发生更改的情况下,您不希望代码运行)? My proposed change uses an Intersect , which will run if the changed range includes the cell you are interested in, so you should change that back if you don't want that to happen. 我建议的更改使用一个Intersect ,如果更改的范围包括您感兴趣的单元格,它将运行,因此,如果您不希望发生这种情况,应将其改回。


Possible rewrite 可能重写

I think I understand what you are trying to do. 我知道您要做什么。 Perhaps the following code will do all your tests at once: 也许以下代码可以一次完成所有测试:

If Not Application.Intersect(Target, Range("K4,J12:J15,M12:M14")) Is Nothing Then
    Application.EnableEvents = False
    If Range("J12").Value <> "" And _
       Range("J13").Value <> "" And _
       Range("J14").Value <> "" And _
       Range("J15").Value <> "" And _
       Range("M12").Value <> "" And _
       Range("M13").Value <> "" And _
       Range("M14").Value <> "" And _
       Range("K4").Value = "Event Based" Then
        Call EventBasedYes
    Else
        Call EventBasedNo
    End If
    Application.EnableEvents = True
End If

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

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