Поводом для написания данной статьи послужила дискуссия на форуме Общий модуль: клиент и сервер о необходимости разработчика доработать типовую УТ 11.1 так, чтоб в момент проведения документа "Заказ клиента" выводилось диалоговое окно с вопросами для обновления информации на форме для изменения логики проведения документа. При попытке разобраться в необходимости такой меры на первое место встал методологический вопрос: почему нельзя провести подобное в клиент-серверном выполнении? А на самом деле нужно было задать вопрос: зачем нужно подобное уточнение в момент проведения документа. Конечно данная вещь запрещена средствами платформы 1С 8.3 и более ранних версий 8.2 где есть поддержка клиент-серверного режима работы. С сервера нельзя вызвать клиентскую процедуру.
В данной статье я решил использовать опыт разработки практически с "нуля" одной нетиповой торговой конфигурации, где ставилась задача обеспечить максимальную производительность при записи, проведении и отмены проведения документов.
При разработке собственных мелких конфигураций или при необходимости оптимизации таких громоздких как УТ 11.1, которая даже на мощных компьютерах при полностью включенном функционале начинает подтормаживать на любых действиях, не только при записи и проведении "массовых" документов: заказов клиентов, реализации товаров и услуг и прочих. Особенно это неприятно при выполнении регламентных операций по восстановлению последовательностей. Конечно, по данной теме есть множество статей, суть которых заключается (особенно это касается клиент-серверных вариантов) в переносе вычислительной нагрузки даже не на сервер приложений, а на SQL сервер, путем не только получения на нем данных из базы 1С, но и проведения там путем запросов математических вычислений с передачей готового результата (при необходимости) за один раз на сервер приложений для записи движений документа "одним пакетом". Ну или, в случае отказа от проведения, передачи некоторой информации на компьютер клиента для обновления информации в форме документа.
Конечно, это все очень важно и нужно, но есть еще одно узкое "бутылочное горло" это подход к самой методологии проведения документов. При сложных случаях во всей цепочке проведения необходимо знать: кто же в данный момент проводит документ человек или компьютер? Поясню на конкретном примере. Допустим есть маленькая конфигурация с несколькими документами и регистрами сведений и накопления. Из нашего примера это даже не маленький аналог УТ 11.1, а скорее очень упрощенная Розница. А вот функционал этой маленькой "розницы" не примитивное пробивание чеков и подготовка отчетов о розничных продажах, а более мощный. В крупных, территориально распределенных организациях бывают так называемые "номенклатурные войны" среди менеджеров: кто раньше всех успел оформить заказ клиента тот заработал больше. Имея номенклатуру в несколько сотен тысяч единиц в реале массово продается несколько десятков. Наподобие советского дефицита "товары повышенного спроса", которые к тому же нужно особым образом резервировать и по сложной логистической структуре доставлять до адресата - конечного покупателя. А есть товар, которого везде буквально завались и он никому не нужен :) А если для подобной системы требуется еще и получение сложной специализированной отчетности, то создание подобной системы учета "с нуля" оправданы.
Так как же добиться быстрого проведения документов? Нужны ли всегда все проверки при использовании файлового или клиент-серверного режима?
Предметная область конфигурации была следующей. Как уже упоминалось выше часть товара "повышенного спроса" приходится в реальном времени резервировать и анализировать свободные остатки. Остановимся на одном документе "Заказ покупателя". В подобной торговой конфигурации он имеет сложный алгоритм резервирования, заполнения и отображения предварительных результатов. Данные для такого документа не один раз приходится получать перед окончательным использованием из различных источников. Там присутствует первоначальная обработка в табличной части некоторой информации с пересылкой на сервер приложений, далее запрос данных на сервере базы данных SQL, дальнейший первоначальный расчет уже в другом запросе, затем возврат результата на сервер приложений, выгрузка в таблицы значений и далее опять обработка кодом в циклах (не все можно получить одним запросом).
А если подобная база должна работать в файловом режиме на 2-3 маломощных компьютерах? Как ускорить восстановление посделовательности и обмен данными?
Исходя из того, что при программной обработке и проведении документов нужно минимум проверок, а в большинстве случаев они должны вообще отсутствовать (как при обмене данными) мы выбрали два режима функционирования:
1. Документ проводился от руки человека (тут срабатывали интерактивные обработчики формы документа при котором максимум проверок по всевозможным вариантам);
2. Программное проведение (восстановление последовательности, обмен данными, внешнее подключение к базе, при котором программно можно все).
В первом случае, события управляемой формы ПередЗаписью(<Отказ>, <ПараметрыЗаписи>) и ПриЗаписи (Отказ) срабатывают только интерактивно (иначе кнопку провести "нажала рука пользователя"). И поскольку при "ручном" нажатии на кнопку можно не только провести (записать без проведения, можно отменить проведение, пометить на удаление), тут срабатывает куча системных обработчиков событий формы, объекта документа (еще не забудем про подписки на события, куда собственно и встраиваем функционал). В таком режиме на клиентской стороне можно использовать возможность задания вопросов пользователю до начала транзакции записи, обращаясь периодически на сервер для забора данных с целью "кто не успел, тот опоздал" проводить анализ данных и, главное что-то записывать в регистры. Дальше возвращаемся на клиент и снова можем задать вопрос, обновить форму и.т.д.
Самое главное, чтоб документ на сервере в момент проведения в процедуре ОбработкаПроведения(), "знал" кто его проводит человек или компьютер (конечно это сильно упрощенно, до этого момента вся серверная часть должна быть подготовлена обработчиками формы либо программными обработчиками второго режима. Обратимся к описанию обработчиков формы (использованы материалы статей обработчики событий при записи объектов. Зачем и что за чем?:
Модуль формы ПередЗаписью(Отказ, ПараметрыЗаписи)
Выполняется на клиенте!
Этот обработчик следует использовать, если необходимо организовать диалог с пользователем перед тем, как записать объект. Запросить дополнительную информацию, предупредить о чём-либо, дать возможность отказаться и т.п.
Второй параметр этого обработчика «ПараметрыЗаписи» имеет тип «Структура». У документов эти параметры заполняются системой предопределенными параметрами РежимЗаписи, РежимПроведения. Можно добавить свои.
Эти параметры передаются между событиями формы ПередЗаписьюНаСервере, ПриЗаписиНаСервере, ПослеЗаписиНаСервере, где их можно благополучно использовать. Например, при записи регистра сведений, надо сделать запись в другой регистр сведений старое значение ресурса. Можно передать старое значение в эти самые параметры и уже в ПриЗаписиНаСервере сделать запись в другой регистр.
Создадим тестовый пример. В тестовой конфигурации 8.3 будет один документ "заказ покупателя"
и посмотрим на обработчики объекта документа (в модуле документа). Далее создадим управляемую форму и посмотрим на список ее обработчиков
Видим их схожесть. Дальше можно посмотреть участок кода типовой УТ 11.1, где также используется обработчик формы ПередЗаписью (см. рисунок) и обратим внимание на параметры записи, которые можно передать вглубь процедуры (рис. отладчика).
В нашем примере, когда документ проводит человек проводятся всевозможные проверки на сервере. Возможен в любой момент до выхода отказ от проведения. Также будет корректная отработка интерактивной пометки на удаление и еще много специфических нюансов. Причем, большая часть проверок будет в клиентском режиме, не нагружая сервер излишней работой.
Во втором случае, при программном проведении, срабатывают только минимум системных обработчиков, которые выполняются всегда, в т.ч. и при интерактивном проведении. Ну и в дополнении специфические проверки: права пользователя, не залезли ли за дату запрета редактирования и прочее. В данной ситуации сервер нагружается по-минимуму. Возможно восстановление последовательности фоновым процессом не мешая пользователям при перерывах и прочие радости.
К сожалению, данная методика в стандартных конфигурациях не подходит. Придется очень сильно менять все внутренние механизмы. Если только менять обработчики одного документа очень аккуратно. Или, разве что для новых документов или подсистем добавляемых в конфигурацию.
Надеюсь, приведенная методика будет полезной при разработке своих систем учета. Также прошу поделиться опытом кто реализовывал подобные алгоритмы, когда параметры записи отсылаются по цепочке до момента окончания проведения документа.