【问题标题】:Detect the type of Selection in a Worksheet just deactivated, in any open Workbook在任何打开的工作簿中检测刚刚停用的工作表中的选择类型
【发布时间】:2015-01-28 21:41:08
【问题描述】:

在更改ActiveSheet编辑:任何打开的Workbook)后,我想要一种查询方法:

  1. 检测上一个活动工作表中Selection 的类型(最重要的是,如果它是ChartObjectRange)。
  2. 如果是Range,获取地址。

这可能吗...?

编辑:...(续)

  1. 无需额外的 Activating/Deactivating 即可查询(首选)。
  2. 需要额外的激活/停用查询。

请注意,将代码添加到 ThisWorkbook 只会影响该工作簿。 所以,我猜想 Jon Peltier 为 Chart 事件发布的内容可能会起作用 (http://peltiertech.com/chart-events-microsoft-excel/)。 我一直在寻找 Excel VBA 原生的东西(首选),或者对我提到的选项或其他替代方案(第二选择)的一些见解。

到目前为止,通过使用基于第 4 节的代码。在the link above 的所有工作簿中启用所有工作表上所有图表的应用程序事件,我已经设法检测到任何工作簿中任何工作表的停用。 然后,我可以想象 2 点的代码。带有额外的激活/停用查询。 但我不知道第 1 点。

(勉强?)相关问题:VBA: Get selected Range in a Worksheet where the Selection is a Chart

【问题讨论】:

    标签: vba excel selection worksheet


    【解决方案1】:

    试着把这个放在ThisWorkbook:

    Private Sub Workbook_SheetDeactivate(ByVal Sh As Object)
    
    Dim Sh2         As Worksheet
    Dim rAddress    As String
    
    Set Sh2 = ActiveSheet
    
    Application.EnableEvents = False
    Application.ScreenUpdating = False
    
    Sh.Activate
    If TypeName(Selection) = "Range" Then rAddress = Selection.Address
    Sh2.Activate
    
    MsgBox rAddress
    
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    
    End Sub
    

    编辑

    要在任何打开的工作簿中检测最近停用的工作表的选择类型,请在您的 PERSONAL.XLSB 文件中添加以下内容(如果是 Windows XP,则为 PERSONAL.XLS):

    名为 cAppEvent 的类模块:

    Option Explicit
    Public WithEvents EventApp As Excel.Application
    
    Private Sub EventApp_SheetDeactivate(ByVal Sh As Object)
    
    Dim wb As Workbook
    Dim ws As Worksheet
    
    Set ws = Sh
    Set wb = ws.Parent
    CheckPreviousSelection ws, wb
    
    End Sub
    

    任意名称的常规模块:

    Public cXLEvents As New cAppEvent
    
    Sub CheckPreviousSelection(Sh As Worksheet, wb As Workbook)
    
    Dim Sh2 As Worksheet
    Dim wb2 As Workbook
    Dim r   As Range
    Dim cht As ChartObject
    Dim chk As Long
    
    Set Sh2 = ActiveSheet
    Set wb2 = Sh2.Parent
    
    Application.EnableEvents = False
    Application.ScreenUpdating = False
    
    Sh.Activate
    If TypeName(Selection) = "ChartArea" Then
        Set cht = Sh.ChartObjects(Right(ActiveChart.Name, Len(ActiveChart.Name) - Len(Sh.Name) - 1))
        chk = 1
    ElseIf TypeName(Selection) = "Range" Then
        Set r = Selection
        chk = 2
    End If
    Sh2.Activate
    
    If chk = 1 Then
        MsgBox wb.Name & vbNewLine & Sh.Name & vbNewLine & cht.Name
        'Do whatever you need to for a chart here.
    ElseIf chk = 2 Then
        MsgBox wb.Name & vbNewLine & Sh.Name & vbNewLine & r.Address
        'Do whatever you need to for a range here.
    End If
    
    Application.EnableEvents = True
    Application.ScreenUpdating = True
    
    End Sub
    

    在 ThisWorkbook 下:

    Private Sub Workbook_Open()
    
    Set cXLEvents.EventApp = Application
    
    End Sub
    

    注意事项:

    1. 您可能需要关闭 Excel 并重新打开它才能开始工作。
    2. 这将为您提供有关先前在任何打开的工作簿中跨工作表选择的信息。但是,如果选择了新工作簿,它将不会为您提供有关先前选择的信息。如有必要,可以添加更多代码来捕获该片段。
    3. 此方法使用额外的激活/停用。由于没有Workbook_BeforeSheetDeactivate,因此我不确定是否可以在不进行额外激活/停用的情况下完成您想要的操作。
    4. 这将在您打开的任何工作簿上运行,即使您不想这样做。您很可能希望将 ThisWorkbook 中的代码更改为以下内容:

      If MsgBox("Turn on AppEvents?", vbYesNo) = vbYes Then Set cXLEvents.EventApp = Application

      或者将其从 Workbook_Open 事件中取出,仅在需要时运行。

    【讨论】:

    • 即使我没有测试它,这似乎适用于原始帖子 (+1)。我添加了一个我忘记明确说明的要求。
    • @sancho.s 我已经编辑了我的答案,包括在任何打开的工作簿中检测最近停用的工作表的选择类型的能力。如果这是您要找的,请告诉我。
    【解决方案2】:

    您可以将这个问题和其他问题的答案拼凑起来所需的行为。

    1. 使用应用程序级事件来处理SelectionChangeWorksheetDectivate 事件
    2. 使用Chart 事件来处理工作表上图表的选择
    3. 使用全局变量来跟踪当前选择,无论它位于哪个工作表/工作簿中
    4. 可以将代码放入您选择的工作簿中,如果需要,还可以添加一个插件。

    将此代码放在ThisWorkbook 模块中

    Private WithEvents App As Application
    Private WithEvents Cht As Chart
    
    Private sel As Variant
    
    
    Private Sub App_SheetActivate(ByVal Sh As Object)
        If Sh.ChartObjects.Count > 0 Then
            Set Cht = Sh.ChartObjects(1).Chart
        Else
            Set Cht = Nothing
        End If
    End Sub
    
    Private Sub Cht_Activate()
        Set sel = Cht
    End Sub
    
    Private Sub Workbook_Open()
        Set App = Application
        Set sel = Selection
        If ActiveSheet.ChartObjects.Count > 0 Then
            Set Cht = ActiveSheet.ChartObjects(1).Chart
        Else
            Set Cht = Nothing
        End If
    End Sub
    
    Private Sub App_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
        Set sel = Selection
    End Sub
    
    Private Sub App_WorkbookActivate(ByVal Wb As Workbook)
        Set sel = Selection
    End Sub
    
    
    Private Sub App_SheetDeactivate(ByVal Sh As Object)
        Debug.Print Sh.Name
        If TypeName(sel) = "Range" Then
            Debug.Print sel.Address
        Else
            Debug.Print TypeName(sel)
        End If
    
        Set sel = Selection
    End Sub
    

    【讨论】:

    • SheetSelectionChange 在将 SelectionRange 更改为 Chart 时不会触发(实际上,ChartArea 通过鼠标单击),反之亦然,如果重新选择最后一个之前选择的Range。我想这直接意味着该事件对第 1 点没有用。
    • @sancho.s 我从您的评论中得知您正在使用放置在工作表上的图表,而不是图表表。请参阅我的更新以处理此案例。关于 Excel 事件的一个很好的参考是 Cpearson.com
    • 是的,我正在使用放置在工作表上的图表。我在您的链接页面之前阅读过。请注意,我的意思是将代码放在一起,一旦加载,它将作用于任何工作簿,如标题所示。例如,我指向 Jon Peltier 网站的链接。我不确定您发布的代码是否这样做,我会在检查后发布反馈。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-19
    • 2014-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多