我有以下代码:
Sub test()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim r As Long
Dim rng As Range
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
'Set some dummy data
For r = 1 To 20
ws1.Cells(r, "A").Value = r + 100
ws2.Cells(r, "A").Value = r + 200
Next
'Set a reference to Sheet1!A11
Set rng = ws1.Range("A11")
'Copy Sheet1 row 11 to Sheet2 row 5
rng.EntireRow.Cut ws2.Range("A5")
'Delete Sheet1 row 11
rng.EntireRow.Delete
End Sub
我为“Sheet1”的第11行中的单元格指定了引用。使用该引用,我Cut
行到“Sheet2”上的某个位置,然后我使用该引用从“Sheet1”中删除整行。
我的期望是“Sheet1”的第11行将被删除,在第1行到第10行的第A列101到110中留下值,在第11到19行留下112到120.
正在发生的事情是第11行被清除(由于Cut
)而第5行正在被删除。
删除第5行的事实似乎与第5行是Cut
语句的“Sheet2”上的目标行有关。如果它删除了“Sheet2”上的第5行,我可以理解发生了什么 - 即引用被重新命名为另一个工作表作为Cut
的一部分 - 但它删除了“Sheet1”上的第5行。
任何人都可以解释这种奇怪的行为吗?
注意:这个问题的灵感来自我尝试撰写this answer,我对该问题的OP发表的许多评论告诉他们“当然EntireRow.Delete
会删除你的行 - 你为什么要告诉我它不起作用“。
答案 0 :(得分:1)
使用“复制”代替“剪切”
rng.EntireRow.Copy ws2.Range(“A5”)
删除时,sheet1 A11的行不必为空
这是一个更简单的版本,显示了不良行为
Sub test()
Dim rng As Range
Set rng = Sheets("Sheet1").Range("A11")
rng.Value = "cut and paste me"
Sheets("Sheet1").Range("A11").Cut Sheets("Sheet2").Range("A5") ' rng object not used in this line
rng.Select ' selects Sheet1 A5 ... it should be Sheet2 A5
End Sub
它似乎是excel中的一个错误
由于剪切/粘贴有效地移动了剪切范围,因此excel将引用移动到新位置
excel将引用移动到正确的单元格,但无法移动到正确的工作表
如果您手动进行剪切/粘贴,则正确移动参考
例如:
如果,sheet1单元格A1包含“= B1”
然后切割sheet1单元格B1并将其粘贴到sheet2单元格C3
然后sheet1单元格A1将包含“= sheet2!C3”
答案 1 :(得分:0)
试试我的代码:
Sub test()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim r As Long
Dim rng As Range
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
'Set some dummy data
For r = 1 To 20
ws1.Cells(r, "A").Value = r + 100
ws2.Cells(r, "A").Value = r + 200
Next
'Set a reference to Sheet1!A11
Set rng = ws1.Range("A11")
'Copy Sheet1 row 11 to Sheet2 row 5
rng.EntireRow.Cut ws2.Range("A5")
'Delete Sheet1 row 11
Range("A:A").SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub
答案 2 :(得分:0)
正如@ASH所提到的,Debug.Print rng.Address(external:=True)
操作之前和之后的Cut
将分别打印结果[workbookName.xlsm]Sheet1!$A$11
和[workbookName.xlsm]Sheet1!$A$5
,原因是它会剪切对象和粘贴进入指定目的地并获取其地址。
作为Worksheet对象成员的Range Object无法更改其父级,因此它将继续保留为ws1
的成员。因此,尝试ws2.rng.EntireRow.Delete
将生成编译错误“未找到方法或数据成员”。
答案 3 :(得分:0)
可能的解释 - 但没有任何借口可以解决这个不明显的问题:
1)为什么不更换表格呢? -
.Cut
方法仅覆盖 Range
定义,因为它是
通过Worksheet
从属于ws1 = Worksheets("Sheet1")
对象集,
因此ws1
对象只获得一个新的目标范围$ A $ 5,但仍然是原始工作表
2)为什么要将源范围更改为目标? - IMO在方法代码本身中的极简主义。
3)该怎么做 - 重置原始范围(参见下面的代码):
Sub test()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim r As Long
Dim rng As Range
Set ws1 = Worksheets("Sheet1")
Set ws2 = Worksheets("Sheet2")
'Set some dummy data
For r = 1 To 20
ws1.Cells(r, "A").Value = r + 100
ws2.Cells(r, "A").Value = r + 200
Next
' Set a reference to Sheet1!A11
Set rng = ws1.Range("A11")
' Copy Sheet1 row 11 to Sheet2 row 5
rng.EntireRow.Cut ws2.Range("A5")
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' Possible explication - but no excuse for this not obvious comportment:
' 1) Why not changing the sheet, too? -
' The CUT method overwrites only the RANGE definition because it is
' subordinated to the worksheet object set via ws1 = Worksheets("Sheet1"),
' thus the ws1 object only gets a new target range $A$5 but remains the original sheet
' 2) Why changing the source range to target? -
' IMO sort of minimalism within the method code itself.
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' >> check range definition after executing CUT - rng definitively remains in sheet1
MsgBox "Range rng: " & rng.Worksheet.Name & "!" & rng.Address & vbNewLine & _
"Entire row: " & rng.EntireRow.Address & " ", vbInformation, "rng.Address"
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' If you want to do something with the original range you have to reset it
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' >> reset rng before further action as deleting source
Set rng = ws1.Range("A11") ' << resetting rng necessary
' Delete Sheet1 row 11
rng.EntireRow.Delete
End Sub