Excel VBA防止在单击每个单元格时刷新/执行选择更改

Excel VBA防止在单击每个单元格时刷新/执行选择更改,excel,vba,Excel,Vba,我创建了下面的子例程,目的是在从单元格(2,3)上的数据验证列表下拉列表中选择一个项目时执行宏。我创建了一个模板,用于比较预测值与实际值以及差异部分。预测在顶部,实际在中间,方差在底部。每个部分包含相同的子市场名称列表。如果单元格(2,3)为空,则查看所有数据。如果选择了某个项目,则除所选子市场外,所有行都将隐藏。最终用户将在屏幕上看到带有标题和标题的预测、实际值和差异行,以便进行简单分析,并使其成为一个用户友好的工具。它工作正常,但在任何时候通过鼠标或键盘选择任何单元格时,子例程似乎都会执行/

我创建了下面的子例程,目的是在从单元格(2,3)上的数据验证列表下拉列表中选择一个项目时执行宏。我创建了一个模板,用于比较预测值与实际值以及差异部分。预测在顶部,实际在中间,方差在底部。每个部分包含相同的子市场名称列表。如果单元格(2,3)为空,则查看所有数据。如果选择了某个项目,则除所选子市场外,所有行都将隐藏。最终用户将在屏幕上看到带有标题和标题的预测、实际值和差异行,以便进行简单分析,并使其成为一个用户友好的工具。它工作正常,但在任何时候通过鼠标或键盘选择任何单元格时,子例程似乎都会执行/刷新。此外,在单元格(2,3)的下拉列表中选择项目时,子例程将不会执行。仅当再次单击图纸上的任意位置时,才会执行该命令

我已经读了两个多小时的书,试图找到一个解决方案,来防止在每次点击工作表时执行/刷新子程序。子例程的目标是仅当在单元格(2,3)中的下拉列表中选择某个项目或在单元格(2,3)中清除该项目时才执行。我会继续阅读,但我想把问题贴出来,看看我在研究的时候是否能得到答案。提前感谢您提供的任何帮助

Private Sub Worksheet_SelectionChange(ByVal Target As Range)


Dim Wk2 As Worksheet
Set Wk2 = Sheets("By SubMarket")

Application.ScreenUpdating = False

With Wk2

Set Target = Cells(2, 3)

'If the cell with the drop-down data validation list is blank then unhide all rows -- effectively show all data
If Target = "" Then

Wk2.Cells.Rows.Hidden = False

Else
'Goal:  Hide all rows and only leave the rows related to the submarket selected on the drop down for each section
'       This is down so the end-user can drill down and view a specific market easily FCST vs. Actual vs. Variance
Wk2.Cells.Rows.Hidden = False

'define the header row of the Forecast section
'define the first row of data in the Forecast section
'define the last row of data in the Forecast section

Dim hRowFcst As Long
Dim fRowFcst As Long
Dim lRowFcst As Long

hRowFcst = Cells.Find("FCST", LookAt:=xlWhole).Offset(1, 0).Row
fRowFcst = Cells.Find("FCST", LookAt:=xlWhole).Offset(2, 0).Row
lRowFcst = Cells.Rows(hRowFcst).Find("State", LookAt:=xlWhole).End(xlDown).Row

'define the header row of the Actuals section
'define the first row of data in the Actuals section
'define the last row of data in the Actuals section
Dim hRowAct As Long
Dim fRowAct As Long
Dim lRowAct As Long

hRowAct = Cells.Find("ACT", LookAt:=xlWhole).Offset(1, 0).Row
fRowAct = Cells.Find("ACT", LookAt:=xlWhole).Offset(2, 0).Row
lRowAct = Cells.Rows(hRowAct).Find("State", LookAt:=xlWhole).End(xlDown).Row

'define the header row of the Variance section
'define the first row of data in the Variance section
'define the last row of data in the Variance section

Dim hRowVar As Long
Dim fRowVar As Long
Dim lRowVar As Long

