При разработке обработок загрузки данных начинающие разработчики часто сталкиваются с ситуацией, когда код процедуры написан без явных синтаксических ошибок, кнопка нажимается, но новый документ в базе данных так и не появляется. Разберем по шагам, почему возникает эта проблема, какие ошибки часто допускаются в клиент-серверном взаимодействии и как правильно организовать создание и проведение документов программно.
Проанализируем базовый механизм работы управляемых форм. Обработчик нажатия кнопки на форме выполняется в контексте клиента (директива &НаКлиенте). Если логика создания документа вынесена в отдельную процедуру с директивой &НаСервере, платформа не будет вызывать ее автоматически. Ее необходимо явно вызвать из клиентского метода.
Посмотрим на исходный пример, где обработка файла происходила на клиенте, а серверная процедура осталась изолированной:
&НаКлиенте
Процедура КнопкаВыполнитьНажатие(Команда)
// Обработка данных
// Серверная процедура СоздатьНовыйДокумент() здесь не вызывалась!
КонецПроцедуры
&НаСервере
Процедура СоздатьНовыйДокумент()
// Логика создания документа
КонецПроцедуры
Чтобы код отработал, свяжем клиентскую команду и серверный контекст:
&НаКлиенте
Процедура КнопкаВыполнитьНажатие(Команда)
СоздатьНовыйДокументНаСервере();
КонецПроцедуры
&НаСервере
Процедура СоздатьНовыйДокументНаСервере()
// Создание и запись документа
КонецПроцедуры
В коде создания объектов 1С важно соблюдать корректный синтаксис вызова методов. Рассмотрим типичные неточности:
Документы.ПеремещениеТоваров.СоздатьДокумент или ТекущаяДата без скобок () не вызывают метод или системную функцию, а возвращают описание объекта/метода. Обязательно пишем Документы.ПеремещениеТоваров.СоздатьДокумент().ТекущаяДата() на сервере рекомендуется применять ТекущаяДатаСеанса(), чтобы учитывать часовой пояс пользователя, запустившего сеанс.Разберем нюансы сохранения созданного документа в информационной базе:
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись); непосредственно перед НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение); создает лишнюю транзакцию и нагрузку на СУБД. Если документ нужно сразу провести, достаточно одного вызова с режимом РежимЗаписиДокумента.Проведение.Номер сбивает механизм автонумерации платформы. Рекомендуется использовать метод НовыйДокумент.УстановитьНовыйНомер(); или оставить формирование номера платформе при первой записи.СоздатьДокумент() создает полностью пустой объект. Чтобы сработал стандартный модуль объекта и реквизиты заполнились типовыми значениями, вызовем метод НовыйДокумент.Заполнить(Неопределено);.Объединим рекомендации и посмотрим на готовый шаблон процедуры создания документа на сервере:
&НаСервере
Процедура СоздатьНовыйДокументНаСервере()
НовыйДокумент = Документы.ПеремещениеТоваров.СоздатьДокумент();
// Инициализация стандартных реквизитов
НовыйДокумент.Заполнить(Неопределено);
НовыйДокумент.Дата = ТекущаяДатаСеанса();
НовыйДокумент.УстановитьНовыйНомер();
// Заполнение реквизитов шапки и табличных частей
// НовыйДокумент.Организация = ...
// НовыйДокумент.СкладОтправитель = ...
Попытка
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ВызватьИсключение "Ошибка при проведении документа: " + ОписаниеОшибки();
КонецПопытки;
КонецПроцедуры
Выясним причину, почему точки останова могут не срабатывать в процедурах с директивой &НаСервере. По умолчанию служба кластера серверов 1С запускается без режима отладки. Чтобы отладчик останавливался в серверных модулях:
ragent) в параметре запуска необходимо указать ключ -debug.dbgs, а соответствующие порты открыты в брандмауэре.Если данные для документа считываются из внешнего XML-файла, важно учитывать, что сервер 1С не имеет прямого доступа к файловой системе клиентского компьютера (по путям вида C:\test\test.xml). Правильная схема работы:
ПоместитьФайлНаСервер() или ПоместитьФайлыНаСервер().ПолучитьИзВременногоХранилища() и выполняем парсинг через ЧтениеXML или ФабрикаXDTO.