简体   繁体   English

删除行并保持输入范围

[英]Delete Rows & Maintain Input Range

I wonder whether someone may be able to help me please. 我想知道是否有人可以帮助我。

For a few weeks now I've been trying to find a solution whereby users can do the following: 几周以来,我一直在尝试找到一种解决方案,用户可以通过它执行以下操作:

  • Delete rows with and without data, 删除有数据和无数据的行,
  • Shift all rows containing data aso that they sit one under another, 将所有包含数据的行移动到另一行,
  • Whilst maintaining a defined 'Input Range' 保持定义的“输入范围”

I've put together the following script which clears the cell contents and hence doesn't alter the 'Input Range'. 我整理了以下脚本,该脚本清除了单元格的内容,因此不会更改“输入范围”。

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

Updated Code 更新的代码

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

The problem with this though, is that if a user selects a blank row they receive a 'Error 400' message and it doesn't shift the rows up to sit underneath each other. 但是,这样做的问题是,如果用户选择空白行,则会收到“错误400”消息,并且不会将这些行向上移动到彼此下方。

As I said, I've spent so much time on this trying to find a solution without any success. 就像我说的那样,我花了很多时间在寻找解决方案上没有成功。

I really would be so grateful if someone could look at this please and offer some guidance on how I may achieve this. 如果有人可以看一下这个问题,并就如何实现这一目标提供一些指导,我真的会非常感激。

Many thanks and kind regards 非常感谢和问候

If the selection is blank, the line Selection.SpecialCells(xlCellTypeConstants).ClearContents will fail because there are no xlCellTypeConstants . 如果选择为空白,则行Selection.SpecialCells(xlCellTypeConstants).ClearContents将失败,因为没有xlCellTypeConstants You need to test this and only clear the content if there are any: 您需要对此进行测试,并且仅在存在以下情况时清除内容:

EDIT: To try to answer Sorting question 编辑:尝试回答排序问题

I think you just want to sort no matter what, so I just moved the Sort to after the ClearContents . 我想您无论如何都希望进行排序,因此我将Sort移至ClearContents I sorted the UsedRange though, which I don't think is what you want. 我对UsedRange进行了排序,但我认为这不是您想要的。 You need to define the range to be sorted, either as a named range using the Name Manager in Excel, or in your code. 您需要定义要排序的范围,或者使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM