Долгая работа макроса, который сравнивает данные из двух листов
Ищу в мэппинговой таблице и расставляю на основной что нашёл в мэппинге и что не нашёл:
Sub CheckCCRCompleteness()
'1. Создаёт ключ в колонке №44 (закладка "Data"): №4 & №6 & №12 в требуемом отчётном месяце'
'2. Смотрит есть ли созданный на шаге №1 ключ в массиве ключей на закладке "Completeness CCR" в соответствующем отчётном месяце (месяц определяется как первое число каждого отчётного месяца)'
'3. Если ключ с шага №1 не найден на шаге №2, то в колонке №44 (закладка "Data") ставит признак "Нет на CCR" (если обнаружил, то ставит признак "ОК")'
'Примечание: изначально в колонке №44 (закладка "Data") сделал формулу для проверки, но тогда файл долго пересчитывается (поэтому было решено сделать кнопку, которая будет для каждого отчётного месяца создавать ключи (в колонке №44 (закладка "Data")) и проверять его наличие на закладке "Completeness CCR"'
Dim SourceData As Worksheet: Set SourceData = ThisWorkbook.Sheets("Data") 'Определяем закладку-источник данных'
Dim Mapping As Worksheet: Set Mapping = ThisWorkbook.Sheets("Completess CCR") 'Определяем источник мэппинга'
Dim SourceDataLstr As Long, MappingLstr As Long
Dim i As Long, j As Long
Dim RawDataKey As String, MappingKey As String
Dim ReportMonth As Date
Dim ReportMonthCol As Long
Dim Rng As Range
SourceDataLstr = SourceData.Range("A" & Rows.Count).End(xlUp).Row 'Находим последнюю строку на закладке-источнике'
MappingLstr = Mapping.Range("A" & Rows.Count).End(xlUp).Row 'Находим последнюю строку на источнике мэппинга'
ReportMonth = InputBox("Введите первую дату отчётного месяца (например, 01.12.2019)") 'Задаём отчётный месяц, в котором генерируем ключ'
'Определяем номер столбца на закладке "Completeness CCR", в котором содержатся ключи требуемого отчётного месяца'
Set Rng = Sheets("Completess CCR").Rows(1).Find(ReportMonth, , xlFormulas, xlWhole)
ReportMonthCol = Rng.Column
'Debug.Print ReportMonthCol'
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With SourceData
For i = 2 To SourceDataLstr
If Cells(i, 12).Value = ReportMonth Then
RawDataKey = .Cells(i, 4).Value & .Cells(i, 6).Value & .Cells(i, 12).Value
For j = 2 To MappingLstr
MappingKey = Mapping.Cells(j, ReportMonthCol).Value
If MappingKey <> RawDataKey Then
.Cells(i, 44).Value = "Нет на CCR"
Else: .Cells(i, 44).Value = "OK"
Exit For
End If
Next j
Else
End If
Next i
End With
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Уходит в небытие... где-то здесь:
If MappingKey <> RawDataKey Then
.Cells(i, 44).Value = "Нет на CCR"
Else: .Cells(i, 44).Value = "OK"
Exit For
Ответы (1 шт):
Автор решения: vikttur
→ Ссылка
Уходим от медленной работы с объектами листа. По одному разу обращаемся к листам для получения данных и еще раз - выгружаем результат.
Sub CheckCCRCompleteness()
Dim aData(), aMapp(), aResult()
Dim ReportMonthCol As Long, ReportMonth
Dim bFlag As Boolean
Dim RawDataKey As String
Dim i As Long, n As Long
Call Extraction_(aMapp, Worksheets("Completess CCR"))
Call Extraction_(aData, Worksheets("Data"))
ReDim aResult(1 To UBound(aData), 1 To 1)
aResult(1, 1) = Worksheets("Data").Cells(1, 44).Value
ReportMonth = Val(InputBox("Введите номер отчетного месяца (от 1 до 12)"))
If ReportMonth < 1 Or ReportMonth > 12 Then
MsgBox "Неправильно указан месяц", 64, "ОШИБКА": Exit Sub
Else
ReportMonth = DateSerial(Year(Date), ReportMonth, 1)
End If
ReportMonthCol = fFindMonth(aMapp, ReportMonth)
If ReportMonthCol = 0 Then Exit Sub
For i = 2 To UBound(aData)
If aData(i, 12) = ReportMonth Then
RawDataKey = aData(i, 4) & aData(i, 6) & CDbl(aData(i, 12))
For n = 2 To UBound(aMapp)
If aMapp(n, ReportMonthCol) = RawDataKey Then
aResult(i, 1) = "OK"
bFlag = True: Exit For
End If
Next n
If bFlag = False Then aResult(i, 1) = "Нет на CCR" Else bFlag = False
End If
Next i
Worksheets("Data").Cells(1, 44).Resize(UBound(aData), 1).Value = aResult
End Sub
Sub Extraction_(aArr(), sht As Worksheet)
Dim lLastRow As Long
With sht
lLastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
If lLastRow < 2 Then End
aArr = .Range("A1:L" & lLastRow).Value
End With
End Sub
Function fFindMonth(aMapp(), ReportMonth) As Long
Dim j As Long
For j = 4 To UBound(aMapp, 2)
If aMapp(1, j) = ReportMonth Then
fFindMonth = j: Exit Function
End If
Next j
End Function
Если нужно, добавьте отключение/включение обновления экрана и пересчетов.