Переделал скаченную программу под свои нужды. Выполняет сравнение двух диапазонов и при совпадении подставляет данные из одного в другой. Если оба сравниваемых диапазона находятся на одном листе, то все работает правильно. Как только разношу на разные листы, то выдает ошибку в строке [vba]
Код
Set obsii = Worksheets("Общий").Range(Cells(1, 1), Cells(a, 1))
[/vba] Если в коде везде указать имя одного листа то работает. Помогите пожалуйста начинающему разобраться. [vba]
Код
Sub Start() 'Общий—Сортировка'
Dim obsii As Range, xx As Range, cc As Range, sort As Range
x2 = InputBox("В какой столбик писать результат?") d1 = Time
aa = Worksheets("Сортировка").Range("b1").End(xlDown).Row MsgBox aa Set sort = Worksheets("Сортировка").Range(Cells(1, 2), Cells(aa, 2))
a = Worksheets("Общий").Range("a1").End(xlDown).Row MsgBox a Set obsii = Worksheets("Общий").Range(Cells(1, 1), Cells(a, 1)) For Each xx In sort If Worksheets("Сортировка").Cells(xx.Row, xx.Column + 1) > 0 Then Set cc = obsii.Find(What:=xx.Value, LookIn:=xlValues) If Not (cc Is Nothing) Then 'Если что-то нашли, то копируем Worksheets("Общий").Cells(cc.Row, CDbl(x2)).Value = Worksheets("Сортировка").Cells(xx.Row, xx.Column + 1).Value Else Worksheets("Сортировка").Cells(xx.Row, xx.Column).Interior.Color = VBA.RGB(255, 0, 0) End If End If Next xx
Beep d2 = Time Время = MsgBox((DateDiff("n", d1, d2) \ 60 & " час " & DateDiff("n", d1, d2) Mod 60 & " мин " & DateDiff("s", d1, d2) Mod 60 & " сек"), 0, "Затрачено:") End Sub
[/vba]
Переделал скаченную программу под свои нужды. Выполняет сравнение двух диапазонов и при совпадении подставляет данные из одного в другой. Если оба сравниваемых диапазона находятся на одном листе, то все работает правильно. Как только разношу на разные листы, то выдает ошибку в строке [vba]
Код
Set obsii = Worksheets("Общий").Range(Cells(1, 1), Cells(a, 1))
[/vba] Если в коде везде указать имя одного листа то работает. Помогите пожалуйста начинающему разобраться. [vba]
Код
Sub Start() 'Общий—Сортировка'
Dim obsii As Range, xx As Range, cc As Range, sort As Range
x2 = InputBox("В какой столбик писать результат?") d1 = Time
aa = Worksheets("Сортировка").Range("b1").End(xlDown).Row MsgBox aa Set sort = Worksheets("Сортировка").Range(Cells(1, 2), Cells(aa, 2))
a = Worksheets("Общий").Range("a1").End(xlDown).Row MsgBox a Set obsii = Worksheets("Общий").Range(Cells(1, 1), Cells(a, 1)) For Each xx In sort If Worksheets("Сортировка").Cells(xx.Row, xx.Column + 1) > 0 Then Set cc = obsii.Find(What:=xx.Value, LookIn:=xlValues) If Not (cc Is Nothing) Then 'Если что-то нашли, то копируем Worksheets("Общий").Cells(cc.Row, CDbl(x2)).Value = Worksheets("Сортировка").Cells(xx.Row, xx.Column + 1).Value Else Worksheets("Сортировка").Cells(xx.Row, xx.Column).Interior.Color = VBA.RGB(255, 0, 0) End If End If Next xx
Beep d2 = Time Время = MsgBox((DateDiff("n", d1, d2) \ 60 & " час " & DateDiff("n", d1, d2) Mod 60 & " мин " & DateDiff("s", d1, d2) Mod 60 & " сек"), 0, "Затрачено:") End Sub
227, Вот первоначальный код, который я переделывал:
[vba]
Код
Sub Start() 'Пробная процедура' Dim a As Range Set a = Range("A1:A7") 'Обрабатываемый диапазон' Call SearchID(a) End Sub
Sub SearchID(diap As Range) Dim BaseDiap As Range, x As Range, c As Range
Set BaseDiap = Range("C1:C4") 'Диапазон с исходными данными' For Each x In diap Set c = BaseDiap.Find(What:=x.Value, LookIn:=xlValues) If Not (c Is Nothing) Then 'Если что-то нашли, то копируем значение из соседнего столбца' Cells(x.Row, x.Column + 1).Value = Cells(c.Row, c.Column + 1).Value End If Next x End Sub
[/vba]
227, Вот первоначальный код, который я переделывал:
[vba]
Код
Sub Start() 'Пробная процедура' Dim a As Range Set a = Range("A1:A7") 'Обрабатываемый диапазон' Call SearchID(a) End Sub
Sub SearchID(diap As Range) Dim BaseDiap As Range, x As Range, c As Range
Set BaseDiap = Range("C1:C4") 'Диапазон с исходными данными' For Each x In diap Set c = BaseDiap.Find(What:=x.Value, LookIn:=xlValues) If Not (c Is Nothing) Then 'Если что-то нашли, то копируем значение из соседнего столбца' Cells(x.Row, x.Column + 1).Value = Cells(c.Row, c.Column + 1).Value End If Next x End Sub
227, переделанный макрос берет заначения ячеек из диапазона столбика B на одном листе, и сравнивает их с диапазоном столбика A на другом листе. При совпадениях копирует ячейку правее B у казанный столбик.
227, переделанный макрос берет заначения ячеек из диапазона столбика B на одном листе, и сравнивает их с диапазоном столбика A на другом листе. При совпадениях копирует ячейку правее B у казанный столбик.227
[/vba] вот эти Cells(1, 1), Cells(a, 1) т.к. не указан лист, будут браться с активного листа. Перед каждым cells нужно указать лист! В оригинале т.к. всё работало на одном активном листе это роли не играло. А вообще если нужно сравнивать большие диапазоны - делайте на массивах и словаре. Если конечно не Мак - там нет словарей...
[/vba] вот эти Cells(1, 1), Cells(a, 1) т.к. не указан лист, будут браться с активного листа. Перед каждым cells нужно указать лист! В оригинале т.к. всё работало на одном активном листе это роли не играло. А вообще если нужно сравнивать большие диапазоны - делайте на массивах и словаре. Если конечно не Мак - там нет словарей...Hugo
Hugo, помогло, спасибо огромное! Макрос теперь работает, но ужасно медленно((( У меня сейчас диапазоны на обоих листах примерно 15К на каждом. На одном, если исключить нули, то примерно половина. И одно сравнение занимает много времени(((
Можно подробнее про:
Цитата
...если нужно сравнивать большие диапазоны - делайте на массивах и словаре. Если конечно не Мак - там нет словарей...
У меня мак, но есть доступ и к виндовым компам. Скорость очень важна! ..я сделал уже несколько вариантов этого алгоритма, этот уже третий. Первый был на простом копировании ячеек, второй на массиве, и этот на диапазонах уже третий. Но скорость на всех примерно одинаковая ± 5-7 мин. На медленном компе ~ 35 мин, на быстром 19 мин. Очень хотелось бы ускорить этот процесс! Как не странно, но при простом копировании ячеек получается быстрее на несколько мин(
Hugo, помогло, спасибо огромное! Макрос теперь работает, но ужасно медленно((( У меня сейчас диапазоны на обоих листах примерно 15К на каждом. На одном, если исключить нули, то примерно половина. И одно сравнение занимает много времени(((
Можно подробнее про:
Цитата
...если нужно сравнивать большие диапазоны - делайте на массивах и словаре. Если конечно не Мак - там нет словарей...
У меня мак, но есть доступ и к виндовым компам. Скорость очень важна! ..я сделал уже несколько вариантов этого алгоритма, этот уже третий. Первый был на простом копировании ячеек, второй на массиве, и этот на диапазонах уже третий. Но скорость на всех примерно одинаковая ± 5-7 мин. На медленном компе ~ 35 мин, на быстром 19 мин. Очень хотелось бы ускорить этот процесс! Как не странно, но при простом копировании ячеек получается быстрее на несколько мин(227
AndreTM, я пробовал с массивом, но так получилось даже медленнее на несколько минут чем с ячейками(( Вот вариант с массивом:
[vba]
Код
Sub СортировкаZ3массив()
Dim K1(999999) As String 'Массив Dim K2(999999) As String 'Массив Dim K3(999999) As Integer 'Массив Dim nss As Long Dim retval As Integer Dim d1 As Date, d2 As Date, Время As String
xx = InputBox("В какой столбик писать результат?") d1 = Time
nss = 2 Do While Worksheets("Сортировка").Range("B" & nss).Value <> "" 'определить количество строк в Сортировка nss = nss + 1 Loop nss = nss - 1 'MsgBox nss
nso = 2 Do While Worksheets("Общий").Range("A" & nso).Value <> "" 'определить количество строк в Общий nso = nso + 1 Loop nso = nso - 1 'MsgBox nso
For q2 = 2 To nss K2(q2) = Worksheets("Сортировка").Cells(q2, 2) 'запомнить артикул в Сортировка Next For q3 = 2 To nss 'MsgBox q3 K3(q3) = Worksheets("Сортировка").Cells(q3, 3) 'запомнить количество в Сортировка 'MsgBox K3(q3) Next For q1 = 2 To nso K1(q1) = Worksheets("Общий").Cells(q1, 1) 'запомнить артикул в Общем Next
For i = 2 To nss If K3(i) > 0 Then 'если количество больше 0
If Worksheets("Общий").Cells.Find(What:=K2(i), LookAt:=xlWhole) Is Nothing Then 'если не нашлось Worksheets("Сортировка").Cells(i, 2).Interior.Color = VBA.RGB(255, 0, 0) Else R = Worksheets("Общий").Cells.Find(What:=K2(i), LookAt:=xlWhole).Row Worksheets("Общий").Cells(R, CDbl(xx)).Value = K3(i) End If End If Next
Beep d2 = Time Время = MsgBox((DateDiff("n", d1, d2) \ 60 & " часов " & DateDiff("n", d1, d2) Mod 60 & " минут " & DateDiff("s", d1, d2) Mod 60 & " секунд"), 0, "Затрачено:") End Sub
[/vba]
Летучие функции это формулы? Ничего такого нет, я все пробую на новой чистой книге. Скрины исходных данных и таблица куда это все пишется. Один столбик одна сортировка:
Там идет сравнение уникальных ячеек, при точном совпадении переносятся ячейки с целыми числами. Я далеко не претендую на оптимальность кода, я всего неделю программирую. Если вы можете предложить иной алгоритм сравнения, который повысит скорость, то буду очень благодарен за любой совет как увеличить скорость.
AndreTM, я пробовал с массивом, но так получилось даже медленнее на несколько минут чем с ячейками(( Вот вариант с массивом:
[vba]
Код
Sub СортировкаZ3массив()
Dim K1(999999) As String 'Массив Dim K2(999999) As String 'Массив Dim K3(999999) As Integer 'Массив Dim nss As Long Dim retval As Integer Dim d1 As Date, d2 As Date, Время As String
xx = InputBox("В какой столбик писать результат?") d1 = Time
nss = 2 Do While Worksheets("Сортировка").Range("B" & nss).Value <> "" 'определить количество строк в Сортировка nss = nss + 1 Loop nss = nss - 1 'MsgBox nss
nso = 2 Do While Worksheets("Общий").Range("A" & nso).Value <> "" 'определить количество строк в Общий nso = nso + 1 Loop nso = nso - 1 'MsgBox nso
For q2 = 2 To nss K2(q2) = Worksheets("Сортировка").Cells(q2, 2) 'запомнить артикул в Сортировка Next For q3 = 2 To nss 'MsgBox q3 K3(q3) = Worksheets("Сортировка").Cells(q3, 3) 'запомнить количество в Сортировка 'MsgBox K3(q3) Next For q1 = 2 To nso K1(q1) = Worksheets("Общий").Cells(q1, 1) 'запомнить артикул в Общем Next
For i = 2 To nss If K3(i) > 0 Then 'если количество больше 0
If Worksheets("Общий").Cells.Find(What:=K2(i), LookAt:=xlWhole) Is Nothing Then 'если не нашлось Worksheets("Сортировка").Cells(i, 2).Interior.Color = VBA.RGB(255, 0, 0) Else R = Worksheets("Общий").Cells.Find(What:=K2(i), LookAt:=xlWhole).Row Worksheets("Общий").Cells(R, CDbl(xx)).Value = K3(i) End If End If Next
Beep d2 = Time Время = MsgBox((DateDiff("n", d1, d2) \ 60 & " часов " & DateDiff("n", d1, d2) Mod 60 & " минут " & DateDiff("s", d1, d2) Mod 60 & " секунд"), 0, "Затрачено:") End Sub
[/vba]
Летучие функции это формулы? Ничего такого нет, я все пробую на новой чистой книге. Скрины исходных данных и таблица куда это все пишется. Один столбик одна сортировка:
Там идет сравнение уникальных ячеек, при точном совпадении переносятся ячейки с целыми числами. Я далеко не претендую на оптимальность кода, я всего неделю программирую. Если вы можете предложить иной алгоритм сравнения, который повысит скорость, то буду очень благодарен за любой совет как увеличить скорость.227
Вот просто с переносом ячеек пробовал, тут вообще не совсем правильно, тут поиск идет по всему листу а не по диапазону, что должно быть дольше, но как ни странно, этот вариант работает быстрее остальных.
[vba]
Код
Sub СортировкаZ2()
Dim nss As Long xx = InputBox("В какой столбик писать результат?") y = InputBox("С какой строки начинать?")
MsgBox Time nss = 2 Do While Worksheets("Сортировка").Range("B" & nss).Value <> "" nss = nss + 1 Loop MsgBox Time For i = 2 To nss - 1 If Worksheets("Сортировка").Range("C" & i) > 0 Then zz = Worksheets("Сортировка").Range("B" & i) If Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole) Is Nothing Then Worksheets("Сортировка").Cells(i, 2).Interior.Color = VBA.RGB(255, 0, 0) Else R = Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole).Row zz = Worksheets("Сортировка").Range("C" & i) Worksheets("Общий").Cells(R, CDbl(xx)).Value = zz End If End If Next Beep MsgBox Time End Sub
[/vba]
Вот просто с переносом ячеек пробовал, тут вообще не совсем правильно, тут поиск идет по всему листу а не по диапазону, что должно быть дольше, но как ни странно, этот вариант работает быстрее остальных.
[vba]
Код
Sub СортировкаZ2()
Dim nss As Long xx = InputBox("В какой столбик писать результат?") y = InputBox("С какой строки начинать?")
MsgBox Time nss = 2 Do While Worksheets("Сортировка").Range("B" & nss).Value <> "" nss = nss + 1 Loop MsgBox Time For i = 2 To nss - 1 If Worksheets("Сортировка").Range("C" & i) > 0 Then zz = Worksheets("Сортировка").Range("B" & i) If Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole) Is Nothing Then Worksheets("Сортировка").Cells(i, 2).Interior.Color = VBA.RGB(255, 0, 0) Else R = Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole).Row zz = Worksheets("Сортировка").Range("C" & i) Worksheets("Общий").Cells(R, CDbl(xx)).Value = zz End If End If Next Beep MsgBox Time End Sub
В принципе да, здесь должно хватать и обычного ВПР() (или его заменителя). Особенно, если таблицу на листе "Сортировка" есть возможность сразу предварительно отсортировать по первому столбцу-коду. Или нужно это проделывать именно и только кодом, на VBA? Тогда наибольшее быстродействие на больших объемах показывать будет запрос к данным. Например, с использованием MSQuery. Проще было бы, конечно, используя ADO или DAO,но я не в курсе, поддерживаются ли эти провайдеры на маках. Да и даже свой алгоритм можно сделать, достаточно простой, если использовать заранее отсортированные списки. Изабыть на время об использовании .Find
Кроме того, я вам могу намекнуть ещё на то, что "пробовали вы с массивами" вообще как-то этак... Вам посоветовали "все данные занести в массивы и работать уже только с ними (т.е. сравнение вести уже в них), а вы что сделали? Ну и открою вам великую тайну - в Excel данные любого диапазона ячеек - и так массив, поэтому чтение с листа (или запись на него) не требует использования циклов: [vba]
Код
Dim arr() arr = Range("A1:B10").Value ' чтение данных с листа в массив Cells(1, 11).Resize(UBound(arr, 1), UBound(arr, 2)) = arr ' запись на лист из массива
[/vba] По поводу второго вашего куска кода тоже могу дать намёк: [vba]
Код
If Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole) Is Nothing Then ' ... Else R = Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole).Row ' ...
[/vba]не кажется ли, что вы два раза ищете одно и тоже?
Не говоря уже о том, что вам был дан нулевой намёк ранее - отключите пересчет и обновление листа на время исполнения кода.
В принципе да, здесь должно хватать и обычного ВПР() (или его заменителя). Особенно, если таблицу на листе "Сортировка" есть возможность сразу предварительно отсортировать по первому столбцу-коду. Или нужно это проделывать именно и только кодом, на VBA? Тогда наибольшее быстродействие на больших объемах показывать будет запрос к данным. Например, с использованием MSQuery. Проще было бы, конечно, используя ADO или DAO,но я не в курсе, поддерживаются ли эти провайдеры на маках. Да и даже свой алгоритм можно сделать, достаточно простой, если использовать заранее отсортированные списки. Изабыть на время об использовании .Find
Кроме того, я вам могу намекнуть ещё на то, что "пробовали вы с массивами" вообще как-то этак... Вам посоветовали "все данные занести в массивы и работать уже только с ними (т.е. сравнение вести уже в них), а вы что сделали? Ну и открою вам великую тайну - в Excel данные любого диапазона ячеек - и так массив, поэтому чтение с листа (или запись на него) не требует использования циклов: [vba]
Код
Dim arr() arr = Range("A1:B10").Value ' чтение данных с листа в массив Cells(1, 11).Resize(UBound(arr, 1), UBound(arr, 2)) = arr ' запись на лист из массива
[/vba] По поводу второго вашего куска кода тоже могу дать намёк: [vba]
Код
If Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole) Is Nothing Then ' ... Else R = Worksheets("Общий").Cells.Find(What:=zz, LookAt:=xlWhole).Row ' ...
[/vba]не кажется ли, что вы два раза ищете одно и тоже?
Не говоря уже о том, что вам был дан нулевой намёк ранее - отключите пересчет и обновление листа на время исполнения кода.
Hugo, означает и это, что на винде этот макрос будет работать намного быстрее? С формулой с наскока не получилось разобраться, выдается странный результат #ИМЯ?, надо будет почитать как они работают.
AndreTM, сейчас так и делаем, сортировка а-я, выделенине цветом дубликатов, сортировка по цвету, перестановка и тд. Довольно много рутинных действий, которые хотелось бы автоматизировать. Я не совсем корректно сделал тестовый файл, просто сделал схематически. Вообще на эталонном листе Общий имеется много столбиков с разной инфой не по алфавиту, и порядок и количество артикулов на листе Сортировка не совпадает с Общий, по этому и поиск. От этой сортировки требуется только добавить дополнительный столбик на первый лист.
MSQuery для меня пока это сложновато(
Hugo, означает и это, что на винде этот макрос будет работать намного быстрее? С формулой с наскока не получилось разобраться, выдается странный результат #ИМЯ?, надо будет почитать как они работают.
AndreTM, сейчас так и делаем, сортировка а-я, выделенине цветом дубликатов, сортировка по цвету, перестановка и тд. Довольно много рутинных действий, которые хотелось бы автоматизировать. Я не совсем корректно сделал тестовый файл, просто сделал схематически. Вообще на эталонном листе Общий имеется много столбиков с разной инфой не по алфавиту, и порядок и количество артикулов на листе Сортировка не совпадает с Общий, по этому и поиск. От этой сортировки требуется только добавить дополнительный столбик на первый лист.
227, привет просто для интереса, вот так будет работать на Мак? (сомневаюсь про Timer - можно закомментировать если что) [vba]
Код
Sub СортировкаZ3массив22() Dim x, i&, r As Range Dim tm#: tm = Timer With Sheets("Общий") x = .Range("A1", .Cells(Rows.Count, 1).End(xlUp)).Value End With With Sheets("Сортировка").Columns(1) For i = 1 To UBound(x) Set r = .Find(x(i, 1), LookAt:=xlWhole) If r Is Nothing Then x(i, 1) = "" Else x(i, 1) = r(1, 2) Next i End With Sheets("Общий").Range("B1").Resize(i - 1).Value = x MsgBox Timer - tm End Sub
[/vba]
исправил r(1)(1, 2) на r(1, 2), опечатка
227, привет просто для интереса, вот так будет работать на Мак? (сомневаюсь про Timer - можно закомментировать если что) [vba]
Код
Sub СортировкаZ3массив22() Dim x, i&, r As Range Dim tm#: tm = Timer With Sheets("Общий") x = .Range("A1", .Cells(Rows.Count, 1).End(xlUp)).Value End With With Sheets("Сортировка").Columns(1) For i = 1 To UBound(x) Set r = .Find(x(i, 1), LookAt:=xlWhole) If r Is Nothing Then x(i, 1) = "" Else x(i, 1) = r(1, 2) Next i End With Sheets("Общий").Range("B1").Resize(i - 1).Value = x MsgBox Timer - tm End Sub
nilem, это высший пилотаж! Супер! Снимаю шляпу! Прирост скорости почти в 20 раз!
Это то что надо! Хотел только немного подправить логику, но не получается разобраться(( У вас как-то хитро сделано. В этом коде значения из Общий сравниваются с Сортировка, а нужно наоборот, так как в Сортировка значений может быть больше, и нужно как-то метить то, что в Общий не нашлось, в своей версии я эти ячейки заливал красным, а после завершения делал сортировку по цвету. В вашем варианте менял местами названия листов, в случае неудачного поиска прописывал ZZZ и менял местами переменные, но получается ерунда какая-то(((
[vba]
Код
If r Is Nothing Then x(i, 1) = "zzz" Else r(1)(1, 2) = x(i, 1)
[/vba]
Подскажите пожалуйста как поправить логику?
nilem, это высший пилотаж! Супер! Снимаю шляпу! Прирост скорости почти в 20 раз!
Это то что надо! Хотел только немного подправить логику, но не получается разобраться(( У вас как-то хитро сделано. В этом коде значения из Общий сравниваются с Сортировка, а нужно наоборот, так как в Сортировка значений может быть больше, и нужно как-то метить то, что в Общий не нашлось, в своей версии я эти ячейки заливал красным, а после завершения делал сортировку по цвету. В вашем варианте менял местами названия листов, в случае неудачного поиска прописывал ZZZ и менял местами переменные, но получается ерунда какая-то(((
[vba]
Код
If r Is Nothing Then x(i, 1) = "zzz" Else r(1)(1, 2) = x(i, 1)
давайте еще раз... На листе Общий нужно для каждого кода прописать значения, взятые из листа Сортировка. А на листе Сортировка как-то отметить те коды, которые отсутствуют на листе Общий. Правильно?
Отсортировать столбцы с кодами на обоих листах допускается?
давайте еще раз... На листе Общий нужно для каждого кода прописать значения, взятые из листа Сортировка. А на листе Сортировка как-то отметить те коды, которые отсутствуют на листе Общий. Правильно?
Отсортировать столбцы с кодами на обоих листах допускается?nilem
nilem, все правильно! Только я изначально исходил из листа Сортировка, если значение > 0, то поиск по Общий (ну чтобы ускорить процесс, просто там много нулей), если точное совпадение, то копия из Сортировка в Общий. Сортировать допускается, только в Общий очень длинные строки, он как накопитель инфы.
nilem, все правильно! Только я изначально исходил из листа Сортировка, если значение > 0, то поиск по Общий (ну чтобы ускорить процесс, просто там много нулей), если точное совпадение, то копия из Сортировка в Общий. Сортировать допускается, только в Общий очень длинные строки, он как накопитель инфы.227
Сообщение отредактировал 227 - Понедельник, 04.05.2015, 22:02
Sub ertert() Dim tm#: tm = Timer Dim x, y, rez(), i&, j&, bu As Boolean Dim ubx&, lbx&
With Sheets("Сортировка") 'где ищем. Данные д.б. отсортированы по Коду 'берем 2 столбца x = .Range("A2:B" & .Cells(Rows.Count, 1).End(xlUp).Row).Value End With
With Sheets("Общий") 'что ищем, сортировать необязательно y = .Range("A2", .Cells(Rows.Count, 1).End(xlUp)).Value End With ReDim rez(1 To UBound(y), 1 To 1)
For i = 1 To UBound(y) lbx = 1: ubx = UBound(x) Do bu = 0: j = (lbx + ubx) \ 2 Select Case y(i, 1) Case Is > x(j, 1): lbx = j + 1 Case Is < x(j, 1): ubx = j - 1 Case Is = x(j, 1): bu = 1: Exit Do End Select Loop Until ubx < lbx 'x(j, 2) - возвращаем значение из 2-го столбца листа Сортировка If bu Then rez(i, 1) = x(j, 2) Next i
Sheets("Общий").Range("B2").Resize(i - 1).Value = rez() MsgBox Timer - tm End Sub
[/vba]
попробуйте вот так: [vba]
Код
Sub ertert() Dim tm#: tm = Timer Dim x, y, rez(), i&, j&, bu As Boolean Dim ubx&, lbx&
With Sheets("Сортировка") 'где ищем. Данные д.б. отсортированы по Коду 'берем 2 столбца x = .Range("A2:B" & .Cells(Rows.Count, 1).End(xlUp).Row).Value End With
With Sheets("Общий") 'что ищем, сортировать необязательно y = .Range("A2", .Cells(Rows.Count, 1).End(xlUp)).Value End With ReDim rez(1 To UBound(y), 1 To 1)
For i = 1 To UBound(y) lbx = 1: ubx = UBound(x) Do bu = 0: j = (lbx + ubx) \ 2 Select Case y(i, 1) Case Is > x(j, 1): lbx = j + 1 Case Is < x(j, 1): ubx = j - 1 Case Is = x(j, 1): bu = 1: Exit Do End Select Loop Until ubx < lbx 'x(j, 2) - возвращаем значение из 2-го столбца листа Сортировка If bu Then rez(i, 1) = x(j, 2) Next i
Sheets("Общий").Range("B2").Resize(i - 1).Value = rez() MsgBox Timer - tm End Sub