Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 编辑单元格后的自动选择更改事件选择相同的新单元格,即使我的更改事件代码定义了新的目标单元格_Vba_Excel_Sorting_Events - Fatal编程技术网

Vba 编辑单元格后的自动选择更改事件选择相同的新单元格,即使我的更改事件代码定义了新的目标单元格

Vba 编辑单元格后的自动选择更改事件选择相同的新单元格,即使我的更改事件代码定义了新的目标单元格,vba,excel,sorting,events,Vba,Excel,Sorting,Events,屏幕更新抑制被释放,原始宏结束 我花了3个小时在这上面并追踪到了错误?在这一点上,但对我来说,我所看到的情况并不符合逻辑,因此没有找到最佳的治疗方法。 请帮忙 我使用_SelectionChange事件将单元格的值存储在全局变量中。 在修改单元格值后_Change事件启动时用作旧值 作为_changetriggered宏的一部分,列表值会动态更新,最后我会触发排序,使列表重新排序。 最后,我再次激活排序前修改过的单元格(在新位置) 我跟踪了存储在oVal(选择更改)中的值,它始终显示正确的值。

屏幕更新抑制被释放,原始宏结束

我花了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刚刚被选为跟踪椭圆的视觉输出)

此处的测试代码:

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不在乎,仍然不更改运行原始事件。