![]() |
Ускорить работу макроса
Как ускорить работу скрипта?
Код:
Sub test() |
Вы проверяли, куда именно уходит время, на какие строки кода? Тупо расставить вывод времени и места в коде в текстовый файл и смотреть?
|
Iska, здравствуйте) рад видеть вас) в общем загрузка в массив из запроса примерно 25-30 сек (это те самые 500тыс строк) это знаю точно.
По количеству комбинаций знаю что 34,5 миллиарда. Хотя это не так важно. Завтра посмотрю на время. Придется воспользоваться коллекциями или словарём, если проблема в переборе 2х массивов? |
Цитата:
|
Iska, суть проста: берём 1 элемент из arr2( с листа экселя) и проверяем входит ли он в какой либо элемент массива arr1(взятого из sql таблицы). Если есть совпадение то "закидывает" в массив arr2 в соседний столбец массива.
Все остальное это доп надстройки-проверки. |
Там очень много InStr().
|
Iska, это единственное что я знаю на проверку есть ли подстрока в строке.
|
blackeangel,
Цитата:
СУБД - специализированная система и все такое. Важно только про всякие тримы и тому подобное при переносе не забыть... |
y--, вот, тоже вариант, а можно подробнее?
Ссылки, примеры? правда надо все делать средствами sql встроенными в vba, ТК акссес не у всех есть. Потом надо создать виртуальные таблицы, ТК запись на жёсткий ограничена. |
Iska, в общем померил время. Все очень и очень грустно. Во первых в память все очень закидывается, аж целую минуту. Выкидывается на лист ещё дольше - 7 минут, все остальное время это цикл.
Для того чтобы понять на сколько все реально плохо решил на 6 строках попробовать. Время выполнения 10 сек. Причем запрос выполнялся 7 сек, все остальное цикл, считывание с листа, запись на лист. Но запрос делается один раз, ему простительно это все. |
Вложений: 1
Если интересно, вот пример того что надо получить с исходными данными как раз те 6 номеров которые отработали за 10 сек.
|
Iska, есть вот такой код, по словам автора он, в какой то степени решает мою задачу. Но объяснять код отказался. Может вы что скажете дельного?
Код:
Option Explicit |
Вложений: 1
Вот он же, только в книге.
|
Цитата:
|
Цитата:
А свой код методом переборов массива могу расписать от и до, чтоб вам понятно было. |
Цитата:
Цитата:
|
Iska,
Цитата:
А теперь как работает мой код. Загружаем в 2 массива(arr1 из базы, arr2 c листа). Берём arr1 и проверяем каждый номер по тому по arr2. Причем проверяем входимость. Если есть в элементе arr1 "СБ" тогда проверяем, есть ли в текущем элементе arr2 символ "-", Если есть, то в переменную m записываем все что до черточки., проверяем есть ли текущее arr1 + "СБ", дальше сверяем 2 столбца в arr1, и если они равны, то тогда в arr2 пишем значение arr1, если нет, то пишем что "нет страниц" вот этот кусок кода Код:
For i = LBound(arr1) To UBound(arr1) Проверяем есть ли m в текущем arr1, если есть, то сравниваем значения 2х столбцов из arr1, если нет, то пишем в arr2 "нет страниц". Код:
If InStr(1, m, arr1(i, 0), vbTextCompare) > 0 Then Код:
If InStr(1, arr2(j, 1) + "СБ", arr1(i, 0), vbTextCompare) > 0 Then Код:
If arr2(j, 2) = Empty Then |
Цитата:
Всё, что Вы описываете, понятно из самого кода. Я не об этом. Я о том, что на всё описанное куча вопросов «Зачем?», «Зачем так?» и «Почему именно так, а не иначе?». Понимаете — о чём я? На всякий случай: в VB/VBA/VBScript есть одна такая хорошая функция Filter. Не знаю, поможет ли она Вам как-то, но посмотрите на примеры её использования. |
blackeangel,
Подробнее - либо через DTS либо напрямую через источник данных в ODBC - разово или на постоянной основе организовать перекачку данных в таблицу SQL. Именно в таблицу - так как дергать по одной записи тож на тож выйдет - то есть медленно. В процессе переброски не забыть об обрезании пробелов справа и слева для текстовых значений(alltrim()) и приведении всех остальных данных к правильному типу(с полями типа дата может изрядный геморой быть - в общей ситуации може даже проще затягивать как текст и считывать по формату). А дальше элементарный селект... Если на постоянной основе делать то надо вначале создать таблицу нужной структуры и единовременно залить все данные, на дальнейшее лучше реализовать что-то типа триггера на доливку/обновление/удаление разности - я-ля реплицировать. Примеров в сети по работе с DTS - море, да и маны достаточно подробные ;) |
y--, SELECT можно и для Рабочего листа Excel выполнять, не в том дело.
|
Цитата:
Быстродействие ПРАВИЛЬНОГО SQL-запроса должно быть зависимым от размера итоговой выборки и слабо зависимо от объема обрабатываемых данных... Iska, Цитата:
|
y--, у нас ситуация другая. Работать только на текущем пк. С сервера мы только можем запросить отфильтрованные данные. Дальше, если существует такое, создать виртуальные таблицы и работать в них как на сервере. Но как это кодить вообще не знаю. От слова совсем.
|
blackeangel,
На текущем компе: 1. Ставим SQL-сервер, создаем пустую базу, создаем две таблицы правильной структуры 2. Разово через DTS заливаем данные в таблицы из двух разных источников данных 3. Пишем нужный селект в виде сторки которая возвращает таблицу нужных данных 4. Настраиваем интерфейс запуска сторки - вот тут мороки больше всего и в зависимости от потребностей конечного пользователя надо будет подобрать нужный инструментарий(и как следствие определиться с видом СУБД). 5. Настраиваем источники ODBC к двум разным источникам данных. 6. В планировщике SQL пишем задания на периодическую синхронизацию с настроенными источниками |
Цитата:
|
y--, что-то мне подсказывает, что таким макаром «…и до аэродрома недалеко» ;).
|
Цитата:
|
blackeangel,
Цитата:
Возможная оптимизация времени исполнения в пределах поставленных условий может составлять десятки процентов - то есть(для меня) не имеет смысла и находится в пределах погрешности на загруженность самой системы... Всего лишь замена HDD на SSD(или на RAM-диск) для времени исполнения будет иметь больший эффект. Iska, Цитата:
|
blackeangel,
я к тому что даже без прав на установку софта - я пас... Если админ считает что не надо - значит он прав. Если он не прав - смотри предыдущее предложение. |
y--, самое странное то, что вы предлагаете что то установить, вместо того чтобы работать с имеющейся информацией. Если бы можно было бы ставить, я б поставил, и не упирался бы в оптимизацию кода. К примеру можно было б написать макрос для Акссеса.В акссесе это операция занимает пару минут.
Цитата:
Цитата:
А если серьёзно, если админ скажет считать столбиком, вы его послушаете? |
blackeangel,
Цитата:
|
y--, ну что же, это прискорбно, что вы так думаете, в лучшем случае - они принесут калькуляторы
|
blackeangel, в виде исключения на письмо ответил. Но общаться лучше на форуме.
|
Цитата:
К сожалению, здесь нерационально практически всё: и структура данных, и тягание данных туда-сюда, и сам алгоритм. Цитата:
|
Цитата:
Цитата:
Цитата:
Цитата:
Iska, хорошо, допустим мы выполним 2 запроса: один соберёт данные с сервера, второй с листа. Как выполнить 3й запрос на основе этих 2х запросов? |
Цитата:
|
Iska, значит аксесс использует другое что то?
Iska, задам тупой вопрос: а что можно с Recordset делать? |
Цитата:
Цитата:
|
Iska, насколько запрос медленнее чем перебор массива?)
Просто есть мысль о том, что данные с сервера получить, сохранить на жёсткий диск базой, и уже в цикле обращаться к ней. Ужасная идея? |
Цитата:
Цитата:
|
Iska, нее, они предлагают ставить сервер, стороннее ПО.
Цитата:
Так понимаю, вы в этом направлении практиковались мало? |
Цитата:
|
Iska, то есть для начала надо поштудировать вот это
https://www.google.ru/url?sa=t&sourc...eZZXo2lOk1wi5l Iska, но меня терзает то, что я нигде не видел чтоб можно было создать файл базы и заполнить её данными из recordset. |
Цитата:
Цитата:
|
Iska, так
Скрытый текст
Код:
Sub KD5_Zapros() Как сделать запросом перенести таблицу из базы сервера в свою базу? |
Цитата:
|
Iska, просто из экселя удалось одним select сразу в новый файл как таблицу нужный диапазон забросить. А вот из сервера что то никак не соображу. Пока весь код выполняется за 0.09сек, что неплохо.
Я склоняюсь в сторону select...into, но вот не могу понять как организовать from из того что у меня закоментировано в самом низу. |
Iska, нет, ваш пример не котируется, ТК не понятно как использовать instr между двумя таблицами, а не в пределах одной.
|
blackeangel, какой именно пример, и что значит «использовать instr между двумя таблицами»?
|
Iska, вот в этом посте http://forum.oszone.net/post-2782275-41.html
Цитата:
Код:
InStr(1,[list].[stolbec], [base].[stolbc5])>0 Как что то похожее в запрос прикрутить? |
Цитата:
Цитата:
Цитата:
Давайте так. Вы сделаете две небольших, коротких таблицы в Microsoft Access. Сделаете третью таблицу, которую хотели бы получить из этих двух в итоге. Словами опишете, по какому принципу (не в терминах запросов, а просто словами) эта таблица строилась бы, если бы Вы делали всё «ручками» — то есть: смотрим сюда, берём вот это, ищем его здесь, найденное помещаем в новую таблицу и т.д. |
Цитата:
Цитата:
Надо узнать, входит ли частично или полностью из таблицы base в таблице list. То есть, как и с перебором массива, надо брать элемент таблицы base и проверить входит ли он в какой либо элемент таблицы list. Если хоть раз совпало пишем в соседний столбец и переходим к следующей записи. Как то так. |
blackeangel, увы, мой Microsoft Access 2003 не понимает формат Вашего файла mdb.
|
Iska, у меня 2010 Access. А какой формат прочитается? accdb? Если да, то вот https://drive.google.com/file/d/190e...w?usp=drivesdk
|
Цитата:
Update: blackeangel, то, что у Вас именовано как mdb — судя по всему как раз-таки accdb: Код:
Standard ACE DB |
Iska, mdb был создан макросом, а потом открыт access и дополнен. Видимо это его и сделало нечитаемым в 2003.
|
Я обновил предыдущее сообщение.
Цитата:
|
Iska, сохранил в 2000 формате, пробуйте https://drive.google.com/file/d/1k6A...w?usp=drivesdk
|
blackeangel, у нас разные понятия об:
Цитата:
|
Iska, а зачем вам их просматривать? Вам не надо смотреть таблицу basa. Вам понадобятся только list и итого. ТК это все реальный рабочий пример. База, она и есть база, и что в ней, на сервере - не знаю. То есть она как есть. Но с уверенностью в 100% скажу что те что на list есть в basa.
|
Цитата:
Цитата:
Впрочем, я не настаиваю. Вам лень сделать «пару коротких таблиц» с примером, я же не вижу смысла копаться в сотнях тысяч записей. На том и сойдёмся. |
Iska, хорошо, завтра порежу до пары десятков строк.
|
Вложений: 1
Iska, итак, порезал всё, вот, смотрите.
|
нечто похожее проделывал тоже. только массивы в память не загонял. Более мелкий список на 69 тыс строк - загонял на соседний лист и сравнивал построчно/поколонно через ввод значения ячейки в промежуточную переменную с значением переменной второго 500 тыс списка. Всё это в рамках одной книги. и никаких запросов через интернет, ну если только в начале загрузить 69 тыс список в книгу с 500 тыс списком на соседний лист. а потом циклы сравнения.
|
azbest, ну я решил свою задачу, разбив её на 4 маленькие, плюс вынес все в запросы, в итоге 25-27сек стала. По моему это отличная замена 6-7 часам..
И это если учесть, что у меня и так много лишних действий есть, то можно ещё быстрее. |
Время: 10:18. |
Время: 10:18.
© OSzone.net 2001-