Страницы: 1
RSS
Проверить идентичность таблиц макросом
 
Дернуло меня сверить две таблицы, с целью сэкономить время за счет исключения напрасной процедуры обновления данных. Оказалось - палка о двух концах.
Придумал цикл - for each (есть в примере). Он хорошо справляется с небольшими массивами. На больших таблицах, если долго перебирает, то вгоняет Эксель в кому.
Стал разбираться со словарями - не разобрался. Но, заметил что большие массивы загружаются относительно долго. Если данные разнятся в начале таблиц,то цикл оказывается гораздо быстрее. Как можно оптимизировать эти дела?

Пример нужно немножко "приготовить". Первый макрос раздует файл до 5 МБ - по 1 млн.ячеек на каждый лист.
 
Подскажите пожалуйста, как избавиться от On Error Resume Next ?  Ошибка возникает когда не совпадают размеры диапазонов. Вместо UsedRange у меня пара Lastrow\Lastrcol для каждой книги.
Код
Dim x(), y(), i, j As Variant
x = Worksheets(1).UsedRange.Value
y = Worksheets(2).UsedRange.Value
For i = 1 To UBound(x)
    For j = 1 To UBound(x, 2)
        'On Error Resume Next
        If x(i, j) <> y(i, j) Then
           mmmm = "1"
           Exit For
        End If
    Next j
Next i
Изменено: qwerrr - 10.08.2017 17:40:00
 
У вас в цикле ориентир на массив x причем здесь y.
Да и файл пустой!

а это вообще не понятно зачем!
Код
           mmmm = "1"
           Exit For
Изменено: Nordheim - 10.08.2017 16:46:55
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, К примеру: y(i, j) оказывается на строку ниже LastRow.
Переменная указывает на несовпадение значений. Дальше выход.
 
и откуда известно что массив y содержит индексы i и j.
Пример у вас пустой, занесите данные , можно будет посмотреть. а так не на что пока смотреть.
Но цикл не  будет выдавать ошибку только в том случае если массив y меньше массива x. да и сверка у вас некорректная,
вы сравниваете конкретный адрес с конкретным адресом, по моему это не имеет смысла!!!  
Изменено: Nordheim - 10.08.2017 16:57:40
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, В примере нужно запустить первый макрос - он заполнит листы. For Each в файле тормозной, т.е. не нужен. Новый цикл сравнивает значения.
Изменено: qwerrr - 10.08.2017 17:05:42
 
Цитата
qwerrr написал:
В примере нужно запустить первый макрос - он заполнит листы
Т.е. вы просите помощи и параллельно ребусы загадываете. Нужно догадаться запустить макрос , что бы он заполнил данными лист, и только после этого начинать думать над вопросом. Интересную вы помощь просите!!!
"Все гениальное просто, а все простое гениально!!!"
 
 Вот тут непонятно зачем используется оператор
Код
[/CODE][CODE] With...End With 
или  
Код
.Activate
Код
  With Sheets("Лист1")
        .Activate
        .Range(Cells(1, 1), Cells(40000, 25)) = "o"
    End With
    With Sheets("Лист2")
        .Range(Cells(1, 1), Cells(40000, 25)) = "o"
         x = Cells(Rows.Count, 1).End(xlUp).Row
        .Cells(x, 10) = "" 'Изменить
    End With
End Sub
Изменено: Nordheim - 10.08.2017 19:59:13
"Все гениальное просто, а все простое гениально!!!"
 
Цитата
qwerrr написал:
Новый цикл сравнивает значения.
Какие значения? У вас сравнивается ячейка с ячейкой без перебора.
т.у. то же самое что и:
Код
A1=B1
A2=B2
A3=B3

Цикл должен работать подругому (в моем понимании):
Код
A1=B1:A1=B2:A1=B3
A2=B1:A2=B2:A2=B3
A3=B1:A3=B2:A3=B3
У вас происходит сравнение по первому варианту. что мне кажется теряет смысл всего цикла!!!
"Все гениальное просто, а все простое гениально!!!"
 
Nordheim, Какой ребус? Зачем ребус?  :D  Сообщение прочитали и нет ребуса. Я всегда так делаю... :oops:  И для чего вы разбираете второстепенный скрипт? Ему же на свалку... Причину ошибки я у себя нашел. Кстати еще раз спасибо за тот код в первой моей теме, шикарная штука, грызет одновременно восемь столбцов за мгновения. Всего доброго.
 
Цитата
qwerrr написал:
И для чего вы разбираете второстепенный скрипт? Ему же на свалку...
Если в скрипте "на свалку ошибки", думаете в основном их не будет:) Это заблуждение, нужно ко всему подходить грамотно. даже к скриптам "на свалку" :)
Цитата
qwerrr написал:
Кстати еще раз спасибо за тот код в первой моей теме, шикарная штука, грызет одновременно восемь столбцов за мгновения
Всегда пожалуйста :)
"Все гениальное просто, а все простое гениально!!!"
 
Если правильно понял задачу, я бы делал так:
Код
Sub SheetsDataComparision()
    Dim arr1 As Variant, arr2 As Variant, flag As Boolean, flag_loop As Byte
    arr1 = Worksheets("Лист1").UsedRange.Value
    arr2 = Worksheets("Лист2").UsedRange.Value
    flag = True
    If (UBound(arr1, 1) = UBound(arr2, 1)) And (UBound(arr1, 2) = UBound(arr2, 2)) Then
      flag_loop = 0
      i = LBound(arr1, 1)
      Do While (i <= UBound(arr1, 1)) And (flag_loop = 0)
         j = LBound(arr1, 2)
         Do While (j <= UBound(arr1, 2)) And (flag_loop = 0)
            If arr1(i, j) <> arr2(i, j) Then
               flag_loop = 1
               flag = False
            End If
            j = j + 1
         Loop
         i = i + 1
      Loop
    Else
      flag = False
    End If
    If flag Then
      MsgBox ("Данные на листах совпадают")
    Else
      MsgBox ("Данные на листах не совпадают")
    End If
End Sub
 
Пробуйте!
Код
Sub Test1()   'Бежать до первого отличия
Dim arr1(), arr2(), metka As Boolean
Dim  i&, j&
metka = False
arr1 = Sheets(1).UsedRange.Value
arr2 = Sheets(2).UsedRange.Value
If UBound(arr1) <> UBound(arr2) Or UBound(arr1, 2) <> UBound(arr2, 2) Then _
    MsgBox "Таблицы не совпадают 100%", vbInformation + vbCritical: Exit Sub
For i = LBound(arr1) To UBound(arr1)
    For j = LBound(arr1, 2) To UBound(arr1, 2)
        If arr1(i, j) <> arr2(i, j) Then metka = True: Exit For
    Next j
    If metka = True Then MsgBox "Таблицы не совпадают", vbInformation: Exit Sub
Next i
MsgBox "Полностью идентичные таблицы", vbInformation
End Sub
Изменено: Nordheim - 11.08.2017 08:37:52
"Все гениальное просто, а все простое гениально!!!"
 
Забрал оба. Спасибо.
Страницы: 1
Читают тему
Наверх