Я пытаюсь написать код, который перемещает строку с одного листа на другой при изменении значения в одном столбце. В целях тестирования указано, что если в ячейке в столбце 13 указано «Тест», то эта строка удаляется из исходного листа и перемещается на новый лист «Тестовый лист». Тем не менее, я пытаюсь вставить строку, перемещенную в новую, как значения, но когда я пытаюсь включить Pastespecial, появляются ошибки.
Это мой код в его нынешнем виде
Sub move_rows_to_another_sheet_master()
For Each myCell In Selection.Columns(13).Cells
If myCell.Value = "Test" Then
myCell.EntireRow.Copy Worksheets("TestSheet").Range("A" & Rows.Count).End(3)(2)
myCell.EntireRow.Delete
End If
Next
End Sub
Я почти уверен, что мне нужно где-то включить «PasteSpecial Paste:=xlValues», но везде, где я пытаюсь его включить, похоже, это не работает.
Покажите фактический код, который вы используете для вставки на другой лист, и точные сообщения об ошибках, которые он выдает. Вы можете создать макрос с помощью функции записи макросов в Excel. Записывая каждый шаг, делая это вручную, вы сможете найти решение самостоятельно.
По сути, это тот же самый код, который я использую, и я не могу сохранить то, что у меня есть, потому что строка с копированием и вставкой становится красной и говорит: «Ошибка компиляции: Ожидается: конец оператора», когда я пытаюсь добавить «.PasteSpecial Paste:=». xlPasteValues» до конца строки 4.
''' Sub move_rows_to_another_sheet_test() для каждой ячейки myCell в Selection.Columns(13).Cells If myCell.Value = "Test" Тогда myCell.EntireRow.Copy Worksheets("TestSheet").Range("A" & Rows.Count) .End(3)(2).PasteSpecial Paste:=xlPasteValues myCell.EntireRow.Delete End If Next End Sub ''' Это то, что я пытаюсь сделать, и получаю упомянутую выше ошибку. Он прекрасно работает без текста «.PasteSpecial Paste:=xlPasteValues». Но мне нужно его вставить как значения
Я заменил пустую строку на Rows.Count, сейчас отредактирую
Думаю, я решил это сам, мне просто нужно было поместить копирование и вставку в отдельные строки, и это сработало!


РЕДАКТИРОВАТЬ Комментарий @BigBen перефразировал ответ.
Неисправный код заключается в том, что вы хотите скопировать всю строку, но цель не охватывает всю строку. Поэтому попробуйте следующее:
myCell.EntireRow.Copy Worksheets("TestSheet").Range("B" & Rows.Count).End(xlUp)(2).EntireRow
Если вы хотите вставить первую пустую строку, используйте Offset
myCell.EntireRow.Copy Worksheets("TestSheet").Range("A" & Rows.Count).End(xlUp).Offset(1)
Если в исходном диапазоне есть формулы и вам нужны только значения, либо используйте только абсолютные ссылки, либо не можете напрямую скопировать/вставить диапазон. Тогда, как вы решили, нужно использовать PasteSpecial
myCell.EntireRow.Copy
Worksheets("TestSheet").Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial(xlPasteValues)
То, как я это сделал изначально, сработало, но я попробовал и ваш способ, и он тоже сработал! Я вообще не очень хорошо разбираюсь в коде VBA. Есть ли между ними существенная разница? Или что-то, что предлагает ваше решение, чего нет в моей текущей настройке? Кроме того, допустим, мне нужно было исходное приглашение для отправки строк с «Test» в столбце 13 в «TestSheet», но я также хотел отправить строки с «Test2» в столбце 13 в «TestSheet2» и строки с «Test3» в столбец 13 в «TestSheet3»? Могу ли я просто скопировать и вставить исходный код подряд с разными параметрами и «следующим» между ними?
Существенной разницы нет, использование имен констант и явных выражений более понятно окружающим. Кажется, самый простой способ использовать ElseIf sg. вот так: If myCell.Value = "Test" Then -part1- ElseIf myCell.Value = "Test2" Then -part2- ElseIf myCell.Value = "Test3" Then -part3- Else -part4- End If
Ах, спасибо! Я попробую это с помощью «ElseIf». Если бы я использовал предложенный вами код, куда бы вы поместили ElseIf? Будет ли это просто заменить «Если» в строке 5?
Попробуйте этот код:
Sub move_rows_to_another_sheet_master()
Dim myCell As Range, ToDelete As Range
Set ToDelete = Range("A" & Rows.Count) ' initialize ToDelete
For Each myCell In Selection.Columns(13).Cells
If myCell.Value = "Test" Then
Worksheets("TestSheet").Range("A" & Rows.Count).End(xlUp)(2).EntireRow.Value = myCell.EntireRow.Value
Set ToDelete = Union(ToDelete, myCell)
End If
Next myCell
ToDelete.EntireRow.Delete
End Sub
С вашим кодом есть 2 проблемы.
For Each идет от начала до конца, и вы удаляете строки во время этого цикла, вы пропускаете строки. Обычно нам следует делать это в обратном порядке. Но вам нужно иметь скопированные строки без реверса.Не имеет значения, я скопировал исходный код.
Для ОП: (2) было бы намного понятнее, если бы вы использовали .Offset.
Опять же, я использовал обозначение OP. Для меня это понятно, означает следующую строку и короче .Offset(1).
Вместо зацикливания просто используйте автофильтр, как показано ЗДЕСЬ