При переводе информационной базы 1С из файлового режима в клиент-серверный вариант (SQL Server) разработчики нередко сталкиваются с ошибками выполнения кода, который ранее успешно работал. Типичный пример — сбой фонового обмена данными в распределенной информационной базе (РИБ) или падение транзакции проведения документа из-за вызова модальных окон. Разберем подробно, почему интерактивные методы вызывают критические сбои на сервере, к каким последствиям для СУБД это приводит и как правильно организовать контроль заполнения реквизитов.
Проанализируем ситуацию, когда в модуле объекта документа (например, в процедуре ОбработкаПроведения или при вызове вспомогательных процедур записи) размещен следующий код:
Процедура ПроверкаЗаполненияПродавец(Продавец)
Если Продавец.Пустая() Тогда
Продавец = ОткрытьФормуМодально("Справочник.ФизическиеЛица.ФормаВыбора",,Продавец);
КонецЕсли;
КонецПроцедуры
В файловой однопользовательской базе данный фрагмент работает без видимых исключений, если запись инициирована пользователем через интерфейс. Однако при переходе на SQL Server и настройке обменов возникают критические проблемы:
ОткрытьФорму, ОткрытьФормуМодально, Предупреждение или Вопрос приводит к аварийной остановке с ошибкой недоступности интерактивных операций.ОбменДанными.Загрузка = Истина. Загрузка пакетов выполняется пакетно на сервере. Интерактивные запросы блокируют процесс чтения XML и срывают автоматическую синхронизацию.Если требуется интерактивно запросить или заполнить значение перед сохранением документа пользователем, весь пользовательский интерфейс необходимо вынести в модуль формы. Логику проверки следует разместить в предопределенном событии ПередЗаписью формы.
Разберем по шагам правильную реализацию в модуле формы (для обычного приложения):
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
// Проверяем заполнение реквизита на клиенте до начала транзакции
Если Не ЗначениеЗаполнено(ЭтотОбъект.Продавец) Тогда
// Интерактивно открываем форму выбора
ВыбранноеЗначение = ОткрытьФормуМодально("Справочник.ФизическиеЛица.ФормаВыбора");
Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
ЭтотОбъект.Продавец = ВыбранноеЗначение;
Иначе
// Пользователь закрыл форму выбора, не выбрав значение
Сообщить("Не указан продавец! Проведение документа отменено.", СтатусСообщения.Важное);
Отказ = Истина;
Возврат;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В этом случае модальный диалог отрабатывает строго на клиенте до открытия серверной транзакции записи. Если документ проводится программно, через фоновое задание или загружается по РИБ, модуль формы вообще не инициализируется, и ошибка не возникает.
Для гарантированной проверки данных независимо от того, как записывается объект (интерактивно через форму или программно из внешних источников), правила платформы 1С требуют разделять логику проверки и интерфейс.
Посмотрим, как организовать неинтерактивную проверку:
Продавец и установим свойство Проверка заполнения в значение Выдавать ошибку.ПередЗаписью и ОбработкаПроведения первой строкой всегда добавляем проверку режима загрузки данных:
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Если РежимЗаписи = РежимЗаписиДокумента.Проведение И Не ЗначениеЗаполнено(Продавец) Тогда
Сообщить("Поле ""Продавец"" не заполнено!", СтатусСообщения.Важное);
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Для визуального выделения поля на форме включим у соответствующего элемента управления свойство АвтоОтметкаНезаполненного = Истина. При таком подходе пользователь сразу видит обязательное поле, а транзакции SQL Server не удерживают блокировки в ожидании действий оператора.