Использование функции поиска VBA для проверки наличия диапазона на листе Excel - PullRequest
0 голосов
/ 14 мая 2018

Очень плохо знаком с VBA (и программированием в целом), пытаясь научить себя информации, которую я могу найти в Интернете.

Запись макроса, который будет копировать данные о производительности сотрудников, которые построчно заносятся в ГЛАВНЫЙ лист, на лист LOG рабочей книги.

До этого момента мне удавалось заставить его работать нормально. Но теперь я хочу добавить функцию FIND, чтобы определить, существует ли уже строка данных на листе LOG, чтобы я мог затем использовать оператор IF ... THEN:

  • Если данные по конкретному сотруднику И дате не еще существуют, то эта строка копируется в первую пустую строку листа журнала.
  • Если уже существует , существующая строка данных на листе журнала будет перезаписана.

Вот что у меня есть:

Sub CopyToLog()

Dim RowCount As Integer

    Sheets("MAIN").Select

    For RowCount = 1 To Range("WeeklyData").Rows.Count

        With Sheets("LOG").Range("A:B")
        Set Dupe = .Find(Sheets("MAIN").Range("B5:C5").Offset(RowCount - 1, 0), LookIn:=xlValues)

        Range("B5:F5").Offset(RowCount - 1, 0).Select
        Selection.Copy

        Sheets("LOG").Select

            If Dupe Is Nothing Then

            Range("A" & Rows.Count).End(xlUp).Offset(1).Select
            Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False

            Else

            Dupe.Select
            Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
            :=False, Transpose:=False

            End If
        End With

    Sheets("MAIN").Select

    Next RowCount

End Sub

Однако это не работает. Похоже, проблема в функции поиска:

With Sheets("LOG").Range("A:B")       
Set Dupe = .Find(Sheets("MAIN").Range("B5:C5").Offset(RowCount - 1, 0), LookIn:=xlValues)

I необходимо для проверки обоих Дата и Employee (столбцы B и C на ГЛАВНОМ листе против столбцов A и B на листе LOG), однако, кажется, что формула в том виде, в каком она здесь, сравнивает только первый столбец (Дата) В результате данные для одного сотрудника теперь перезаписываются следующим сотрудником, если они относятся к той же дате.

Можно ли использовать «Найти» только для поиска значения в одной ячейке, а не для диапазона двух соседних ячеек? Если да, то какие советы как обойти это?

1 Ответ

0 голосов
/ 14 мая 2018

Похоже, что вспомогательные клетки могут выполнить то, что вы ищете. Я предполагаю, что у вас есть место в клетке D5 рядом с Sheets("MAIN").Range("B5:C5"). Введите в формуле =B5&C5 в D5. Это даст вам комбинацию из двух и позволит вам достичь желаемого результата. Вам также понадобится вспомогательный столбец для диапазона поиска в журнале. Если ваша информация начинается в строке 10 в ячейке C10, введите =A10&B10, при необходимости скопируйте. Теперь вы можете использовать их для проверки. Я изменил ваш код, чтобы использовать вспомогательные ячейки.

Sub CopyToLog()
    Dim main As Worksheet
    Set main = ThisWorkbook.Worksheet("MAIN")

    Dim log As Worksheet
    Set log = ThisWorkbook.Worksheets("LOG")

    Dim searchRange As Range
    Set searchRange = log.Range("C:C") 'Helper Column

    Dim RowCount As Integer
    For RowCount = 1 To main.Range("WeeklyData").Rows.Count
        Dim lookFor As String
        lookFor = main.Range("D5").Offset(RowCount - 1, 0).Value2 'Uses helper cells

        Dim dupe As Range
        Set dupe = searchRange.Find(lookFor, LookIn:=xlValues)

        Dim copyInfo As Range
        Set copyInfo = searchRange.Range("B5:F5").Offset(RowCount - 1, 0)

        Dim destination As Range
        If dupe Is Nothing Then
            Set destination = log.Range("A" & Rows.Count).End(xlUp).Offset(1)
        Else
            Set destination = dupe
        End If

        destination.Resize(ColumnSize:=copyInfo.Columns.Count).Value2 = copyInfo.Value2
    Next

    main.Select
End Sub

Работа с самими объектами. Я удалил пары .Select и Selection.. Отказ от их использования сделает ваш код более читабельным и быстрым. Чтобы начать работу, рекордер макросов будет использовать их, но имейте в виду, что вы можете сгруппировать их (IE Range("M10").Select, за которым следует Selection.Copy, лучше всего записать как Range("M10").Copy).

Я заменил все неквалифицированные переменные Range квалифицированными. Range - это простота, использующая ActiveSheet, по сути это ActiveSheet.Range. Определение его с помощью объекта листа, такого как main.Range("A5"), позволяет точно определить, с какого листа он поступает. Это избавит вас от следующих моментов, когда выдергиваете волосы.

destination.Resize(ColumnSize:=copyInfo.Columns.Count).Value2 = copyInfo.Value2 делает то же самое, что напрямую копирует значения. Изменение размера используется, чтобы оба диапазона были одинакового размера.

...