我发现剪切单元的源范围地址不一致。
我在基于Excel的工具中有一个实用程序,可以迁移用户选择的行。然后,用户必须选择目的地,该目的地可以在同一张纸上,也可以在另一张纸上。
众所周知,Excel在剪切和插入到另一张纸时留空行的问题(参见Cutting Row with Data and moving to different sheet VBA和Excel VBA remove blank row after cut),并且它们有解决此问题的解决方案。但是,我的工具使用了另一种方法(类似于https://stackoverflow.com/a/27093382/9101981),现在我将展示它无法按预期工作。
Sub TestMigration()
'' Source Cells = migrateSource.Range("A3:A4") ' this simulates how the ranges are selected in the real world application
'' Target Cells = migrateTarget.Range("A7") ' this simulates the real world application where this is chosen through a pick box
MigrateRows migrateSource.Range("A3:A4"), migrateTarget.Range("A7")
End Sub
Sub MigrateRows(sourceCells As Range, targetCells As Range)
Debug.Print "Original source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
sourceCells.EntireRow.Cut ' the command used in the real world application
Debug.Print "After cut source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
targetCells.Insert
Debug.Print "After insert source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
If Not (sourceCells.Worksheet Is targetCells.Worksheet) Then sourceCells.EntireRow.Delete
End Sub
源数据和目标数据是:
预期结果是:
原始来源地址:MigrateSource,$ A $ 3:$ A $ 4
剪切后的源地址:MigrateSource,$ A $ 3:$ A $ 4
在插入源地址之后:MigrateSource,$ A $ 3:$ A $ 4
实际结果是:
原始来源地址:MigrateSource,$ A $ 3:$ A $ 4
剪切后的源地址:MigrateSource,$ A $ 3:$ A $ 4
在插入源地址之后:MigrateSource,$ A $ 7:$ A $ 8
上面的数据显示,源范围采用了插入单元格的地址,但不是工作表名称。如果剪切的单元格地址是要“移动”的,我希望它也可以使用新的工作表。
代码:
Sub MigrateRows1(sourceCells As Range, targetCells As Range)
Dim tSourceRowsCopy As Range
Set tSourceRowsCopy = sourceCells
Debug.Print "Original source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
sourceCells.EntireRow.Cut ' the command used in the real world application
Debug.Print "After cut source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
Debug.Print "After cut source_copy address: " & tSourceRowsCopy.Worksheet.Name & "," & tSourceRowsCopy.Address
targetCells.Insert
Debug.Print "After insert source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
Debug.Print "After insert source_copy address: " & tSourceRowsCopy.Worksheet.Name & "," & tSourceRowsCopy.Address
If Not (sourceCells.Worksheet Is targetCells.Worksheet) Then tSourceRowsCopy.EntireRow.Delete
'Debug.Print "After delete source address: " & tSourceRows.Worksheet.Name & "," & tSourceRows.Address
'Debug.Print "After delete source_copy address: " & tSourceRowsCopy.Worksheet.Name & "," & tSourceRowsCopy.Address
End Sub
测试运行1(MigrateRows1)
原始来源地址:MigrateSource,$ A $ 3:$ A $ 4
剪切后的源地址:MigrateSource,$ A $ 3:$ A $ 4
剪切后的source_copy地址:MigrateSource,$ A $ 3:$ A $ 4
在插入源地址之后:MigrateSource,$ A $ 7:$ A $ 8
在插入source_copy地址之后:MigrateSource,$ A $ 7:$ A $ 8
结果:无变化
代码:
Sub MigrateRows2(sourceCells As Range, targetCells As Range)
Dim tSourceRowsCopy As Range
Dim tSourceAddress As String
tSourceAddress = sourceCells.Address
Set tSourceRowsCopy = sourceCells.Worksheet.Range(tSourceAddress)
Debug.Print "Original source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
sourceCells.EntireRow.Cut ' the command used in the real world application
Debug.Print "After cut source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
Debug.Print "After cut source_copy address: " & tSourceRowsCopy.Worksheet.Name & "," & tSourceRowsCopy.Address
targetCells.Insert
Debug.Print "After insert source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
Debug.Print "After insert source_copy address: " & tSourceRowsCopy.Worksheet.Name & "," & tSourceRowsCopy.Address
If Not (sourceCells.Worksheet Is targetCells.Worksheet) Then tSourceRowsCopy.Delete
' Debug.Print "After delete source address: " & tSourceRows.Worksheet.Name & "," & tSourceRows.Address
' Debug.Print "After delete source_copy address: " & tSourceRowsCopy.Worksheet.Name & "," & tSourceRowsCopy.Address
End Sub
测试运行2(MigrateRows2)
原始来源地址:MigrateSource,$ A $ 3:$ A $ 4
剪切后的源地址:MigrateSource,$ A $ 3:$ A $ 4
剪切后的source_copy地址:MigrateSource,$ A $ 3:$ A $ 4
在插入源地址之后:MigrateSource,$ A $ 7:$ A $ 8
在插入source_copy地址之后:MigrateSource,$ A $ 7:$ A $ 8
结果:无变化
代码:
Sub MigrateRows3(sourceCells As Range, targetCells As Range)
Dim tSourceAddress As String
tSourceAddress = sourceCells.Address
Debug.Print "Original source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
sourceCells.EntireRow.Cut ' the command used in the real world application
Debug.Print "After cut source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
targetCells.Insert
Debug.Print "After insert source address: " & sourceCells.Worksheet.Name & "," & sourceCells.Address
Debug.Print "Address to be deleted: " & sourceCells.Worksheet.Name & "," & tSourceAddress
If Not (sourceCells.Worksheet Is targetCells.Worksheet) Then sourceCells.Worksheet.Range(tSourceAddress).Delete
'Debug.Print "After delete source address: " & tSourceRows.Worksheet.Name & "," & tSourceRows.Address
End Sub