В разработке на платформе 1С:Предприятие 8.3 часто возникает задача отобразить данные в виде сложной иерархии, которая включает не только реквизиты объекта (например, справочника), но и строки его табличных частей. Типичный пример: отображение списка номенклатуры с группировкой по производителю, классу и вложенным списком материалов. На первый взгляд, решение кажется очевидным — использовать динамический список с произвольным запросом. Однако при реализации программисты часто сталкиваются с ошибкой «Некорректное использование поля Ссылка». В этой статье мы подробно разберем, почему возникает эта проблема и как ее правильно решить несколькими способами.
Рассмотрим стандартную ситуацию. Мы создаем динамический список и пишем в нем запрос с использованием ЛЕВОЕ СОЕДИНЕНИЕ основной таблицы справочника с его табличной частью. Запрос выглядит примерно так:
ВЫБРАТЬ
СправочникНоменклатура.Производитель КАК Производитель,
СправочникНоменклатура.Класс КАК Класс,
СправочникНоменклатура.Ссылка КАК Номенклатура,
НоменклатураТЧ.Материал КАК Материал
ИЗ
Справочник.Номенклатура КАК СправочникНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ
Справочник.Номенклатура.Комплектующие КАК НоменклатураТЧ
ПО
СправочникНоменклатура.Ссылка = НоменклатураТЧ.Ссылка
Проблема заключается в свойстве «Основная таблица» динамического списка. Когда в этом свойстве указан справочник (например, Справочник.Номенклатура), платформа ожидает, что поле Ссылка будет уникальным идентификатором строки. Однако при соединении с табличной частью одна и та же ссылка дублируется столько раз, сколько строк содержится в ТЧ для данной номенклатуры. Как только мы пытаемся включить группировку в настройках списка, механизм динамического считывания данных (Dynamic Data Read) «теряется», не понимая, какую именно физическую строку данных открывать или изменять. Это и приводит к ошибке некорректного использования поля Ссылка.
Важно помнить: использование конструкции ИТОГИ ПО в тексте запроса динамического списка категорически запрещено синтаксисом платформы. Все группировки должны настраиваться исключительно через механизмы компоновки данных (вкладка «Настройки» в конфигураторе или через «Еще — Настроить список» в режиме пользователя).
Первый и самый простой способ заставить такой список работать — очистить поле «Основная таблица» в свойствах динамического списка. Разберем этот процесс по шагам:
Производитель -> Класс -> Ссылка -> Материал.Важное предостережение: при отказе от основной таблицы вы теряете стандартный функционал платформы. В списке перестанут работать стандартные кнопки «Создать», «Скопировать», «Изменить», а также контекстное меню для управления пометкой удаления. Вам придется реализовывать эти команды программно, используя методы ОткрытьФорму() или стандартные обработчики команд.
Если нам критически важно сохранить динамический список, но данные дублируются, мы можем попытаться обмануть систему, предоставив ей уникальный ключ для каждой строки. В последних версиях платформы 8.3 в динамическом списке можно явно указать поля, которые составляют ключ. Проанализируем ситуацию: если мы соединяем номенклатуру с материалами, то уникальной связкой будет Ссылка + НомерСтрокиТЧ.
Добавим в запрос выбор номера строки из табличной части:
ВЫБРАТЬ
СправочникНоменклатура.Ссылка КАК Ссылка,
НоменклатураТЧ.НомерСтроки КАК НомерСтрокиТЧ,
СправочникНоменклатура.Производитель,
НоменклатураТЧ.Материал
ИЗ
Справочник.Номенклатура КАК СправочникНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ
Справочник.Номенклатура.Комплектующие КАК НоменклатураТЧ
ПО
СправочникНоменклатура.Ссылка = НоменклатураТЧ.Ссылка
В настройках списка (вкладка «Данные») укажите в качестве Ключа основной таблицы оба этих поля. Это позволит платформе однозначно идентифицировать каждую строку «Справочник + Строка ТЧ», и ошибка группировки исчезнет.
Проанализируем альтернативный вариант. Если иерархия «Производитель — Класс — Номенклатура — Материал» должна быть жесткой и объем данных в справочнике невелик (до нескольких тысяч записей), лучшим решением будет использование объекта ДеревоЗначений вместо динамического списка.
Преимущества дерева значений:
Недостатки: данные загружаются в память целиком. Если у вас справочник на 100 000 позиций, форма будет открываться очень долго. В этом случае дерево значений использовать нельзя.
Профессиональный подход к интерфейсу часто подразумевает разделение данных. Вместо того чтобы пытаться «засунуть» табличную часть в иерархию основного списка, рассмотрим реализацию схемы «Ведущий — Ведомый»:
ПриАктивизацииСтроки первого списка устанавливаем отбор для второго списка по текущей ссылке.Это обеспечит максимальную производительность, так как платформа будет использовать стандартные индексы и механизмы динамического считывания без сложных соединений (Join), которые нагружают СУБД.
Часто возникает вопрос: почему группировка всегда отображается в первой колонке, даже если само поле находится в середине таблицы? Это стандартное поведение платформы 1С для управляемых форм. Текст группировки и значок «плюс/минус» (развертывание) всегда привязаны к первой видимой колонке.
Чтобы визуально «переместить» группировку, можно применить следующие хитрости:
Выясним причину, по которой группировка «обрезается»: если первая колонка имеет фиксированную малую ширину (например, колонка с картинкой или номером), текст группировки просто не поместится. Рекомендуется делать первую колонку достаточно широкой или использовать в ней поле, содержащее наименование объекта.
Подводя итог, можно сказать: динамический список — мощный инструмент, но он имеет свои границы. Для простых группировок по реквизитам он идеален. Для вывода данных табличных частей лучше использовать либо связанные списки, либо дерево значений, тщательно взвешивая объем данных и требования к производительности.