hRowVar = Cells.Find("Over/(Under)", LookAt:=xlWhole).End(xlUp).Row
fRowVar = Cells.Rows(hRowVar).Offset(1, 0).Row
lRowVar = Cells.Find("Over/(Under)", LookAt:=xlWhole).Offset(-1, 0).Row


'define the Total row of the Forecast section
'define the Total row of data in the Actuals section
'define the Total row of data in the Variance section
Dim tRowFcst As Long
Dim tRowAct As Long
Dim tRowVar As Long

tRowFcst = Cells.Rows(lRowFcst).Offset(1, 0).Row
tRowAct = Cells.Rows(lRowAct).Offset(1, 0).Row
tRowVar = Cells.Rows(lRowVar).Offset(1, 0).Row


Dim StateCol As Long
Dim SubMktCol As Long
'Dim Month Col As Long -- See how to make choosing a period dynamic <will define later>

StateCol = Cells.Find("State", LookAt:=xlWhole).Column
SubMktCol = Cells.Find("Sub-Market", LookAt:=xlWhole).Column

'Define the range of all the submarkets listed in the Forecast section
'Define the range of all the submarkets listed in the Actuals section
'Define the range of all the submarkets listed in the Variance section
Dim FSubMktRg As Range
Dim ASubMktRg As Range
Dim VSubMktRg As Range

Set FSubMktRg = Range(Cells(fRowFcst, SubMktCol), Cells(lRowFcst, SubMktCol))
Set ASubMktRg = Range(Cells(fRowAct, SubMktCol), Cells(lRowAct, SubMktCol))
Set VSubMktRg = Range(Cells(fRowVar, SubMktCol), Cells(lRowVar, SubMktCol))

'
  Dim HideRg As Range
  For Each cell In Application.Union(FSubMktRg, ASubMktRg, VSubMktRg)
    If cell <> Cells(2, 3) Then
        If HideRg Is Nothing Then
            Set HideRg = cell
        Else
            Set HideRg = Union(HideRg, cell)
        End If
    End If
  Next
  HideRg.EntireRow.Hidden = True
  'Hides miscelaneous rows between each section
  Range(Cells(tRowFcst, 1), Cells(hRowAct, 1).Offset(-2, 0)).EntireRow.Hidden = True
  Range(Cells(tRowAct, 1), Cells(hRowVar, 1).Offset(-2, 0)).EntireRow.Hidden = True
  Cells(tRowVar, 1).EntireRow.Hidden = True



End If

End With



Application.ScreenUpdating = True


