К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как записать документ на клиенте 1С

Как записать документ на клиенте 1С: методы Записать и ЗаписатьВФорме, режимы проведения, работа с формой документа, типичные ошибки и проверка результата.

Запись документа на клиенте — одна из базовых операций при разработке и доработке конфигураций 1С. Речь идёт о ситуации, когда код выполняется в клиентском контексте (тонкий клиент, толстый клиент, веб-клиент), а не на сервере. От выбранного способа зависит, увидит ли пользователь диалоги, сработают ли обработчики формы и не упадёт ли код с ошибкой «Процедура или функция с указанным именем не определена».

В клиентском контексте доступны не все методы работы с документами. Например, создать объект документа через Документы.РеализацияТоваровУслуг.СоздатьДокумент() на клиенте нельзя — менеджер документов доступен только на сервере. Поэтому запись «на клиенте» обычно означает одно из двух: либо запись объекта, открытого в форме, через методы формы, либо программный вызов серверной процедуры, которая выполняет запись, а клиент лишь инициирует её и обрабатывает результат.

Ниже разобраны рабочие сценарии: запись через форму документа, запись с проведением, программное создание через серверный вызов, обработка ошибок и типичные ограничения тонкого клиента. Примеры приведены на встроенном языке 1С и подходят для управляемых форм в типовых и самописных конфигурациях.

Что доступно на клиенте, а что только на сервере

Главное ограничение клиентского контекста: в нём недоступны прикладные объекты типа ДокументОбъект, ДокументМенеджер, запросы и прямая работа с базой данных. Попытка выполнить Документы.ЗаказКлиента.СоздатьДокумент() в клиентской процедуре приведёт к ошибке компиляции или выполнения.

На клиенте доступны: данные формы (реквизит Объект типа ДанныеФормыСтруктура), методы формы Записать(), Прочитать(), команды формы, вызовы серверных процедур общих модулей с признаком «Сервер» и обработчики оповещений. Этого достаточно для большинства задач интерактивной записи.

Запись документа через форму

Самый частый сценарий — пользователь заполнил документ в открытой форме, а код должен его записать. Для этого у управляемой формы есть метод Записать(). Вызов без параметров записывает документ в текущем режиме; с параметрами можно указать режим записи и проведения.

&НаКлиенте

Процедура ЗаписатьИЗакрыть(Команда)

Если ЭтаФорма.Записать() Тогда

ЭтаФорма.Закрыть();

Иначе

ПоказатьПредупреждение(, "Документ не записан. Проверьте заполнение полей.");

КонецЕсли;

КонецПроцедуры

Метод возвращает Истина при успешной записи и Ложь, если запись не удалась (например, не заполнены обязательные реквизиты или проведение завершилось с ошибкой). Всегда проверяйте возвращаемое значение — это единственный надёжный признак результата на клиенте.

Запись с проведением

Чтобы не просто записать, а провести документ, передайте параметры:

&НаКлиенте

Процедура ПровестиДокумент(Команда)

ПараметрыЗаписи = Новый Структура;

ПараметрыЗаписи.Вставить("РежимЗаписи", РежимЗаписиДокумента.Проведение);

ПараметрыЗаписи.Вставить("РежимПроведения", РежимПроведенияДокумента.Оперативный);

Если ЭтаФорма.Записать(ПараметрыЗаписи) Тогда

ОповеститьОбИзменении(Объект.Ссылка);

КонецЕсли;

КонецПроцедуры

Режим проведения «Оперативный» допустим только для документов с текущей датой и при включённом оперативном проведении в метаданных. Для документов задним числом используйте РежимПроведенияДокумента.Неоперативный, иначе получите ошибку.

