Почему Excel непоследовательно управляет диапазоном строк обрезки во время вырезания и вставки на новый лист? - PullRequest
0 голосов
/ 24 марта 2019

Я обнаружил несоответствие в адресе диапазона источника для обрезанных ячеек.

У меня есть утилита в инструменте на основе 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

Исходные и целевые данные:

Source dataTarget data

Ожидаемые результаты:

Expected source data after cut and insertExpected target data after cut and insert

Исходный адрес источника: MigrateSource, $ A $ 3: $ A $ 4

После сокращения адрес источника: MigrateSource, $ A $ 3: $ A $ 4

После вставки адреса источника: MigrateSource, $ A $ 3: $ A $ 4

Фактические результаты:

enter image description hereenter image description here

Исходный адрес источника: MigrateSource, $ A $ 3: $ A $ 4

После сокращения адрес источника: MigrateSource, $ A $ 3: $ A $ 4

После вставки адреса источника: MigrateSource, $ A $ 7: $ A $ 8

Приведенные выше данные показывают, что диапазон source занял адрес вставленных ячеек, но не имя листа. Если бы адрес перерезанных ячеек должен был «переместиться», я ожидал бы, что он также возьмет новый лист.

Дополнительная информация - что еще я пытался сделать это?

  1. Я пытался создать копию исходных ячеек. Поскольку это копирование ссылки, я не ожидал, что она сработает, и не разочаровался.

Код:

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

Результат: без изменений

  1. Я пытался создать новую ссылку на основе адреса, но создал эту ссылку перед переездом.

Код:

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

Результат: без изменений

  1. Я попытался сохранить адрес, а затем создать новую ссылку перед удалением. Это сработало.

Код:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...