【问题标题】:Excel VBA: Sort, then Copy and PasteExcel VBA:排序,然后复制和粘贴
【发布时间】:2011-05-25 16:21:57
【问题描述】:

所有,我需要编写一个执行以下操作的宏:

  1. 在E列最后一个空白单元格中输入数据,按E列降序对整个工作表进行排序

  2. 工作表排序后:

    2a。将单元格复制到紧挨第一次输入数据的单元格左侧的相邻单元格

2b。将复制的数据粘贴到最初输入数据的同一行的第一列

2c。将光标移动到紧邻第一次输入数据的单元格右侧的相邻单元格

下面,我展示了输入代码的排序,它有效。但是,我无法然后获取要复制、粘贴和正确移动的代码。我最常见的问题:数据输入后,行移动,但光标停留在第一次输入数据的行。任何人都可以帮忙吗? (我什至无法在这篇文章中正确缩进!)

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not (Application.Intersect(Worksheets("Sheet1").Range("E:E"), Target) Is Nothing) Then
        DoSort
    End If
End Sub

Private Sub DoSort()
    Worksheets("Sheet1").Range("A:E").Sort Key1:=Worksheets("Sheet1").Range("E1"), Order1:=xlDescending, Header:=xlYes
End Sub

【问题讨论】:

  • 感谢您的帮助,@Jean-François Corbett。请看下面的评论。

标签: excel vba


【解决方案1】:

关于 1、2a 和 2b:在排序之前进行复制更简单。这样,复制的值将与其余值一起排序。

Private Sub Worksheet_Change(ByVal Target As Range)
    If Not (Application.Intersect(Worksheets("Sheet1").Range("E:E"), Target) _
        Is Nothing) Then
        ' First copy
        Target.Offset(0, -1).Copy Destination:=Target.Offset(0, -4)
        ' Then sort
        DoSort
    End If
End Sub

这留下了问题 (2c),即在对行进行排序后如何将活动单元格移动到适当的行。大概,您希望用户在 F 列中输入更多数据?

同样,最直接的解决方案是先进行此输入,然后再进行排序。这将具有额外的好处,即用户不会让输入行在输入 E 列和 F 列中的数据之间跳转。排序甚至可以只发生一次,在用户输入所有数据之后。

当然,以上更多的是设计建议,而不是针对您的特定任务 2c 的解决方案。如果在排序后移动活动单元格确实是您想要的,那么解决方案将不可避免地更加复杂。 Excel 的Sort 方法不返回索引,以便在排序后定位您的条目。您必须自己制作索引/“序列号”并在排序后进行搜索。这有效:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim newIndex As Long
    If Not (Application.Intersect(Worksheets("Sheet1").Range("E:E"), Target) _
        Is Nothing) Then
        ' Index the new entry in column B. (You can put the index elsewhere.)
        newIndex = WorksheetFunction.Max(Range("B:B")) + 1
        Target.Offset(0, -3).Value = newIndex
        ' Copy the entry.
        Target.Offset(0, -1).Copy Destination:=Target.Offset(0, -4)
        ' Sort
        DoSort
        ' Search for the new index after sorting. Select cell in column 6 (F).
        Cells(WorksheetFunction.Match(newIndex, Range("B:B"), 0), 6).Select
    End If
End Sub

如果您的所有条目都是唯一的(即没有重复),则不一定需要创建索引;您原则上可以只搜索条目本身。但是,如果有可能重复,那么搜索条目本身(而不是其索引)将更加混乱,并且可能导致不需要的行为,除非它的编程恰到好处。我发现只使用索引要干净得多。

【讨论】:

  • 啊哈,糟糕和不完整的用户需求导致程序员困惑。
  • @Tiago Cardoso:谢谢。这些是很好的答案,不幸的是在我的情况下不起作用。我现在想知道我是否正在尝试解决一个不优雅的现有解决方案的问题。我将在问题“Excel:创建可排序的复合 ID”中更详细地发布我的问题。再次感谢!
  • @Steve T:这个答案符合您在问题中的要求。
【解决方案2】:

我建议你保存输入的值并在排序后搜索这个值。

请注意,我们可能在 E 列中添加了 dup 数据,因此我们还需要存储其他列的信息,直到获得可靠的密钥。

因此,一旦您知道需要搜索的值,请找到包含您在 E 列中添加的数据的单元格(现在可能在任何其他行中,而不仅仅是在最后一行中)并使用它作为您其他操作的锚。

有几种方法可以在矩阵中查找特定条目(根据需要使用 Excel 或纯 VBA)。如果您在实施时遇到问题,请告诉我们。

拥有包含刚刚添加的值的单元格地址(在 E 列中),您将使用 offset 函数来设置相邻值。同样,如果您在实施时遇到问题,请告诉我们您的疑问。

希望对你有帮助:)

Rgds

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多