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

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

Как записать объект на форме 1С

Как записать объект на форме 1С: методы Записать(), ЗаписатьВФорме, работа с ДанныеФормыВЗначение, запись документов и справочников, типичные ошибки и FAQ.

Запись объекта с формы — одна из базовых операций при доработке конфигураций 1С. Разработчик сталкивается с ней, когда нужно сохранить изменённые данные программно: например, провести документ по кнопке, записать элемент справочника после редактирования реквизитов или сохранить объект из произвольной формы обработки.

Главная сложность в том, что на управляемой форме данные обычно представлены не самим объектом, а реквизитом формы типа ДанныеФормыСтруктура, и напрямую вызвать метод Записать() у него нельзя. Нужно либо использовать штатные средства формы, либо преобразовать данные формы в объект, записать его и вернуть результат обратно.

Ниже разобраны рабочие способы записи объекта с формы: стандартная команда, метод формы Записать(), программная запись через ДанныеФормыВЗначение, запись на сервере и особенности для документов, справочников и регистров. Отдельно рассмотрены типичные ошибки, из-за которых запись «молча» не происходит или вызывает исключение.

Как устроены данные на управляемой форме

На управляемой форме 1С работает разделение контекстов: клиентский код не имеет прямого доступа к базе данных, а данные объекта хранятся в реквизитах формы. Основной реквизит формы объекта (например, Объект у документа или справочника) имеет тип ДанныеФормыСтруктура — это сериализуемое представление объекта, а не сам прикладной объект.

Из-за этого попытка написать Объект.Записать() на клиенте приведёт к ошибке: у ДанныеФормыСтруктура нет такого метода. Платформа предлагает два пути: использовать встроенные механизмы формы (команды «Записать», «Провести», метод формы Записать()) или вручную конвертировать данные в объект на сервере.

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

Самый простой и предпочтительный способ — не изобретать свой код, а вызвать штатный механизм. У формы объекта есть метод Записать(), который выполняет ту же запись, что и кнопка «Записать» в командной панели. Он доступен и на клиенте, и сам корректно переносит данные на сервер.

Метод принимает необязательный параметр — структуру параметров записи. Для документа через неё можно указать режим записи: РежимЗаписиДокумента.Проведение, ОтменаПроведения или Запись. Также поддерживается параметр РежимПроведенияДокумента (оперативный или неоперативный).

&НаКлиенте

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

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

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

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

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

КонецЕсли;

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

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

Программная запись через ДанныеФормыВЗначение

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

&НаСервере

Процедура ЗаписатьОбъектНаСервере()

ОбъектДанных = РеквизитФормыВЗначение("Объект");

ОбъектДанных.Комментарий = "Записан программно";

ОбъектДанных.Записать();

ЗначениеВРеквизитФормы(ОбъектДанных, "Объект");

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

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

Для документа метод Записать() принимает параметры: ОбъектДанных.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Оперативный). Если проведение не требуется, достаточно вызова без параметров.

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

Особенности записи разных типов объектов

Документы

Для документа важен режим записи. Обычная запись сохраняет документ без движений по регистрам, проведение — формирует движения, отмена проведения — очищает их. При проведении из формы учитывайте оперативный режим: если документ проводится текущей датой, оперативное проведение может быть запрещено настройками или правами.

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

Справочники

Запись элемента справочника проще: параметров у Записать() нет. Основные подводные камни — дубли по наименованию или коду (если включён контроль уникальности) и обязательные реквизиты, проверяемые в ОбработкаПроверкиЗаполнения. Ошибки заполнения выводятся пользователю, а запись отклоняется.

Регистры сведений и наборы записей

Если на форме редактируется набор записей регистра (например, форма записи регистра сведений), логика аналогична: набор преобразуется через РеквизитФормыВЗначение, вызывается Записать() набора. У набора записей параметр Записать(Истина) означает полную замену записей по отбору, Ложь — добавление.

Способы записи объекта с формы

Метод формы Записать()

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

ДанныеФормыВЗначение + Записать()

Полный контроль: проверки, транзакции, запись нескольких объектов. Требует серверного вызова и обратного преобразования.

Менеджер объекта (Справочники.Имя.СоздатьЭлемент())

