[英]SpecialCells causing SheetSelectionChange event in Excel 2010
I have a test Macro我有一个测试宏
Sub test()
Dim rSrcMatrix As Range
Set rSrcMatrix = Sheets("Code Matrix").Range("Xfer_To_Xfer_Matrix").Range("A1")
Set rSrcMatrix = rSrcMatrix.Resize(rSrcMatrix.SpecialCells(xlCellTypeLastCell).Row, rSrcMatrix.SpecialCells(xlCellTypeLastCell).Column)
End Sub
I am using this macro to test my COM addin that I have created in VS2010.我正在使用这个宏来测试我在 VS2010 中创建的COM插件。 I have delegated the
SheetSelectionChange
event in the addin to some function.我已将插件中的
SheetSelectionChange
事件委托给一些 function。
Now I notice that whenever I run this macro, Excel fires the SheetSelectionChange
event 4 times and my addin calls the associated method for that many times.现在我注意到,每当我运行此宏时,Excel 都会触发
SheetSelectionChange
事件 4 次,并且我的插件会多次调用关联的方法。
Is there anything that I am missing or is this a bug in excel?有什么我遗漏的,还是 excel 中的错误?
I believe and I could be wrong because I couldn't find an MSDN article to prove it but SpecialCells performs a type of selection and triggers the Worksheet_SelectionChange
or the Workbook_SheetSelectionChange
event and hence you need to switch off events. 我相信而且我可能是错的,因为我找不到MSDN文章来证明这一点,但是SpecialCells执行一种选择并触发
Worksheet_SelectionChange
或Workbook_SheetSelectionChange
事件,因此您需要关闭事件。
Here is a simple way to test it. 这是一种简单的测试方法。
Place this code in the Sheet Code Area 将此代码放在工作表代码区域
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
MsgBox "Damn! The SpecialCells caused me to pop up!!!"
End Sub
Sub test()
Debug.Print ActiveSheet.Cells.SpecialCells(xlCellTypeLastCell).Row
End Sub
Worksheet_SelectionChange
and Workbook_SheetSelectionChange
do the same job. Worksheet_SelectionChange
和Workbook_SheetSelectionChange
做相同的工作。 Worksheet_SelectionChange
is used in the sheet code are for a specific sheet. Worksheet_SelectionChange
表代码中使用的Worksheet_SelectionChange
用于特定的工作表。 And Workbook_SheetSelectionChange
is used when you want the event to fire across all the sheets in that workbook. 当您希望事件在该工作簿中的所有工作表上触发时,将使用
Workbook_SheetSelectionChange
。
YOUR QUESTION FROM THE COMMENT : What if we wanted to associate another event with that line of code.
您的评论 :如果我们想将另一个事件与该行代码关联,该怎么办。 In that case, we cannot suppress the event.
在这种情况下,我们无法抑制该事件。
Now, we have two alternatives. 现在,我们有两种选择。 Based on your above question we cannot use
Alternative One
. 根据您的上述问题,我们无法使用
Alternative One
。 So you may directly skip to Alternative 2
因此,您可以直接跳至
Alternative 2
ALTERNATIVE 1 替代方案1
Switch Off Events 关闭事件
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo Whoa
Application.EnableEvents = False
'
'~~> YOUR CODE
'
Letscontinue:
Application.EnableEvents = True
Exit Sub
Whoa:
MsgBox Err.Description
Resume Letscontinue
End Sub
ALTERNATIVE 2 替代方案2
Instead of using SpecialCells
to find the last row or the last column, we will use .Find
. 而不是使用
SpecialCells
查找最后一行或最后一列,我们将使用.Find
。
Sub test()
Dim ws As Worksheet
Dim rSrcMatrix As Range
Dim Lrow As Long, LCol As Long
Set ws = ThisWorkbook.Sheets("Code Matrix")
With ws
If Application.WorksheetFunction.CountA(.Cells) <> 0 Then
Lrow = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
LCol = .Cells.Find(What:="*", _
After:=.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
Else
Lrow = 1
End If
Set rSrcMatrix = .Range("Xfer_To_Xfer_Matrix").Range("A1")
Set rSrcMatrix = rSrcMatrix.Resize(Lrow, LCol)
Debug.Print rSrcMatrix.Address
End With
End Sub
Based on @Siddharth Rout technique, here is a method that will return the last cell of a Worksheet.UsedRange
(see my comments below his answer)基于@Siddharth Rout 技术,这是一个返回
Worksheet.UsedRange
的最后一个单元格的方法(请参阅我在他的回答下方的评论)
Function GetLastCellEmpty(rng As Range) As Range
Set m_rngCheck = rng
Set m_rngFound = m_rngCheck.Find(What:="", _
LookIn:=XlFindLookIn.xlFormulas, _
Lookat:=XlLookAt.xlPart, _
SearchDirection:=XlSearchDirection.xlPrevious)
Set GetLastCellEmpty = m_rngFound
End Function
Function GetLastCellUsedRange(ws As Worksheet) As Range
Set GetLastCellUsedRange = GetLastCellEmpty(ws.UsedRange.Offset(1, 1)).Offset(-1, -1)
End Function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.