End Sub
Private子工作表\u selection更改(ByVal目标作为范围)
将Wk2设置为工作表
设置Wk2=图纸(“按子市场”)
Application.ScreenUpdating=False
使用Wk2
设置目标=单元格(2,3)
'如果具有下拉数据验证列表的单元格为空,则取消隐藏所有行--有效地显示所有数据
如果Target=”“,则
Wk2.Cells.Rows.Hidden=False
其他的
'目标:隐藏所有行,仅保留与每个部分下拉列表中选定的子市场相关的行
“这是向下的,因此最终用户可以深入查看特定市场,方便地查看FCST与实际值与差异
Wk2.Cells.Rows.Hidden=False
'定义预测部分的标题行
'定义预测部分中的第一行数据
'定义预测部分中的最后一行数据
暗hRowFcst与长hRowFcst相同
变暗的泡沫和长的一样
暗lRowFcst与长lRowFcst相同
hRowFcst=Cells.Find(“FCST”,LookAt:=xlWhole).偏移量(1,0).行
fRowFcst=Cells.Find(“FCST”,LookAt:=xlWhole).偏移量(2,0).行
lRowFcst=Cells.Rows(hRowFcst).Find(“State”,LookAt:=xlother.End(xlDown).Row
'定义实际值部分的标题行
'在“实际值”部分定义第一行数据
'定义“实际值”部分中的最后一行数据
暗淡的头发和头发一样长
模糊的倒影和长的一样
昏暗的街道和长的一样
hRowAct=Cells.Find(“ACT”,LookAt:=xlWhole).偏移量(1,0).行
fRowAct=Cells.Find(“ACT”,LookAt:=xlWhole).偏移量(2,0).行
lRowAct=Cells.Rows(hRowAct).Find(“State”,LookAt:=xlother.End(xlDown).Row
'定义差异部分的标题行
'定义差异部分中的第一行数据
'定义差异部分中的最后一行数据
Dim hRowVar尽可能长
长而暗淡
暗lRowVar为长
hRowVar=Cells.Find(“上方/(下方)”,LookAt:=xlother.End(xlUp.Row)
fRowVar=Cells.Rows(hRowVar).Offset(1,0).Row
lRowVar=Cells.Find(“在上方/(下方)”,LookAt:=xlother.Offset(-1,0)。行
'定义预测部分的总行
'在“实际值”部分定义数据的总行
'定义差异部分中的数据总行
变暗的tRowFcst和长的一样
暗藏
Dim tRowVar尽可能长
tRowFcst=Cells.Rows(lRowFcst).Offset(1,0).Row
tRowAct=Cells.Rows(lRowAct).Offset(1,0).Row
tRowVar=Cells.Rows(lRowVar).Offset(1,0).Row
暗淡如长
将SubMktCol变暗为长
“尽可能长的时间——了解如何使选择周期变得动态”
StateCol=Cells.Find(“State”,LookAt:=xlWhole).Column
SubMktCol=Cells.Find(“Sub-Market”,LookAt:=xlother).Column
'定义“预测”部分中列出的所有子市场的范围
'定义实际值部分列出的所有子市场的范围
'定义差异部分中列出的所有子市场的范围
变暗FSubMktRg As范围
Dim ASubMktRg As范围
Dim VSubMktRg As范围
设置FSubMktRg=范围(单元格(fRowFcst,SubMktCol),单元格(lRowFcst,SubMktCol))
设置ASubMktRg=范围(单元格(fRowAct,SubMktCol),单元格(lRowAct,SubMktCol))
设置VSubMktRg=范围(单元格(fRowVar,SubMktCol),单元格(lRowVar,SubMktCol))
'
Dim HideRg As射程
对于Application.Union(FSubMktRg、ASubMktRg、VSubMktRg)中的每个单元格
如果是单元格(2,3),则
如果HideRg什么都不是
设置HideRg=单元格
其他的
设置HideRg=并集(HideRg,单元格)
如果结束
如果结束
下一个
HideRg.EntireRow.Hidden=True
'在每个节之间隐藏不规则的行
范围(单元格(tRowFcst,1),单元格(hRowAct,1)。偏移量(-2,0))。EntireRow.Hidden=True
范围(单元格(tRowAct,1),单元格(hRowVar,1)。偏移量(-2,0))。EntireRow.Hidden=True
单元格(tRowVar,1).EntireRow.Hidden=True
如果结束
以
Application.ScreenUpdating=True
端接头

您可以使用Target,它是触发工作表更改事件的活动单元格:

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)

    On Error GoTo EXIT_SUB
    If Sh.name = Worksheets("Your Sheet Name").name Then
        If Target.Address = .Range("rngYourDropdownRange").Address Then
            myMacro
        ElseIf Target.Address = .Range("rngAnotherRangeIHave").Address Then
            mySecondMacro
        End If
    End If

如果只想在单元格C2更改时响应,请使用不同的事件


一个音符。您通常希望所有“执行任务”的业务逻辑和宏都位于一个模块中。工作表对象/事件通常保持空白,除非出于非常直接的目的。太好了!我更愿意把它放在一个模块中,但我只是通过表格看到了这一点。我会尝试所有的选择,看看结果如何。谢谢我会让你知道一些东西是否有效。我试图把它放在一个模块中,而不是直接放在工作表上。我一直无法激活此代码。我在这个过程中遗漏了一些东西。在VBA编辑器中,在左侧的资源管理器中,右键单击“模块”和“插入模块”。在该模块下,将函数移动到
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Cells(2, 3), Target) Is Nothing Then Exit Sub
    Application.EnableEvents = False
        MsgBox "A change has been made to cell(2,3)"
    Application.EnableEvents = True
End Sub