Итак, предыстория такова: заказчик очень любит Excel и сильно просит, чтобы данные из БД можно было выводить в виде огромной портянки в 3000 строк и около сотни столбцов. Пробовал использовать PHPExcel. Он довольно удобен, но на больших файлах начинает тупить и не укладывается в типичный для многих хостингов временной интервал в 30-60 секунд. Выводить успевает строк 300, причем, основное время тратится не на выборку и укладку данных в ячейки, а именно на сборку окончательного файла для загрузки, то есть резервов для оптимизации моего кода не осталось, загвоздка - в ядре PHPExcel. В общем, решено было делать это через SOAP чтобы:
а) часть работы перенести на клиента (украшательства и излишества всякие нехорошие)
б) за счет использования небольших запросов обойти ограничение на время исполнения скрипта.
Идея:
Делать выборку в 2 шага. На первом шаге загружаем в шаблон список ключевых атрибутов большой выборки с учетом необходимых фильтраций и сортировок. На втором этапе для каждой строки Excel по ключевому атрибуту вытягивать с сервера содержимое одной строки. Я тащу по 2 значения на каждую ячейку - текст ячейки и её цвет.
Про серверную логику рассказал вчера. На стороне Excel необходимо провести следующие предварительные шаги:
1 - скачать и установить необходимые дополнительные компоненты
- SOAPToolkit 3.0 (
http://www.microsoft.com/downloads/en/d ... laylang=en)
- MSXML 4.0, если ответ от сервера идет в виде XML и надо его разобрать (
http://www.microsoft.com/downloads/en/d ... layLang=en)
2 - включить установленные компоненты, чтобы можно было использовать их в EXCEL VBA. В редакторе VBA идем в пункт меню TOOLS->References и ставим галочки на нужных компонентах (Microsoft Soap Type Library v3.0 и Microsoft XML, v6.0)
После этого можно начинать кодировать.
Я использовал следующий подход - на шаблоне имеется пустой лист с шапками и кнопка "обновить". По нажатию кнопки открывается форма, на которой задаются параметры запроса - фильтр по объектам, в моем случае и ввод пользовательского пароля (пока проверка пароля осуществляется на стороне Excelя с использованием "ЗАЩИТЫ ЛИСТА" и скрытия кода VBA). Есть кнопка начала процесса, ProgressBar, чтобы пользователь видел, сколько ему скучать. Ну и кнопка прерывания процесса, если уж совсем невмоготу ждать.
Текста VBA накручено много. Там и логика запароливания доступа для разных контрагентов, оживление ProgressBar и т.п хрень. Весь текст не выкладываю, так как к вопросу SOAP там относится совсем чуть. Принципиальные моменты такие:
1 - объявление переменной
Суффикс "30" может меняться, в зависимости от того, какой тулкит скачан. У меня так для
SOAPToolkit 3.0
2 - Создание экземпляра
Код: Выделить всё
Set soapclient = CreateObject("MSSOAP.SoapClient30")
3 - подготовка к использованию
Код: Выделить всё
soapclient.ClientProperty("ServerHTTPRequest") = True
Call soapclient.MSSoapInit("http://localhost/psid/index.php?r=SOAP/quote")
4 - вызов удаленной функции №1
Код: Выделить всё
XML = soapclient.getCodeList(Cells(1, 9), "какбысекретноеслово")
Здесь имеется ввиду, что значение параметра для передачи в удаленную функцию уже установлено в ячейке(1,9)
или №2
Код: Выделить всё
Line = soapclient.getobjectrow(code, "ещеболеесекретноеслово")
Вот собственно и всё. Остался единственный вопрос - надо ли (и как) уничтожать созданный экземпляр soapclient. Пока это не тяготит, но испытания насчет утечки памяти не проводил.
В качестве основы и учебного пособия использовал пример с сайта Центробанка - там они поясняют, как работать с их сервисами:
http://www.cbr.ru/scripts/Root.asp?Prtid=DWS
http://www.cbr.ru/scripts/MrrfSample.rar