Как сохранить значение флажка в табличной части документа Установка цен номенклатуры

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

Приветствуем вас! Сегодня мы подробно разберем одну из самых распространенных проблем, с которой сталкиваются начинающие разработчики при доработке сложных типовых конфигураций «1С:Предприятие 8» (таких как ERP, Комплексная автоматизация или Управление торговлей 11). Проблема заключается в том, что добавленный на форму флажок (колонка с типом Булево) сбрасывает свое значение и не сохраняется в базе данных при проведении или закрытии документа. Особенно остро этот вопрос стоит в документе «Установка цен номенклатуры».

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

Выясним причину: почему данные флажка не сохраняются?

Для начала проанализируем ситуацию и поймем физику процесса взаимодействия формы и базы данных в системе 1С. Начинающие программисты часто совершают ошибку, полагая, что любое добавление колонки на форму автоматически влечет за собой сохранение этих данных. Это не так.

Данные на форме («данные формы») живут ровно до тех пор, пока открыто окно этой формы. Как только пользователь закрывает документ, оперативная память очищается, и все несохраненные данные теряются. Чтобы значение флажка сохранялось, оно обязательно должно быть связано с реквизитом базы данных.

Вторая и самая главная сложность конкретно с документом «Установка цен номенклатуры» заключается в его архитектуре:

  1. На форме этого документа отображается вовсе не стандартная табличная часть Товары, а дерево значений — специальный реквизит формы под названием ДеревоЦен.
  2. Интерфейс этой формы строится динамически. При ее открытии или изменении параметров вызываются сложные процедуры общего модуля (например, УстановкаЦенСервер.ПостроитьДеревоЦен), которые программно пересобирают структуру колонок.

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

---

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

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

Шаг 1. Добавление реквизита в табличную часть

Первым делом нам необходимо создать физическое место для хранения нашего флажка в базе данных. Для этого в расширении конфигурации найдем документ УстановкаЦенНоменклатуры, перенесем его в расширение и добавим в его табличную часть Товары (или Товары2_5 в зависимости от версии вашей конфигурации) новый реквизит. Назовем его, например, ВыбранДляАкции с типом данных Булево.

Шаг 2. Программное добавление реквизита в ДеревоЗначений формы

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

Пропишем следующий код, который добавит описание нового реквизита в структуру ДеревоЦен:


&После("ПриСозданииНаСервере")
Процедура ИмяРасш_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    // Описываем новый реквизит, привязывая его к пути "ДеревоЦен"
    НовыеРеквизиты = Новый Массив;
    ДобавляемыйРеквизит = Новый РеквизитФормы(
        "ВыбранДляАкции", 
        Новый ОписаниеТипов("Булево"), 
        "ДеревоЦен", 
        "Для акции"
    );
    НовыеРеквизиты.Добавить(ДобавляемыйРеквизит);
    
    // Применяем изменения структуры формы
    ИзменитьРеквизиты(НовыеРеквизиты);
    
КонецПроцедуры

Шаг 3. Визуальное отображение флажка на форме

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


// Находим элемент формы - таблицу дерева цен
РодительКолонки = Элементы.ДеревоЦен;
    
// Добавляем новое поле на форму
НоваяКолонка = Элементы.Добавить("ДеревоЦенВыбранДляАкции", Тип("ПолеФормы"), РодительКолонки);
НоваяКолонка.Вид = ВидПоляФормы.ПолеФлажка;
    
// Связываем визуальный элемент с созданным ранее путем к данным
НоваяКолонка.ПутьКДанным = "ДеревоЦен.ВыбранДляАкции";
НоваяКолонка.Заголовок = "Акция";

Шаг 4. Чтение сохраненных данных из базы

Теперь колонка отображается на форме, но она будет пустой при открытии ранее созданного документа. Нам нужно научить систему считывать данные из нашей табличной части в динамическое дерево цен. Для этого в общем модуле УстановкаЦенСервер нам потребуется расширить процедуру заполнения (например, ЗагрузитьТабличнуюЧастьТовары или аналогичный метод компоновки дерева). Используя метод &Вместо или &После, скорректируем запрос получения данных, добавив в него выборку нашего реквизита:


// Пример фрагмента запроса, дополняющего выборку
Запрос.Текст = СтрЗаменить(Запрос.Текст, 
    "Товары.Номенклатура КАК Номенклатура,", 
    "Товары.Номенклатура КАК Номенклатура, Товары.ВыбранДляАкции КАК ВыбранДляАкции,");

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

НоваяСтрокаДерева.ВыбранДляАкции = СтрокаВыборки.ВыбранДляАкции;

Шаг 5. Запись изменений обратно в базу данных

Финальный штрих — сохранение измененного пользователем флажка обратно в базу. Перед записью документа выполняется обратный перенос данных из дерева на форме в табличную часть объекта. Найдем процедуру, отвечающую за этот перенос (например, ЗаписатьИзмененияЦенНаСервере) и добавим в нее обход строк дерева с записью в табличную часть:


// В цикле переноса данных из ДереваЦен обратно в ТабличнуюЧасть Товары
СтрокаТЧ.ВыбранДляАкции = СтрокаДерева.ВыбранДляАкции;

---

Способ 2. Альтернативное решение с использованием регистра сведений

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

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

Разберем этот вариант по шагам:

  1. Создание регистра сведений: Создадим новый независимый регистр сведений, например, ХозяйственныеНастройкиДокументов.
    • Измерения: ДокументУстановки (тип: ДокументСсылка.УстановкаЦенНоменклатуры), Номенклатура (тип: СправочникСсылка.Номенклатура).
    • Ресурсы: ФлажокАктивен (тип: Булево).
  2. Программное добавление колонки на форму: Точно так же, как и в первом способе, динамически добавляем колонку в ДеревоЦен при создании формы на сервере.
  3. Чтение данных при открытии: В обработчике чтения данных формы пишем простой запрос к нашему регистру сведений и заполняем созданную колонку в дереве значений.
  4. Запись при изменении: Для созданного элемента формы (поля флажка) программно назначаем событие ПриИзменении. В обработчике этого события прописываем код оперативной записи в регистр сведений:

&НаСервереБезКонтекста
Процедура ЗаписатьФлажокВРегистр(ДокументСсылка, НоменклатураСсылка, ЗначениеФлажка)
    
    МенеджерЗаписи = РегистрыСведений.ХозяйственныеНастройкиДокументов.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.ДокументУстановки = ДокументСсылка;
    МенеджерЗаписи.Номенклатура       = НоменклатураСсылка;
    МенеджерЗаписи.ФлажокАктивен     = ЗначениеФлажка;
    
    МенеджерЗаписи.Записать(Истина);
    
КонецПроцедуры

Этот способ значительно безопаснее, так как мы никак не влияем на типовые транзакции проведения и записи самого сложного документа ценообразования.

Подведем итоги

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

← На главную