" Worksheet_Change"覆盖重定位的行,无法处理列之间的间隙

时间:2016-11-15 09:56:53

标签: excel vba excel-vba filter worksheet-function

我想在Zeile中编写一段VBA代码,它对Excel中下拉列表中所做的更改做出反应。

目前,我已在Row = K7:K1007中编写了以下代码,并且下拉列表中的每个相关条目都可以在C的范围内找到。设置为Completed Items(=已完成)时,相应的行应重新定位到另一个名为Private Sub Worksheet_Change(ByVal Target As Range) Dim Zeile As Long Set Target = Intersect(Target, Range("K7:K1007")) If Target Is Nothing Then Exit Sub If Target = "C" Then Zeile = Target.Row Range(Range(Cells(Zeile, 1), Cells(Zeile, 11)), _ Range(Cells(Zeile, 14), Cells(Zeile, 17))).Copy _ Destination:=Sheets("Completed Items").Cells(Rows.Count, 1).End(xlUp).Offset(6, 0) Target.EntireRow.Delete End If End Sub 的工作表。

Sheet1

将一行从Completed Items移至名为Sheet1的工作表。但是,仍然存在一些问题。

始终覆盖重定位的行

启动序列时,相应的行将从7中的Completed Items移至行7。但是,移动另一个行会导致Completed Items中的覆盖Offset()。这是为什么?我试图更改11选项,但到目前为止还没有任何结果。

VBA无法处理列141

之间的差距

我只想将111417 Sheet1Completed Items重新定位到Sheet1,以便该范围内的所有内容来自1的{​​{1}}已重新定位到15中的Completed Items列到1。但是,这不起作用,来自17所有列(Sheet1Completed Items)都会重新定位到{{1}}。有什么问题?

2 个答案:

答案 0 :(得分:2)

正如@arcadeprecinct所提到的,第一个问题很可能是因为您正在复制的第一行的A列中缺少值。

第二个问题是由于你如何定义范围 - 将两个范围作为参数传递给另一个范围将返回这两个范围的凸包,而不是它们不相交的联合。试试

Application.Union(Range(Cells(Zeile, 1), Cells(Zeile, 11)), Range(Cells(Zeile, 14), Cells(Zeile, 17))).Copy

代替。

答案 1 :(得分:1)

始终覆盖重定位的行

您正在确定要复制到Cells(Rows.Count, 1).End(xlUp)的行,这意味着A列中的最后一个单元格。复制行中的第一个单元格是否可能为空?

要在任何列中查找包含数据的最后一行,有多种方法。我发现最可靠的是使用.Find来搜索包含任何内容的最后一个单元格。

Function findLastRow(sh As Worksheet) As Long
    Dim tmpRng As Range 'need to use temporary range object in case nothing is found. (Trying to access .Row of Nothing causes error)

    Set tmpRng = sh.Cells.Find(What:="*", _
        After:=sh.Cells(1), _
        LookIn:=xlValues, _
        SearchOrder:=xlByRows, _
        SearchDirection:=xlPrevious)
    If Not tmpRng Is Nothing Then
        findLastRow = tmpRng.Row
    Else
        findLastRow = 1
    End If
End Function

使用UsedRange更容易,但可能不可靠,因为删除单元格内容后可能无法重置。

VBA无法处理第11列和第14列之间的差距

Range(X,Y)返回包含XY的最小矩形范围,因此在您的情况下,它与Range(Cells(Zeile, 1), Cells(Zeile, 17))

相同 不过,在这种情况下,您应该像使用目的地一样指定工作表。

正如@bobajob所说,您可以使用Union创建包含多个地区的范围,即使用Union(Range(Cells(Zeile, 1), Cells(Zeile, 11)), Range(Cells(Zeile, 14), Cells(Zeile, 17))).Copy

创建它的另一种方法是使用地址(例如第一行的“A1:K1,N1:Q1”):

Range("A" & Zeile & ":K" & Zeile & ",N" & Zeile & ":Q" & Zeile).Copy

然而,通常最好避免复制和粘贴(它很慢)并直接写入值。在你的情况下,它可以用

完成
Dim sh1 As Worksheet  'where to copy from
Dim sh2 As Worksheet  'where to copy to
Dim zielZeile As Long 'which row to copy to

Set sh1 = ThisWorkbook.Worksheets("sheetnamehere")
Set sh2 = ThisWorkbook.Worksheets("Completed Items")

'...
'set the row where to copy
zielZeile = findLastRow(sh2) + 6
'write to columns 1 to 11
sh2.Range(sh2.Cells(zielZeile, 1), sh2.Cells(zielZeile, 11)).Value = sh1.Range(sh1.Cells(Zeile, 1), sh1.Cells(Zeile, 11)).Value
'write to columns 12 to 115
sh2.Range(sh2.Cells(zielZeile, 12), sh2.Cells(zielZeile, 15)).Value = sh1.Range(sh1.Cells(Zeile, 14), sh1.Cells(Zeile, 17)).Value