【问题标题】:Delete Rows & Maintain Input Range删除行并维护输入范围
【发布时间】:2013-02-09 15:08:58
【问题描述】:

我想知道是否有人可以帮助我。

几周以来,我一直在尝试寻找一种解决方案,让用户可以执行以下操作:

  • 删除有数据和没有数据的行,
  • 移动所有包含数据的行,使它们并排放置,
  • 同时保持定义的“输入范围”

我整理了以下脚本,它清除单元格内容,因此不会改变“输入范围”。

Sub DelRow()

      Dim msg

          Sheets("Input").Protect "handsoff", userinterfaceonly:=True
          Application.EnableCancelKey = xlDisabled
          Application.EnableEvents = False
          msg = MsgBox("Are you sure you want to delete this row?", vbYesNo)
          If msg = vbNo Then Exit Sub
          With Selection
              Application.Intersect(.Parent.Range("A:S"), .EntireRow).Interior.ColorIndex = xlNone
              Application.Intersect(.Parent.Range("T:AE"), .EntireRow).Interior.ColorIndex = 42
              Selection.SpecialCells(xlCellTypeConstants).ClearContents
              Application.Intersect(.Parent.Range("C:AE"), .EntireRow).Locked = True
              Application.Intersect(.Parent.Range("AG:AG"), .EntireRow).Locked = True
          End With
              Application.EnableEvents = True
      End Sub

更新代码

Sub DelRow()
Dim RangeToClear As Range
Dim msg As VbMsgBoxResult

'Sheets("Input").Protect "handsoff", userinterfaceonly:=True
Application.EnableCancelKey = xlDisabled
Application.EnableEvents = False
msg = MsgBox("Are you sure you want to delete this row?", vbYesNo)
If msg = vbNo Then Exit Sub
With Selection
    Application.Intersect(.Parent.Range("A:S"), .EntireRow).Interior.ColorIndex = xlNone
    Application.Intersect(.Parent.Range("T:AE"), .EntireRow).Interior.ColorIndex = 42
    On Error Resume Next
    Set RangeToClear = Selection.SpecialCells(xlCellTypeConstants)
    On Error GoTo 0    ' or previously defined error handler
    If Not RangeToClear Is Nothing Then
        RangeToClear.ClearContents
    Else
    Selection.Sort Key1:=Range("B7"), Order1:=xlAscending, Header:=xlNo, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
        DataOption1:=xlSortNormal
    End If
    Application.Intersect(.Parent.Range("C:AE"), .EntireRow).Locked = True
    Application.Intersect(.Parent.Range("AG:AG"), .EntireRow).Locked = True
End With
Application.EnableEvents = True
End Sub

但问题在于,如果用户选择空白行,他们会收到“错误 400”消息,并且不会将行向上移动以位于彼此下方。

正如我所说,我花了很多时间试图找到解决方案,但没有任何成功。

如果有人能看到这个并就我如何实现这一目标提供一些指导,我将非常感激。

非常感谢和亲切的问候

【问题讨论】:

  • 根据support.microsoft.com/?kbid=146864 运行时错误 400 是“表单已显示;无法以模态方式显示”至少在 Excel 97 中(!)。这似乎不适用。 ClearContents 行有错误吗?错误的措辞是什么?
  • 嗨@DougGlancy,感谢您抽出宝贵时间回复我的帖子。错误只是说“400”。如果有帮助,我在这里设置了一个测试文件:box.com/s/cnptwwmnmzoooirrgos2。您会看到在第 8-11 行中,B 列中有数据。然后我将数据添加到第 46 行和第 47 行,再次在 B 列中。如果您突出显示中间的空白行并尝试删除它们,您将收到有问题的错误。非常感谢和亲切的问候
  • 好吧,我看到一个错误,如果选择为空白,您的ClearContents 行,所以我会回答这个问题,看看它是否有帮助。
  • 所以,如果您清除内容,听起来您想要排序。这意味着排序代码不应位于 Else 子句中,而应位于 If 子句中。我会再次尝试修改我的答案以获得你想要的。
  • 嗨@DougGlancy,谢谢,是的,如果可能的话,这就是我想要实现的目标。亲切的问候

标签: excel excel-2003 vba


【解决方案1】:

如果选择为空,Selection.SpecialCells(xlCellTypeConstants).ClearContents 行 将失败,因为没有xlCellTypeConstants。您需要对此进行测试,并且仅在有内容时才清除内容:

编辑:尝试回答排序问题

我认为您无论如何都只想排序,所以我只是将Sort 移到ClearContents 之后。不过,我对 UsedRange 进行了排序,我认为这不是您想要的。您需要定义要排序的范围,可以使用 Excel 中的名称管理器或在您的代码中定义为命名范围。

Sub DelRow()
Dim RangeToClear As Range
Dim msg As VbMsgBoxResult

Sheets("Input").Protect "handsoff", userinterfaceonly:=True
Application.EnableCancelKey = xlDisabled
Application.EnableEvents = False
msg = MsgBox("Are you sure you want to delete this row?", vbYesNo)
If msg = vbNo Then Exit Sub
With Selection
    Application.Intersect(.Parent.Range("A:S"), .EntireRow).Interior.ColorIndex = xlNone
    Application.Intersect(.Parent.Range("T:AE"), .EntireRow).Interior.ColorIndex = 42
    On Error Resume Next
    Set RangeToClear = Selection.SpecialCells(xlCellTypeConstants)
    On Error GoTo 0    ' or previously defined error handler
    If Not RangeToClear Is Nothing Then
        RangeToClear.ClearContents
    End If
    'You need to define a range that you want sorted
    'here I've used UsedRange
    ActiveSheet.UsedRange.Sort Key1:=Range("B7"), Order1:=xlAscending, Header:=xlNo, _
                   OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
                   DataOption1:=xlSortNormal

    Application.Intersect(.Parent.Range("C:AE"), .EntireRow).Locked = True
    Application.Intersect(.Parent.Range("AG:AG"), .EntireRow).Locked = True
End With
Application.EnableEvents = True
End Sub

【讨论】:

  • 嗨@Doug Clancy,非常感谢你。这可以解决错误消息,谢谢!,但不幸的是,它不会移动行,以便那些有数据的行位于彼此下方。你能告诉我,你有什么想法吗?非常感谢和亲切的问候
  • 您好,非常感谢您。正如你所建议的,我录制了一个宏来对信息进行排序,但我一定是在某些地方出错了。我试图在行中添加一个“Else If”:`RangeToClear.ClearContents,这样如果行是空白的,行会向上移动。当我运行它时,虽然我没有收到任何错误消息,但排序不起作用,并且对工作表没有任何更改。我用更新的代码编辑了我的原始帖子。你能不能看看这个,让我知道我哪里出错了。非常感谢和亲切的问候。
  • 嗨@DougClancy,非常感谢你,它工作得很好。我真的无法表达我的感谢,我花了几个星期才达到这一点。非常感谢和亲切的问候。
猜你喜欢
  • 1970-01-01
  • 2015-04-14
  • 2021-07-05
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 2012-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多