如果选择了一个单元格(来自多个工作表),则显示消息框

时间:2017-12-06 16:33:05

标签: excel vba excel-vba

对于初学者来说,我是自学而且还在学习(我从这个网站上学到了很多东西)。话虽如此,请不要认为有些事情是显而易见的。如果你的解决方案太复杂,我将需要帮助改变代码。

我想要完成的是;如果在" Sheet3"," Sheet4"和" Sheet5"上选择单元格A10;然后我想要一个消息框显示来自Sheets的信息(" Sheet6")。范​​围(" A1")。

Option Explicit

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Selection.Count = 1 Then
        If Not Intersect(Target, Range("A10")) Is Nothing Then ' this range is where you click to get the msgbox
                Dim rng As Range, s As String, x As String
                Set rng = Sheets("Sheet6").Range("A1") ' this defines x
                 s = "Define: " ' s is what appears first
                 x = s & rng.Value ' x is what appears after s

                 MsgBox x
        End If
    End If
End Sub

我想要发生什么;如果您在" Sheet3"," Sheet4"和" Sheet5"并在这三张纸中的任何一张中选择A10,它将显示在代码中定义的消息框中。

什么在起作用;目前这是一个私人子,直接在" Sheet5"。当它在这里时,如果选择单元格A10(在" Sheet5"中),则来自" Sheet6" A1会根据需要显示在消息框中。

什么不起作用;因为这是一个私人子,并且在里面" Sheet5"我正在努力让它与A10一起工作,来自" Sheet3"和" Sheet4"。

我尝试通过移动代码并将其声明为公共子代码来改变代码,但是到目前为止还没有成功。

3 个答案:

答案 0 :(得分:2)

对于不同的方法,只需在ThisWorkbook对象内输入一次。

Option Explicit

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

    Select Case Sh.Name

        Case Is = "Sheet3", "Sheet4", "Sheet5"

            If Target.Address = "$A$10" Then

                    MsgBox Worksheets("Sheet6").Range("A1").Value

            End If

    End Select

End Sub

答案 1 :(得分:1)

Worksheet_SelectionChange必须位于工作表的私有模块中。但是,它可以调用公共模块中的另一个例程

所以,如果你把

    Public Sub CheckSelection(Target as range)
        etc

然后,您可以将三个工作表中的代码放入公共模块中

const makeList = WrappedComponent => {
  const List = ({ data }) => (
    <ul style={styles.listStyles}>
      {data &&
        data.map(item => (
          <div>
            <WrappedComponent {...item} />
          </div>
        ))}
    </ul>
  );

  List.propTypes = {
    data: PropTypes.array.isRequired,
  };

  return List
}

答案 2 :(得分:1)

听起来像一个有趣的项目!为了进一步扩展答案,当您使用Worksheet_SelectionChange事件时,这是特定对象发生的事件。这就是为什么它仅适用于具有背后代码的一张纸。要使这个工作在多个工作表中,您可以采取以下三种方法之一。

选项1 :将代码复制到每个工作表对象。从某种意义上说,这是最简单的方法,但在多个位置维护相同代码的副本可能会很麻烦。

选项2 :将您的代码放在标准模块中的公共函数中。这样,您就可以在一个位置维护代码例程,并使用最少的必要代码从每个工作表中调用它。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    MySpecialFunction Target
End Sub

对于大多数情况,您可能会发现这是处理需求的最有效方式。

选项3 :另一种更高级的方法是使用包装类对象。这允许您将函数动态应用于任何活动工作表,而无需将(选项2)代码添加到每个工作表。虽然这更复杂,但它允许您将事件驱动的代码应用于任何工作表,甚至是用户创建的新工作表。

为此,请在项目中创建一个类模块,并将其命名为clsMyClass。然后粘贴以下代码:

Option Explicit

Public WithEvents MySheet As Worksheet

Private Sub MySheet_SelectionChange(ByVal Target As Range)
    ' Do neat stuff here...
End Sub

这里的关键是WithEvents声明。这使您可以从对象变量中获取 事件 。 (但是你只能从类对象而不是标准模块中执行此操作。)

然后在您的Workbook_Open()事件或项目的其他位置,您可以添加将所有当前工作表添加到集合的函数,从而允许您为所有这些工作表利用SelectionChange事件,无需为每个代码添加代码。

Option Explicit

Private mcolSheets As Collection

Public Sub ActivateCodeForAllWorksheets()

    Dim wks As Worksheet
    Dim cSheet As clsMyClass

    ' Initialize module-level collection
    Set mcolSheets = New Collection

    For Each wks In ActiveWorkbook.Worksheets
        ' Create new instance of class
        Set cSheet = New clsMyClass
        ' Set to the current worksheet in our loop,
        ' and add to the collection so the sheet object
        ' reference perists after this sub finishes.
        Set cSheet.MySheet = wks
        mcolSheets.Add cSheet
    Next wks

End Sub

在现实生活中,这对于在具有焦点时将特殊格式应用于文本框,以及在大量对象中具有这种行为一致而不需要数百行重复代码的事情非常有用。

我希望这有用!