#vba
#vba
Вопрос:
У меня есть лист с именем «НЕОБРАБОТАННЫЕ ЭЛЕМЕНТЫ» с данными, а также есть еще несколько листов с другим именем, где мне нужно переместить данные с листа «НЕОБРАБОТАННЫЕ ЭЛЕМЕНТЫ». и все имена листов доступны на листе «НЕОБРАБОТАННЫЕ ЭЛЕМЕНТЫ» в столбцах С3 по С100. Когда я запускаю приведенный ниже код, он работает хорошо, когда я запускаю его в первый раз. Но когда я добавляю некоторые данные на лист «НЕОБРАБОТАННЫЕ ЭЛЕМЕНТЫ», это также перемещает более ранние строки на их связанный лист. Я не могу понять, как остановить перемещение повторяющихся строк. Я имею в виду, как пропустить, если дубликат raw найден на тех листах, где перемещаются данные?
Sub copyPasteData()
Dim PV As String
Dim ps As String
Dim LastRow As Long
PV = "RAW ITEMS"
Sheets(PV).Visible = True
Sheets(PV).Select
Range("C3").Select
Do While ActiveCell.Value <> ""
ps = ActiveCell.Value
ActiveCell.Offset(0, -2).Resize(1, ActiveCell.CurrentRegion.Columns.Count).Select
Selection.Copy
Sheets(ps).Visible = True
Sheets(ps).Select
LastRow = pvs("A")
Cells(LastRow 1, 1).Select
Selection.PasteSpecial xlPasteValues
Application.CutCopyMode = False
Sheets(PV).Select
ActiveCell.Offset(0, 2).Select
ActiveCell.Offset(1, 0).Select
Loop
Range("A1").Select
End Sub
Public Function pvs(col)
Dim LastRow As Long
With ActiveSheet
LastRow = .Cells(.Rows.Count, col).End(xlUp).Row
End With
pvs = LastRow
End Function
Я новичок в VBA. Пожалуйста, помогите мне.
как пропустить, если дубликат raw найден на тех листах, на которых перемещаются данные?
Комментарии:
1. Вы должны посмотреть; Введение в Excel VBA, часть 5 — Выбор ячеек (диапазон, ячейки, Activecell, конец, смещение) , чтобы узнать, как работать с диапазонами.
2. Это помогло бы получить образцы данных. Наилучший подход будет отличаться в зависимости от того, имеют ли данные уникальную идею или нет. Если исходные данные элемента никогда не будут отсортированы, вы можете сохранить запись последней обработанной строки и запустить цикл после этой строки.
Ответ №1:
Попробуйте следующий код, пожалуйста. Это позволяет избежать любого выбора, активации, которая потребляет ресурсы Excel, не принося никакой пользы. Это должно быть быстро, с использованием массивов и работы в памяти:
Sub copyPasteData()
Dim PVWs As Worksheet, PSWs As Worksheet, arrPV, arrPS, arPV, arPS
Dim LastRPv As Long, LastRPs As Long, lastCol As Long, i As Long
Dim j As Long, boolCopy As Boolean
Set PVWs = Worksheets("RAW ITEMS")
LastRPv = PVWs.Range("C" amp; Rows.Count).End(xlUp).Row
lastCol = PVWs.UsedRange.Columns.Count
'load the range in an array:
arrPV = PVWs.Range(PVWs.Range("A" amp; 2), PVWs.Cells(LastRPv, lastCol)).Value
For i = 1 To UBound(arrPV) 'iterate between the array rows
On Error Resume Next
Set PSWs = Worksheets(CStr(arrPV(i, 3))) 'set the sheet to paste, if no a similar row exists
If Err.Number = 9 Then
Err.Clear: On Error GoTo 0
Dim ans As VbMsgBoxResult
ans = MsgBox("The sheet " amp; CStr(arrPV(i, 3)) amp; " does not exist!" amp; vbCrLf amp; _
"Would you like to create it?", vbYesNo, "Sheet creation confirmation")
If ans <> vbYes Then GoTo OverIt
Set PSWs = Worksheets.Add(after:=Worksheets(Worksheets.Count)) 'add the new sheet (after the last)
PSWs.Name = arrPV(i, 3) 'name the newly inserted sheet
'copy the header from the previous sheet:
PSWs.Previous.Range("A1:G1").Copy Destination:=PSWs.Range("A1")
End If
On Error GoTo 0
arPV = Application.Index(arrPV, i, 0) 'a slice of the i row (1D array)
LastRPs = PSWs.Range("A" amp; Rows.Count).End(xlUp).Row 'last row
'load the sheet existing range in an array
arrPS = PSWs.Range(PSWs.Range("A" amp; 1), PSWs.Cells(LastRPs, lastCol)).Value
For j = 1 To UBound(arrPS) ' iterate and check if the sliced rows are all the elements identic
boolCopy = True
arPS = Application.Index(arrPS, j, 0) 'a slice of the j row (1D array)
If Join(arPV, "|") = Join(arPS, "|") Then 'check if the rows are the same
boolCopy = False: Exit For
End If
Next j
If boolCopy Then
'if not alsready in the sheet, the array is copied
PSWs.Range("A" amp; LastRPs 1).Resize(1, UBound(arPV)).Value = arPV
boolCopy = False 'reinitialize the Boolean variable
End If
OverIt:
Next i
End Sub
Логика кода предполагает, что «повторяющаяся строка» означает, что все значения ячеек на листе для копирования строки идентичны значениям анализируемой строки, подлежащей копированию.
И в столбце C должно существовать имя самого листа…
Комментарии:
1. @Prabhat Vishwas: Вы нашли время для тестирования приведенного выше кода?
2. Уважаемый г-н Фанедуру, спасибо за ваш любезный ответ. для вашего лучшего понимания я загружаю файл для вас. [ссылка] ( mega.nz/file /… ).
3. @Prabhat Vishwas: Я не мог себе представить, что вы назовете листы 1, 2, 3… В VBA
Worksheet(1)
означает первый лист иWorksheet("1")
означает лист с именем «1» . Я адаптирую код для преобразования строки. Кроме того, я думаю, что хорошо позволить коду проверить, существует ли имя листа столбца C, и если нет, спросить о его создании. Если вы нажмете «Да», он будет добавлен после последнего. Если нет, эта строка будет пропущена. Возможно, вы только неправильно написали имя и исправите его после запуска кода.4. Адаптировал приведенный выше код. Вот адаптированная рабочая книга. Мы здесь, если кто-то потратит некоторое время и решит наш вопрос, проголосуйте за ответ и, что наиболее важно, установите флажок code слева, чтобы сделать его принятым ответом . Таким образом, кто-то другой, ищущий аналогичную проблему, узнает, что код работает…
5. Невероятно, у вас действительно талант уровня бога. Спасибо, мистер ФанеДуру, снимаю шляпу.