Как реализовать аналог документа «ОперацияБух» на управляемых формах в 1С и связать движения с регистратором без кода?

Программист 1С v8.3 (Управляемые формы) Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При переходе с обычных (неуправляемых) форм на управляемые формы (УФ) разработчики часто сталкиваются с изменением логики работы привычных механизмов. Одним из таких примеров является создание аналога стандартного документа «ОперацияБух» (ручная операция). В обычных формах достаточно было просто разместить табличное поле, связать его с набором записей регистра бухгалтерии, и платформа автоматически считывала и записывала проводки по текущему документу-регистратору. На управляемых формах эта «магия» на первый взгляд пропадает: данные либо не отображаются при открытии, либо введенные строки бесследно исчезают после закрытия формы.

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

Выясняем причину: почему пропадают записи в наборе?

Давайте проанализируем ситуацию, в которой оказался автор темы. При создании документа, у которого отключено проведение, разработчик попытался пойти по пути создания произвольного реквизита управляемой формы с типом РегистрБухгалтерииНаборЗаписей.Хозрасчетный, вынес его на форму в виде таблицы и ожидал автоматической работы. Однако при запуске приложения новые строки добавлялись, но после закрытия и повторного открытия формы таблица оставалась пустой.

Дело в том, что любой набор записей регистра жестко привязан к понятию отбора по регистратору. Набор записей — это не вся таблица базы данных, а лишь ее порция, отфильтрованная по конкретному документу. Если мы создаем независимый реквизит формы с типом «Набор записей», платформа не может самостоятельно догадаться, к какому именно документу (регистратору) этот набор относится. Платформа не устанавливает отбор автоматически, не считывает данные из базы данных при открытии и не выполняет запись набора при сохранении документа.

Для решения этой задачи у нас есть два пути: использовать встроенные механизмы расширения управляемой формы документа или написать программную привязку. Рассмотрим оба варианта по шагам.

Решение 1. Стандартный метод через «Объект.Движения» (без написания кода)

Это самый простой, надежный и рекомендуемый способ, реализующий ту самую автоматическую связь, к которой разработчики привыкли в обычных формах. В управляемом интерфейсе за это отвечает специальный механизм — расширение управляемой формы для документа.

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

Выполним настройку по шагам:

  1. Откроем Конфигуратор и перейдем к нашему документу-аналогу «ОперацииБух».
  2. Перейдем на вкладку «Движения» в дереве метаданных документа.
  3. В списке регистров найдем нужный нам регистр бухгалтерии (например, Хозрасчетный) и установим напротив него флаг. Тем самым мы объявляем наш документ регистратором для этого регистра.
  4. На вкладке «Основные» установим свойство «Проведение» в значение «Запретить». Наш документ не должен формировать движения через обработку проведения, все записи будут интерактивно вноситься пользователем и записываться напрямую.
  5. Откроем управляемую форму документа.
  6. В окне «Реквизиты» (в правой части редактора формы) развернем структуру основного реквизита Объект.
  7. Найдем ветку Движения, а внутри нее — наш регистр Хозрасчетный (он будет доступен там, так как мы указали документ регистратором на шаге 3).
  8. Перетащим мышкой Объект.Движения.Хозрасчетный на рабочую область формы (в левую часть редактора) в виде таблицы.

Все! Никакого кода писать не нужно. Платформа автоматически сделает следующее:

Решение 2. Программный метод (если используется отдельный реквизит формы)

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

Пусть мы создали на форме реквизит с именем ПроводкиДокумента и типом РегистрБухгалтерииНаборЗаписей.Хозрасчетный. Чтобы связать его с документом и заставить данные сохраняться, нам придется вручную прописать логику в модуле управляемой формы.

Рассмотрим подробнее, как должен выглядеть программный код в обработчиках событий формы:


&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
    // 1. Извлекаем прикладной объект набора записей из реквизита формы
    НаборЗаписей = РеквизитФормыВЗначение("ПроводкиДокумента");
    
    // 2. Устанавливаем жесткий отбор по текущему документу
    НаборЗаписей.Отбор.Регистратор.Установить(Объект.Ссылка);
    
    // 3. Читаем данные из базы данных
    НаборЗаписей.Прочитать();
    
    // 4. Возвращаем заполненный набор обратно в реквизит формы для отображения на клиенте
    ЗначениеВРеквизитФормы(НаборЗаписей, "ПроводкиДокумента");
КонецПроцедуры

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    // 1. Преобразуем экранные данные реквизита в объект набора записей
    НаборЗаписей = РеквизитФормыВЗначение("ПроводкиДокумента");
    
    // 2. Перед записью обязательно обновляем отбор (особенно важно для новых, только что созданных документов)
    НаборЗаписей.Отбор.Регистратор.Установить(Объект.Ссылка);
    
    // 3. Записываем проводки в базу данных
    НаборЗаписей.Записать();
КонецПроцедуры

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

Особенности программного создания документов типа «ОперацияБух»

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

Выясним причину: почему нельзя сразу записать проводки вместе с документом в одной транзакции программно, так же, как это делается на форме? Дело в том, что у нового документа еще нет уникальной ссылки в базе данных. А без ссылки мы не можем установить значение в поле Регистратор для записей регистра.

Разберем по шагам правильный алгоритм создания документа без проведения и его проводок:

  1. Создаем новый документ в памяти и заполняем его реквизиты шапки (дата, организация, содержание и т.д.).
  2. Обязательно записываем документ в режиме обычной записи (не проведения), чтобы получить уникальную ссылку.
  3. Обращаемся к коллекции движений записанного документа, добавляем строки проводок и заполняем их аналитику.
  4. Явно вызываем метод Записать() для коллекции движений.

Посмотрим на практический пример кода:


// Шаг 1. Создание и первоначальное заполнение документа
НовыйДокумент = Документы.АналогОперацииБух.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
НовыйДокумент.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", "7700000000");
НовыйДокумент.Содержание = "Ручная операция (программный ввод)";

// Шаг 2. Запись документа для генерации ссылки в БД
НовыйДокумент.Записать(РежимЗаписиДокумента.Запись);

// Шаг 3. Заполнение движений регистра бухгалтерии
Проводки = НовыйДокумент.Движения.Хозрасчетный;

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

// Шаг 4. Фиксация проводок в базе данных
Проводки.Записать();

Важный нюанс: динамическое редактирование Субконто на форме

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

Если просто перетащить поля субконто на форму, они будут отображаться как обычные текстовые строки или вовсе окажутся недоступными для ввода. Чтобы интерактивное редактирование аналитики работало корректно, необходимо правильно настроить свойства элементов формы:

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

← На главную