每次更改单元格选择时如何运行子程序 - excel,vba

时间:2015-05-21 19:06:12

标签: excel vba excel-vba

长话短说:我每次点击一个单元格时都想运行一个子

我在excel中遇到了这个sub,我需要你的帮助。

我正在 ThisWorkbook 区域内编写VBA代码,因为我希望这个子代码能够在每张工作表中运行。

我的目标是:当我单击一个单元格(与工作表无关)时,子运行,进行一些检查,然后在特定单元格(在同一个活动工作表中)写入结果。

是否可以处理此事件?

谢谢。

1 个答案:

答案 0 :(得分:11)

您必须使用SheetChange对象的Workbook方法:

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    'run code everytime one of the sheets is changing
End Sub

对不起,我刚才读得更好: 当我点击一个单元格(无关紧要)时,子运行,进行一些检查,然后写入特定单元格(在同一活动工作表中)的结果。

在这种情况下,您应该使用Workbook_SheetSelectionChange

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    'run code everytime one of the sheets' cells is selected
End Sub

但是,要小心。当选择更改时,上述操作将会运行,而不会在您单击单元格时运行。让我们说“点击一个单元格”是“选择一个单元格”的一个子集(因为如果你点击一个单元格,你选择一个单元格,但如果你选择一个单元格则不一定如此你点击它:你可能是通过VBA代码[Range("A1").Select]或用鼠标向上/向下/向右/向左移动)来选择它。因此,如果您不希望每次更改选择时都运行代码,请不要忘记管理差异。

要预测下一个问题(如何区分点击或不点击?),您可以使用user32.dll API获取点击:

Private Declare PtrSafe Function GetAsyncKeyState Lib "user32.dll" (ByVal vKey As Long) As Integer

注意:PtrSafe关键字用于在64位系统中声明API。如果你是一个32位的,只需从API声明中取出它。

Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    Dim check As Boolean
    check = GetAsyncKeyState(1) '<-- True if click, False if not click
    If check Then '<-- if click...
        'run code everytime one of the sheets' cells is selected and you intercept a click
    End If
End Sub

结束

我引用Siddharth的评论。我已经回答了这个问题,向您展示如何做您要求的事情。如果你说你想要做的是什么,那么95%肯定会有比我上面写的更好的解决方案。

如果你想知道为什么你永远不应该100%信任SelectionChange(为Siddharth提供信用额度),请在工作表中隐藏一行,然后运行此宏(将其放入标准模块) :

Sub test()
    Dim r As Range
    r = Cells.SpecialCells(xlCellTypeVisible)
End Sub

即使您没有选择任何单元格,SelectionChange事件也会被触发(因此存在错误的数据验证风险)。