Как программно или через расширение добавить колонку из другого регистра в динамический список 1С?

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

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

Метод 1. Правильное использование расширения для изменения динамического списка

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

Разберем по шагам алгоритм разблокировки запроса:

  1. Откроем форму списка документа (например, ПеремещениеТоваров) в конфигураторе расширения.
  2. Перейдем на закладку Реквизиты (правое верхнее окно конструктора формы).
  3. Найдем основной реквизит формы — обычно он называется Список и имеет тип ДинамическийСписок.
  4. Нажмем на него правой кнопкой мыши и выберем пункт Добавить в расширение. Это критически важный шаг, без которого свойства списка останутся закрытыми.
  5. После этого в палитре свойств реквизита Список станет доступна гиперссылка Настройка списка.

Проанализируем ситуацию внутри конструктора запроса. Теперь мы можем модифицировать текст запроса, добавив ЛЕВОЕ СОЕДИНЕНИЕ с нашим регистром сведений. Рассмотрим пример такого запроса:


ВЫБРАТЬ
    ДокументПеремещение.Ссылка КАК Ссылка,
    ДокументПеремещение.Дата КАК Дата,
    ДокументПеремещение.Номер КАК Номер,
    ВЫБОР
        КОГДА СведенияОбОригиналах.ОригиналПолучен = ИСТИНА
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК Оригинал
ИЗ
    Документ.ПеремещениеТоваров КАК ДокументПеремещение
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусыОригиналов КАК СведенияОбОригиналах
        ПО ДокументПеремещение.Ссылка = СведенияОбОригиналах.Документ

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

Метод 2. Программное добавление колонки без визуального редактирования СКД

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

Рассмотрим алгоритм программной модификации:

Во-первых, нам нужно изменить текст запроса динамического списка. Мы можем считать текущий текст и добавить в него нужные поля и соединения с помощью строковых функций. Посмотрим на пример реализации:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Получаем текущий текст запроса
    ТекстЗапроса = Список.ТекстЗапроса;
    
    // Добавляем соединение и новое поле. 
    // Важно найти место после основного источника данных.
    НовыйТекст = СтрЗаменить(ТекстЗапроса, 
        "ИЗ Документ.ПеремещениеТоваров КАК ПеремещениеТоваров", 
        "ИЗ Документ.ПеремещениеТоваров КАК ПеремещениеТоваров 
        | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НаличиеОригиналов КАК ХранилищеСтатусов 
        | ПО ПеремещениеТоваров.Ссылка = ХранилищеСтатусов.Документ");
    
    // Добавляем поле в секцию ВЫБРАТЬ
    НовыйТекст = СтрЗаменить(НовыйТекст, 
        "ПеремещениеТоваров.Ссылка КАК Ссылка,", 
        "ПеремещениеТоваров.Ссылка КАК Ссылка, ЕСТЬNULL(ХранилищеСтатусов.ОригиналПолучен, ЛОЖЬ) КАК СтатусОригинала,");
    
    Список.ТекстЗапроса = НовыйТекст;
    
    // Теперь добавим колонку на форму программно
    НоваяКолонка = Элементы.Добавить("СписокСтатусОригинала", Тип("ПолеФормы"), Элементы.Список);
    НоваяКолонка.Заголовок = "Оригинал";
    НоваяКолонка.Вид = ВидПоляФормы.ПолеФлажка;
    НоваяКолонка.ПутьКДанным = "Список.СтатусОригинала";
    
КонецПроцедуры

Проанализируем этот код: использование ЕСТЬNULL позволяет нам корректно обрабатывать документы, по которым в регистре еще нет записей, подставляя значение ЛОЖЬ. Метод Элементы.Добавить создает визуальный элемент, связывая его с виртуальным полем, которое мы только что создали в запросе.

Метод 3. Использование типовых механизмов (Состояния оригиналов)

Прежде чем создавать собственный регистр сведений, проанализируем возможности типовой конфигурации. В современной БСП (Библиотеке стандартных подсистем), которая интегрирована в БП 3.0, уже существует мощный механизм отслеживания оригиналов.

Выясним, как использовать штатные средства:

  1. В пользовательском режиме проверьте: Администрирование — Печатные формы, отчеты и обработки — Состояние оригиналов первичных документов. Если эта опция включена, система сама добавит колонку в списки многих документов.
  2. Если документ ПеремещениеТоваров не входит в список поддерживаемых по умолчанию, его можно добавить через расширение, изменив ОпределяемыйТип.ОбъектСУчетомСостоянияОригиналаПервичногоДокумента.
  3. Нужно добавить ваш документ в этот тип в расширении. После этого система автоматически начнет отслеживать статусы для этого типа объектов, используя типовой регистр СостоянияОригиналовПервичныхДокументов.

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

Важные рекомендации по производительности

При добавлении колонок в динамические списки через ЛЕВОЕ СОЕДИНЕНИЕ, особенно в крупных базах, следует учитывать нагрузку на сервер СУБД. Рассмотрим несколько советов:

Таким образом, мы рассмотрели три основных способа решения задачи. Выбор конкретного метода зависит от ваших навыков работы с расширениями и необходимости следовать типовым стандартам разработки 1С.

← На главную