Vba 编辑单元格后的自动选择更改事件选择相同的新单元格,即使我的更改事件代码定义了新的目标单元格
屏幕更新抑制被释放,原始宏结束 我花了3个小时在这上面并追踪到了错误?在这一点上,但对我来说,我所看到的情况并不符合逻辑,因此没有找到最佳的治疗方法。 请帮忙 我使用_SelectionChange事件将单元格的值存储在全局变量中。 在修改单元格值后_Change事件启动时用作旧值 作为_changetriggered宏的一部分,列表值会动态更新,最后我会触发排序,使列表重新排序。 最后,我再次激活排序前修改过的单元格(在新位置) 我跟踪了存储在oVal(选择更改)中的值,它始终显示正确的值。 但是,当宏结束时,会自动触发1个额外的selectionChange事件(选举没有真正改变),该事件会为oVal提供一个新值,并扰乱以后的计算 当我一步一步走的时候,我注意到有问题的单元格是在排序过程中被选中的,但是我有意识地在宏的末尾激活了我想要完成的单元格。(并更新该值),但在宏结束后,排序的抑制选择更改开始生效 现在有了视觉效果和代码: 假设我有一张 安妮-1 约翰-2 斯图尔特-3 博诺-4 我选择数字1。(一) 我给出了一个新的值4。 现在,我的代码将oVal1与nVal5进行比较,以确定运动参数,并将John更新为1,Stuart 2,Bono3;安妮排在第四位。 在Sort的帮助下,它还将Anne排序到列表的末尾。 由于排序本身选择“某个随机”单元格,因此我在搜索其新位置的帮助下手动激活4。 椭圆形现在会记住4(应该是)作为新旧值。 但是当宏结束时,SelectionChange启动并将oVal设置为2(这是由排序选择的)-没有!!!!将单元格选择移动到那里。 这是一个问题,因为如果现在我不手动移动我的选择,而是给Ann一个新的值(例如,使用微调器),列表会因为错误的椭圆而被错误的值损坏 编辑: 根据要求,我在一个小型MCV测试场景中重建了问题。 Excel中的TestScene: (H11刚刚被选为跟踪椭圆的视觉输出) 此处的测试代码:Vba 编辑单元格后的自动选择更改事件选择相同的新单元格,即使我的更改事件代码定义了新的目标单元格,vba,excel,sorting,events,Vba,Excel,Sorting,Events,屏幕更新抑制被释放,原始宏结束 我花了3个小时在这上面并追踪到了错误?在这一点上,但对我来说,我所看到的情况并不符合逻辑,因此没有找到最佳的治疗方法。 请帮忙 我使用_SelectionChange事件将单元格的值存储在全局变量中。 在修改单元格值后_Change事件启动时用作旧值 作为_changetriggered宏的一部分,列表值会动态更新,最后我会触发排序,使列表重新排序。 最后,我再次激活排序前修改过的单元格(在新位置) 我跟踪了存储在oVal(选择更改)中的值,它始终显示正确的值。
Option Explicit
Dim oVal As Variant
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
oVal = Target.Value
Application.EnableEvents = False
ActiveSheet.Range("H11").Value = oVal
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Range("F13").Value = 1
Range("F14").Value = 2
Range("F15").Value = 3
Range("F16").Value = 4
Call testsort
Application.EnableEvents = True
Range("F16").Activate
End Sub
Sub testsort()
ActiveWorkbook.Worksheets("Sheet3").ListObjects("Table2").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet3").ListObjects("Table2").Sort.SortFields.Add _
Key:=Range("Table2[[#All],[c]]"), SortOn:=xlSortOnValues, Order:= _
xlAscending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet3").ListObjects("Table2").Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
End Sub
您将看到这里发生的情况是,oVal在我的代码末尾取5的值,然后突然又出现了更改,并将val更改为2。
完整代码:(-removed-)
编辑2:解决方法:
在更好地理解问题的本质之后,我测试了一种变通方法。见下文
解决方案:
Option Explicit
Dim oVal As Variant
Dim cameFromChange As Boolean
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If cameFromChange = False Then
oVal = Target.Value
Application.EnableEvents = False
ActiveSheet.Range("H11").Value = oVal
Application.EnableEvents = True
Else
cameFromChange = False
Application.EnableEvents = False
Range("F13").Value = 1
Range("F14").Value = 2
Range("F15").Value = 3
Range("F16").Value = 4
Call testsort
Application.EnableEvents = True
Range("F16").Activate
End If
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
cameFromChange = True
End Sub
这是在单元格中提交值后发生的选择更改 Excel中有一个设置(选项-高级-按Enter move selection键后),用于控制光标在编辑后的移动位置,它将导致选择更改。即使您取消选中移动光标的选项,它也会这样做-然后它会在编辑的单元格本身上引发
选择\u change
令人困惑的是,事件的发生顺序如下:
- 按enter键提交编辑
- 选择更新(光标在屏幕上移动,
属性更新)选择
触发工作表\u更改
激发Selection\u Change
我确信有理由这样做(而不是按照更改事件的顺序,然后移动光标,然后选择事件),但无论如何,您必须使代码适应这样一个事实,即始终存在与任何用户诱导的单元格编辑相关联的
选择更改
,而且它总是在工作表\u Change
返回后触发(如果更改事件是通过编程方式指定单元格的值触发的,则根本不会触发)。如果您发布了一个,则会更有帮助。我已按照您的要求提交了一个测试场景。谢谢,这解释了(并且弄糟了)一切:)如果在某个地方有一个我们可以通过编程更改的参数,这将是一个可接受的特性。解决这个问题的最好办法是将新值保存在某个变量中,以备以后使用,并让额外的SelectionChange在一开始就发生。完成后,关闭事件并在SelectionChange代码中运行ChangeEvent的其余代码。(在第三个变量的帮助下,该变量被设置为监控SC呼叫的性质。Cheers更准确地说,投诉部分:问题不是SelectionChange在更改后被“标记”,而是“标记”无法被更改代码中发生的另一个SC覆盖。我已尝试通过手动设置新选择来覆盖它,但excel不在乎,仍然不更改运行原始事件。