Отчет из Access в Excel, CopyFromRecordset & объед. ячей
Модератор: Naeel Maqsudov
Привет мастерам!
Нужен совет:
Делаю формирование отчетов в Экселе, т.к. это требование заказчика
Хотел бы ускорить скорость
Но не могу использовать CopyFromRecordset, т.к. использую объединенные ячейки в шаблоне
Хитрый Эксель не хочет понимать, что мне не надо подряд во все ячейки данные включать, а только в первые ячейки объединения
Пока выкрутился заполнением по каждому столбцу отдельно
Может быть кто-нибудь посоветует какой-нибудь более эффективный способ?
Как вариант можно использовать запрос с пустыми строками в перемешку с данными, но это совсем не красиво...
Проблема эффективности стоит из-за того, что заказчик предпологает использовать старый парк машин в филиалах
Нужен совет:
Делаю формирование отчетов в Экселе, т.к. это требование заказчика
Хотел бы ускорить скорость
Но не могу использовать CopyFromRecordset, т.к. использую объединенные ячейки в шаблоне
Хитрый Эксель не хочет понимать, что мне не надо подряд во все ячейки данные включать, а только в первые ячейки объединения
Пока выкрутился заполнением по каждому столбцу отдельно
Может быть кто-нибудь посоветует какой-нибудь более эффективный способ?
Как вариант можно использовать запрос с пустыми строками в перемешку с данными, но это совсем не красиво...
Проблема эффективности стоит из-за того, что заказчик предпологает использовать старый парк машин в филиалах
- Naeel Maqsudov
- Сообщения: 2570
- Зарегистрирован: 20 фев 2004, 19:17
- Откуда: Moscow, Russia
- Контактная информация:
Я как-то раз делал один проект на Delphi и тоже столкнулся с проблемой быстродействия (точнее с медленнодействия) при формировании отчета. Существенно помогло присвоение массива значений.
Формируем массив значений и формул в типе Variant, далее присваиваем весь массив одним махом.
RepSheet.Range['A'+IntToStr(FirslLine)+':E'+IntToStr(FirslLine+LineNum)]:=TmpArray;
При раскрашивании полученного отчета тоже быстрее сформировать объединенный адрес (много адресов через пробел) и изменять цвет ячеек одной командой, вместо цикла.
Это, вообще говоря, общая рекомендации по увеличению быстродействия VBA:
1) Не двигать курсор (ну, разьве что, в последней строчке макроса, когда он сделал всю работу и перемещает фокус в удобное пользователю место);
2) Пусть каждая операция с ячейками будет более объемной, но самих операций пусть будет меньше;
3) Быстрее макрос управляет документом, окна которого скрыты. Например, из внешнего приложения лучше запустить Excel с .Visible=false, а когда работа будет закончета сделать .Visible=true.
Формируем массив значений и формул в типе Variant, далее присваиваем весь массив одним махом.
RepSheet.Range['A'+IntToStr(FirslLine)+':E'+IntToStr(FirslLine+LineNum)]:=TmpArray;
При раскрашивании полученного отчета тоже быстрее сформировать объединенный адрес (много адресов через пробел) и изменять цвет ячеек одной командой, вместо цикла.
Это, вообще говоря, общая рекомендации по увеличению быстродействия VBA:
1) Не двигать курсор (ну, разьве что, в последней строчке макроса, когда он сделал всю работу и перемещает фокус в удобное пользователю место);
2) Пусть каждая операция с ячейками будет более объемной, но самих операций пусть будет меньше;
3) Быстрее макрос управляет документом, окна которого скрыты. Например, из внешнего приложения лучше запустить Excel с .Visible=false, а когда работа будет закончета сделать .Visible=true.
Могу добавить еще одну методу по ускорению:
Я сравнил скорость по выполнению всяких издевательств над листами:
а) Используя Эксель как сервер автоматизации на 100% (т.е. из внешнего оприложения управлял формированием отчета)
б) Создав шаблон листа с двумя процедурами - первая формирует все на основе получаемого в параметре рекордсета, а вторая удаляет лист шаблона
Вариант А оказался медленней в 7-15 раз
Так что сейчас вся логика по построению отчета у меня лежит в шаблоне, я создаю экземпляр Экселя, на основе шаблона создаю экземпляр книги, а дальше вызываю две волшебные процедуры
Почему две процедуры, а не одна? Просто у меня готовый класс отчета, и я пользуюсь ими в конструкторе и деструкторе
И еще хотел добавить, что потратив кучу времени на поиск информации, я решил съэкономить его другим и написать статью о создании отчетов в Экселе, ссылку на эл. вариант обещаю выложить в этой ветке
Я сравнил скорость по выполнению всяких издевательств над листами:
а) Используя Эксель как сервер автоматизации на 100% (т.е. из внешнего оприложения управлял формированием отчета)
б) Создав шаблон листа с двумя процедурами - первая формирует все на основе получаемого в параметре рекордсета, а вторая удаляет лист шаблона
Вариант А оказался медленней в 7-15 раз

