Разработка и Конфигурация · 10 мин
Как записать документ на клиенте 1С
Как записать документ на клиенте 1С: методы Записать и ЗаписатьВФорме, режимы проведения, работа с формой документа, типичные ошибки и проверка результата.
Запись документа на клиенте — одна из базовых операций при разработке и доработке конфигураций 1С. Речь идёт о ситуации, когда код выполняется в клиентском контексте (тонкий клиент, толстый клиент, веб-клиент), а не на сервере. От выбранного способа зависит, увидит ли пользователь диалоги, сработают ли обработчики формы и не упадёт ли код с ошибкой «Процедура или функция с указанным именем не определена».
В клиентском контексте доступны не все методы работы с документами. Например, создать объект документа через Документы.РеализацияТоваровУслуг.СоздатьДокумент() на клиенте нельзя — менеджер документов доступен только на сервере. Поэтому запись «на клиенте» обычно означает одно из двух: либо запись объекта, открытого в форме, через методы формы, либо программный вызов серверной процедуры, которая выполняет запись, а клиент лишь инициирует её и обрабатывает результат.
Ниже разобраны рабочие сценарии: запись через форму документа, запись с проведением, программное создание через серверный вызов, обработка ошибок и типичные ограничения тонкого клиента. Примеры приведены на встроенном языке 1С и подходят для управляемых форм в типовых и самописных конфигурациях.
Что доступно на клиенте, а что только на сервере
Главное ограничение клиентского контекста: в нём недоступны прикладные объекты типа ДокументОбъект, ДокументМенеджер, запросы и прямая работа с базой данных. Попытка выполнить Документы.ЗаказКлиента.СоздатьДокумент() в клиентской процедуре приведёт к ошибке компиляции или выполнения.
На клиенте доступны: данные формы (реквизит Объект типа ДанныеФормыСтруктура), методы формы Записать(), Прочитать(), команды формы, вызовы серверных процедур общих модулей с признаком «Сервер» и обработчики оповещений. Этого достаточно для большинства задач интерактивной записи.
Запись документа через форму
Самый частый сценарий — пользователь заполнил документ в открытой форме, а код должен его записать. Для этого у управляемой формы есть метод Записать(). Вызов без параметров записывает документ в текущем режиме; с параметрами можно указать режим записи и проведения.
&НаКлиенте
Процедура ЗаписатьИЗакрыть(Команда)
Если ЭтаФорма.Записать() Тогда
ЭтаФорма.Закрыть();
Иначе
ПоказатьПредупреждение(, "Документ не записан. Проверьте заполнение полей.");
КонецЕсли;
КонецПроцедуры
Метод возвращает Истина при успешной записи и Ложь, если запись не удалась (например, не заполнены обязательные реквизиты или проведение завершилось с ошибкой). Всегда проверяйте возвращаемое значение — это единственный надёжный признак результата на клиенте.
Запись с проведением
Чтобы не просто записать, а провести документ, передайте параметры:
&НаКлиенте
Процедура ПровестиДокумент(Команда)
ПараметрыЗаписи = Новый Структура;
ПараметрыЗаписи.Вставить("РежимЗаписи", РежимЗаписиДокумента.Проведение);
ПараметрыЗаписи.Вставить("РежимПроведения", РежимПроведенияДокумента.Оперативный);
Если ЭтаФорма.Записать(ПараметрыЗаписи) Тогда
ОповеститьОбИзменении(Объект.Ссылка);
КонецЕсли;
КонецПроцедуры
Режим проведения «Оперативный» допустим только для документов с текущей датой и при включённом оперативном проведении в метаданных. Для документов задним числом используйте РежимПроведенияДокумента.Неоперативный, иначе получите ошибку.
- 1Проверьте заполнение обязательных реквизитов (дата, организация, табличные части)
- 2Вызовите ЭтаФорма.Записать() или Записать с параметрами РежимЗаписи и РежимПроведения
- 3Проверьте возвращаемое значение: Истина — записано, Ложь — покажите пользователю сообщения об ошибках
- 4При успехе вызовите ОповеститьОбИзменении(Объект.Ссылка), чтобы обновить открытые списки
Программное создание и запись документа из клиентского кода
Когда документ нужно создать без открытия формы (например, по кнопке в списке или из обработки), логика записи размещается на сервере, а клиент только вызывает её. Общий модуль должен иметь флаги «Сервер» и «Вызов сервера».
// Общий модуль РаботаСДокументамиВызовСервера (Сервер, Вызов сервера)
Функция СоздатьПриходныйКассовый(Организация, Сумма) Экспорт
Док = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();
Док.Дата = ТекущаяДатаСеанса();
Док.Организация = Организация;
Док.СуммаДокумента = Сумма;
Док.Записать(РежимЗаписиДокумента.Запись);
Возврат Док.Ссылка;
КонецФункции
&НаКлиенте
Процедура СоздатьДокумент(Команда)
НоваяСсылка = РаботаСДокументамиВызовСервера.СоздатьПриходныйКассовый(Организация, Сумма);
Если ЗначениеЗаполнено(НоваяСсылка) Тогда
ПоказатьОповещениеПользователя("Создан документ", ПолучитьНавигационнуюСсылку(НоваяСсылка), Строка(НоваяСсылка));
ОповеститьОбИзменении(НоваяСсылка);
КонецЕсли;
КонецПроцедуры
Такой подход — единственный корректный способ программной записи из тонкого и веб-клиента. Возвращать на клиент следует ссылку или структуру с простыми типами: ДокументОбъект сериализовать нельзя, попытка вернуть его вызовет ошибку передачи данных.
Запись перед выполнением действия: печать, команды, ввод на основании
Частая задача — гарантировать, что документ записан перед печатью или созданием связанного документа. Если документ новый (модифицирован, ссылка пустая), сначала выполните запись, иначе печатная форма построится по несохранённым данным или команда завершится ошибкой.
&НаКлиенте
Процедура Печать(Команда)
Если Объект.Ссылка.Пустая() Или ЭтаФорма.Модифицированность Тогда
Если Не ЭтаФорма.Записать() Тогда
Возврат; // не записан — печатать нельзя
КонецЕсли;
КонецЕсли;
// далее вызов печати по ссылке
КонецПроцедуры
Признак незаписанного документа — пустая ссылка Объект.Ссылка.Пустая() и/или признак ЭтаФорма.Модифицированность. Проверяйте оба: документ может быть записан ранее, но изменён после записи.
Обработчики событий записи в форме
Для контроля процесса записи используются события формы: ПередЗаписью (на клиенте, можно отменить запись через параметр Отказ), ПередЗаписьюНаСервере, ПриЗаписиНаСервере и ПослеЗаписи (снова на клиенте). Клиентское ПередЗаписью — правильное место для интерактивных проверок и вопросов пользователю.
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если Объект.Товары.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Табличная часть пуста. Запись отменена.");
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Не выполняйте в ПередЗаписью длительных серверных вызовов и не модифицируйте другие объекты базы — событие предназначено для проверки и при необходимости отказа. Все изменения данных делайте в серверных обработчиках объекта (ПередЗаписью, ПриЗаписи модуля объекта).
Типичные ошибки и их причины
Наиболее частая проблема — попытка использовать объектные методы в клиентском контексте. Вторая по частоте — игнорирование возвращаемого значения Записать(), из-за чего код продолжает работу с незаписанным документом. Третья — неправильный режим проведения для документов задним числом.
Проверка результата и ограничения
Надёжные признаки успешной записи: метод формы вернул Истина, ссылка заполнена, ЭтаФорма.Модифицированность сброшена в Ложь, в списке документов появилась запись. Если записи нет, но ошибок не видно, проверьте журнал регистрации — отказы в подписках на события и обработчиках проведения фиксируются там.
Как проверить результат
Истина
Ложь — смотрите сообщения пользователю и журнал регистрации
Заполнена, Строка(Ссылка) показывает номер и дату
Пустая ссылка — документ не записан
Ложь после записи
Истина — есть несохранённые изменения
Свойство Проведен = Истина, движения видны в регистрах
Проведен = Ложь при режиме Проведение — ошибка контроля остатков или дат
Учтите ограничения: веб-клиент не поддерживает модальные вызовы без обработчиков оповещения — используйте ПоказатьВопрос с описанием оповещения вместо Вопрос(). В тонком клиенте недоступны COM-объекты и часть функций толстого клиента. Длительные операции записи (проведение крупных документов) лучше выносить в фоновые задания, чтобы не блокировать интерфейс.
Что важно запомнить
На клиенте документ записывается через форму методом ЭтаФорма.Записать() с проверкой результата. Программное создание выполняется на сервере, клиент получает ссылку. Режим проведения подбирайте под дату документа, а ошибки ищите в сообщениях и журнале регистрации.
Частые вопросы
Почему нельзя вызвать Объект.Записать() в форме документа?
В управляемой форме реквизит Объект — это ДанныеФормыСтруктура, а не ДокументОбъект. У него нет метода Записать(). Запись выполняет сама форма через ЭтаФорма.Записать(), которая неявно передаёт данные на сервер.
Как записать документ без открытия формы из тонкого клиента?
Напрямую — никак. Создайте общий модуль с флагами «Сервер» и «Вызов сервера», разместите в нём функцию создания и записи документа, а из клиентского кода вызовите её и получите ссылку на созданный документ.
Что вернёт Записать(), если проведение не удалось?
Метод вернёт Ложь, документ останется непроведённым или незаписанным (в зависимости от режима), а пользователю будут показаны сообщения об ошибках. Детали смотрите в журнале регистрации.
Можно ли записать документ без проведения, если он уже проведён?
Да, но при записи в режиме «Запись» проведённый документ будет распроведён. Если нужно сохранить проведение, используйте режим Проведение или заранее уточните требуемое поведение в прикладной логике.
Как задать пользователю вопрос перед записью в веб-клиенте?
Используйте асинхронный вызов ПоказатьВопрос с описанием оповещения в обработчике ПередЗаписью. Синхронный Вопрос() в веб-клиенте и при отключённой модальности работать не будет.
Почему после записи список документов не обновился?
Форма списка не узнаёт об изменении автоматически. После успешной записи вызовите ОповеститьОбИзменении(Ссылка) — открытые списки этого типа документов обновятся.