VBA перемещает данные строки на свой связанный лист, но если найдена дублирующаяся строка, пропустите эту строку

#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. Невероятно, у вас действительно талант уровня бога. Спасибо, мистер ФанеДуру, снимаю шляпу.