Так что сейчас вся логика по построению отчета у меня лежит в шаблоне, я создаю экземпляр Экселя, на основе шаблона создаю экземпляр книги, а дальше вызываю две волшебные процедуры
Почему две процедуры, а не одна? Просто у меня готовый класс отчета, и я пользуюсь ими в конструкторе и деструкторе

И еще хотел добавить, что потратив кучу времени на поиск информации, я решил съэкономить его другим и написать статью о создании отчетов в Экселе, ссылку на эл. вариант обещаю выложить в этой ветке

- Naeel Maqsudov
- Сообщения: 2570
- Зарегистрирован: 20 фев 2004, 19:17
- Откуда: Moscow, Russia
- Контактная информация:
О, а если бы Вам воспользоваться-таки методом CopyFromRecordset но вставить данные в другое место, где нет объединенных ячеек. А потом уж навести марафет, или данные передвинуть?
А я им и пользуюсь, только вставляю отдельные столбцы
Пробовал еще вариант, когда через CopyFromRecordset вставляю данные в необъединенные ячейки, связанные с таблицей через ссылки, а потом копирую в таблицу сами значения (подсказали попробовать такой вариант), но оказалось чуть медленней описаного выше
И еще шустрее оказался способ, когда используются пустые значения, специально выводимые запросом, но мне он просто не нравится, "не аккуратненько" как-то
Пробовал еще вариант, когда через CopyFromRecordset вставляю данные в необъединенные ячейки, связанные с таблицей через ссылки, а потом копирую в таблицу сами значения (подсказали попробовать такой вариант), но оказалось чуть медленней описаного выше
И еще шустрее оказался способ, когда используются пустые значения, специально выводимые запросом, но мне он просто не нравится, "не аккуратненько" как-то

- Naeel Maqsudov
- Сообщения: 2570
- Зарегистрирован: 20 фев 2004, 19:17
- Откуда: Moscow, Russia
- Контактная информация:
Не понял про пустые значения...И еще шустрее оказался способ, когда используются пустые значения, специально выводимые запросом
Это когда строка SQL формируется програмно
Например так:
"SELECT ID,"" as i1,"" as i2,NAME FROM Names;"
т.е. i1 и i2 - преднамеренно вставляемые пустые значения
Потом это все очень мило вставляется через CopyFromRecordset, когда используешь объединение ячеек
Например так:
"SELECT ID,"" as i1,"" as i2,NAME FROM Names;"
т.е. i1 и i2 - преднамеренно вставляемые пустые значения
Потом это все очень мило вставляется через CopyFromRecordset, когда используешь объединение ячеек
- Naeel Maqsudov
- Сообщения: 2570
- Зарегистрирован: 20 фев 2004, 19:17
- Откуда: Moscow, Russia
- Контактная информация:
Не вижу здесь ничего неаккуратного.
Я как-то раз формировал отчеты хранимыми процедурами, так у меня Select к хранимой процедуре возвращал местами и пустые строки и пустые столюцы. Например, одним Select-ом я получал карту движения товара, в которой под шапкой формировалось сразу две таблицы разной высоты: в одной приходные операции, в другой - расходные. А в конце еще и общий Footer с подписями. Все выравнивалось пустыми ячейками.
Эти отчеты можно было и на экранной форме в гриде отобразить, и в MSOffice красиво экспортировать, ну и в генератор отчетов послать.
Так что не стесняйтесь. Это вполне экологичный прием. Цель тут вполне оправдывает средства.
Я как-то раз формировал отчеты хранимыми процедурами, так у меня Select к хранимой процедуре возвращал местами и пустые строки и пустые столюцы. Например, одним Select-ом я получал карту движения товара, в которой под шапкой формировалось сразу две таблицы разной высоты: в одной приходные операции, в другой - расходные. А в конце еще и общий Footer с подписями. Все выравнивалось пустыми ячейками.
Эти отчеты можно было и на экранной форме в гриде отобразить, и в MSOffice красиво экспортировать, ну и в генератор отчетов послать.
Так что не стесняйтесь. Это вполне экологичный прием. Цель тут вполне оправдывает средства.