Порядок записи через форму
  1. 1
    Проверьте заполнение обязательных реквизитов (дата, организация, табличные части)
  2. 2
    Вызовите ЭтаФорма.Записать() или Записать с параметрами РежимЗаписи и РежимПроведения
  3. 3
    Проверьте возвращаемое значение: Истина — записано, Ложь — покажите пользователю сообщения об ошибках
  4. 4
    При успехе вызовите ОповеститьОбИзменении(Объект.Ссылка), чтобы обновить открытые списки

Программное создание и запись документа из клиентского кода

Когда документ нужно создать без открытия формы (например, по кнопке в списке или из обработки), логика записи размещается на сервере, а клиент только вызывает её. Общий модуль должен иметь флаги «Сервер» и «Вызов сервера».

// Общий модуль РаботаСДокументамиВызовСервера (Сервер, Вызов сервера)

Функция СоздатьПриходныйКассовый(Организация, Сумма) Экспорт

Док = Документы.ПриходныйКассовыйОрдер.СоздатьДокумент();

Док.Дата = ТекущаяДатаСеанса();

Док.Организация = Организация;

Док.СуммаДокумента = Сумма;

Док.Записать(РежимЗаписиДокумента.Запись);

Возврат Док.Ссылка;

КонецФункции

&НаКлиенте

Процедура СоздатьДокумент(Команда)

НоваяСсылка = РаботаСДокументамиВызовСервера.СоздатьПриходныйКассовый(Организация, Сумма);

Если ЗначениеЗаполнено(НоваяСсылка) Тогда

ПоказатьОповещениеПользователя("Создан документ", ПолучитьНавигационнуюСсылку(НоваяСсылка), Строка(НоваяСсылка));

ОповеститьОбИзменении(НоваяСсылка);

КонецЕсли;

КонецПроцедуры

Такой подход — единственный корректный способ программной записи из тонкого и веб-клиента. Возвращать на клиент следует ссылку или структуру с простыми типами: ДокументОбъект сериализовать нельзя, попытка вернуть его вызовет ошибку передачи данных.

Запись перед выполнением действия: печать, команды, ввод на основании

Частая задача — гарантировать, что документ записан перед печатью или созданием связанного документа. Если документ новый (модифицирован, ссылка пустая), сначала выполните запись, иначе печатная форма построится по несохранённым данным или команда завершится ошибкой.

&НаКлиенте

Процедура Печать(Команда)

Если Объект.Ссылка.Пустая() Или ЭтаФорма.Модифицированность Тогда

Если Не ЭтаФорма.Записать() Тогда

Возврат; // не записан — печатать нельзя

КонецЕсли;

КонецЕсли;

// далее вызов печати по ссылке

КонецПроцедуры

Признак незаписанного документа — пустая ссылка Объект.Ссылка.Пустая() и/или признак ЭтаФорма.Модифицированность. Проверяйте оба: документ может быть записан ранее, но изменён после записи.

Обработчики событий записи в форме

Для контроля процесса записи используются события формы: ПередЗаписью (на клиенте, можно отменить запись через параметр Отказ), ПередЗаписьюНаСервере, ПриЗаписиНаСервере и ПослеЗаписи (снова на клиенте). Клиентское ПередЗаписью — правильное место для интерактивных проверок и вопросов пользователю.

&НаКлиенте

Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)

Если Объект.Товары.Количество() = 0 Тогда

ПоказатьПредупреждение(, "Табличная часть пуста. Запись отменена.");

Отказ = Истина;

КонецЕсли;

КонецПроцедуры

Не выполняйте в ПередЗаписью длительных серверных вызовов и не модифицируйте другие объекты базы — событие предназначено для проверки и при необходимости отказа. Все изменения данных делайте в серверных обработчиках объекта (ПередЗаписью, ПриЗаписи модуля объекта).

Типичные ошибки и их причины

Наиболее частая проблема — попытка использовать объектные методы в клиентском контексте. Вторая по частоте — игнорирование возвращаемого значения Записать(), из-за чего код продолжает работу с незаписанным документом. Третья — неправильный режим проведения для документов задним числом.