Используется, когда объект не связан с реквизитом формы — например, создание связанного объекта из формы обработки. Данные на форму не возвращаются автоматически.

Запись нескольких объектов и транзакции

Типичный сценарий доработки: по кнопке на форме нужно записать не только сам объект, но и связанные данные — например, создать контрагента, договор и записать документ. В этом случае все записи выполняются в одной серверной процедуре внутри явной транзакции.

&НаСервере

Процедура ЗаписатьВсеНаСервере(Отказ)

НачатьТранзакцию();

Попытка

НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();

НовыйКонтрагент.Наименование = НаименованиеКонтрагента;

НовыйКонтрагент.Записать();

ОбъектДанных = РеквизитФормыВЗначение("Объект");

ОбъектДанных.Контрагент = НовыйКонтрагент.Ссылка;

ОбъектДанных.Записать();

ЗначениеВРеквизитФормы(ОбъектДанных, "Объект");

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

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

ВызватьИсключение ОписаниеОшибки();

КонецПопытки;

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

Транзакция гарантирует, что при ошибке на любом шаге база не останется в половинчатом состоянии: либо записаны все объекты, либо ни одного. Без транзакции возможна ситуация, когда контрагент создан, а документ не записался из-за ошибки заполнения.

Проверка результата и типичные ошибки

После записи стоит убедиться, что объект действительно сохранён: у нового объекта заполнена ссылка, у документа — нужное значение Проведен. На клиенте полезно вызвать ОповеститьОбИзменении(Ссылка), чтобы открытые списки обновились.

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

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

Ссылка у нового объекта
Норма

Ссылка заполнена, Объект.Ссылка.Пустая() = Ложь

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

Ссылка пустая — запись не выполнилась или объект не возвращён в форму

Состояние проведения документа
Норма

Объект.Проведен соответствует выбранному режиму записи

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

Документ записан, но не проведён при режиме Проведение — были ошибки движений

Отображение в списках
Норма

После ОповеститьОбИзменении объект виден в списках

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

Объект не виден — не вызвано оповещение или запись прошла в другой сеанс

Сообщения пользователю
Норма

Нет сообщений об ошибках заполнения

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

Есть сообщения — запись отклонена проверкой заполнения

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

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

Чем Записать() у формы отличается от Записать() у объекта?

Метод формы работает с основным реквизитом формы и сам управляет передачей данных между клиентом и сервером, возвращая Истина/Ложь. Метод прикладного объекта вызывается только на сервере после преобразования ДанныеФормыВЗначение и при ошибке вызывает исключение, а не возвращает Ложь.

Как записать объект, если форма ещё не сохранялась и ссылки нет?

Точно так же: преобразуйте данные формы в объект через РеквизитФормыВЗначение и вызовите Записать(). Платформа присвоит ссылку автоматически. Главное — вернуть объект в форму через ЗначениеВРеквизитФормы, чтобы интерфейс «увидел» новую ссылку.

Можно ли провести документ, не открывая транзакцию вручную?

Да. Метод Записать() у объекта сам выполняется в транзакции, которую платформа открывает неявно. Явная транзакция нужна только когда в одной операции записывается несколько объектов и требуется их атомарность.

Почему при программной записи не срабатывают проверки заполнения?

Скорее всего, перед записью установлено ОбъектДанных.ОбменДанными.Загрузка = Истина. В этом режиме проверки и обработчики пропускаются. Уберите установку этого свойства — оно предназначено только для механизмов обмена данными.

Как записать объект из формы обработки, где нет основного реквизита?

Используйте менеджер объекта: Справочники.Имя.СоздатьЭлемент() или Документы.Имя.СоздатьДокумент() в серверной процедуре, заполните реквизиты из реквизитов формы и вызовите Записать(). Обратное преобразование в форму не требуется, если объект не отображается в реквизите формы.

Что делать, если запись отклоняется из-за прав доступа?

Проверьте роли пользователя на добавление/изменение соответствующего объекта. Программно можно выполнить запись в привилегированном режиме (УстановитьПривилегированныйРежим(Истина)), но только если это оправдано логикой задачи, иначе возникнет дыра в разграничении прав.

Итог

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

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