Я обнаружил несоответствие в адресе диапазона источника для обрезанных ячеек.
У меня есть утилита в инструменте на основе Excel, которая переносит строки, выбранные пользователем. Затем пользователь должен выбрать пункт назначения, который может быть на том же листе или на другом листе.
Хорошо известна проблема отсутствия в Excel пустых строк при вырезании и вставке в другой лист (см. Вырезать строку с данными и перейти на другой лист VBA и Excel VBA удалить пустую строку после вырезания ) и у них есть решения для решения этой проблемы. Однако мой инструмент использует другой подход (аналогичный 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
Приведенные выше данные показывают, что диапазон source занял адрес вставленных ячеек, но не имя листа. Если бы адрес перерезанных ячеек должен был «переместиться», я ожидал бы, что он также возьмет новый лист.
Дополнительная информация - что еще я пытался сделать это?
- Я пытался создать копию исходных ячеек. Поскольку это копирование ссылки, я не ожидал, что она сработает, и не разочаровался.
Код:
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