Типичные ошибки
01
Вызов Документы.ИмяДокумента.СоздатьДокумент() в клиентской процедуре — ошибка компиляции; перенесите создание в серверный общий модуль
02
Игнорирование результата ЭтаФорма.Записать() — код дальше работает с пустой ссылкой, печать и ввод на основании падают
03
Оперативное проведение документа прошлой датой — ошибка проведения; используйте Неоперативный режим
04
Попытка вернуть ДокументОбъект с сервера на клиент — ошибка передачи данных; возвращайте ссылку или структуру
05
Обращение к Объект.Записать() в форме — у ДанныеФормыСтруктура нет такого метода; вызывайте ЭтаФорма.Записать()

Проверка результата и ограничения

Надёжные признаки успешной записи: метод формы вернул Истина, ссылка заполнена, ЭтаФорма.Модифицированность сброшена в Ложь, в списке документов появилась запись. Если записи нет, но ошибок не видно, проверьте журнал регистрации — отказы в подписках на события и обработчиках проведения фиксируются там.

Контрольные точки

Как проверить результат

Возвращаемое значение Записать()
Норма

Истина

Тревожный признак

Ложь — смотрите сообщения пользователю и журнал регистрации

Ссылка после записи
Норма

Заполнена, Строка(Ссылка) показывает номер и дату

Тревожный признак

Пустая ссылка — документ не записан

Модифицированность формы
Норма

Ложь после записи

Тревожный признак

Истина — есть несохранённые изменения

Проведение
Норма

Свойство Проведен = Истина, движения видны в регистрах

Тревожный признак

Проведен = Ложь при режиме Проведение — ошибка контроля остатков или дат

Учтите ограничения: веб-клиент не поддерживает модальные вызовы без обработчиков оповещения — используйте ПоказатьВопрос с описанием оповещения вместо Вопрос(). В тонком клиенте недоступны COM-объекты и часть функций толстого клиента. Длительные операции записи (проведение крупных документов) лучше выносить в фоновые задания, чтобы не блокировать интерфейс.

Итог

Что важно запомнить

На клиенте документ записывается через форму методом ЭтаФорма.Записать() с проверкой результата. Программное создание выполняется на сервере, клиент получает ссылку. Режим проведения подбирайте под дату документа, а ошибки ищите в сообщениях и журнале регистрации.

Частые вопросы

Почему нельзя вызвать Объект.Записать() в форме документа?

В управляемой форме реквизит Объект — это ДанныеФормыСтруктура, а не ДокументОбъект. У него нет метода Записать(). Запись выполняет сама форма через ЭтаФорма.Записать(), которая неявно передаёт данные на сервер.

Как записать документ без открытия формы из тонкого клиента?

Напрямую — никак. Создайте общий модуль с флагами «Сервер» и «Вызов сервера», разместите в нём функцию создания и записи документа, а из клиентского кода вызовите её и получите ссылку на созданный документ.

Что вернёт Записать(), если проведение не удалось?

Метод вернёт Ложь, документ останется непроведённым или незаписанным (в зависимости от режима), а пользователю будут показаны сообщения об ошибках. Детали смотрите в журнале регистрации.

Можно ли записать документ без проведения, если он уже проведён?

Да, но при записи в режиме «Запись» проведённый документ будет распроведён. Если нужно сохранить проведение, используйте режим Проведение или заранее уточните требуемое поведение в прикладной логике.

Как задать пользователю вопрос перед записью в веб-клиенте?

Используйте асинхронный вызов ПоказатьВопрос с описанием оповещения в обработчике ПередЗаписью. Синхронный Вопрос() в веб-клиенте и при отключённой модальности работать не будет.

Почему после записи список документов не обновился?

Форма списка не узнаёт об изменении автоматически. После успешной записи вызовите ОповеститьОбИзменении(Ссылка) — открытые списки этого типа документов обновятся.