Список значений в 1С и дополнительная колонка: что можно сделать
Содержание
Вы открыли код, где есть СписокЗначений, и хотите добавить в него ещё одну колонку: код, сумму, комментарий. Не получится: у списка значений колонок нет, их состав зафиксирован платформой. Но задача решается просто, и ниже три рабочих способа, от самого быстрого до самого гибкого.
Короткий итог: если нужны дополнительные данные в каждой строке, берите ТаблицаЗначений и добавляйте колонки методом Колонки.Добавить(). Если список нужен только для выбора, положите в поле Значение структуру или соответствие.
Почему у списка значений нельзя добавить колонку
Элемент списка значений состоит из четырёх полей. Набор фиксирован, расширить его нельзя ни в коде, ни в конфигураторе.
| Поле | Что хранит |
|---|---|
Значение | Любое значение: строка, число, ссылка, структура |
Представление | Текст, который видит пользователь |
Пометка | Флажок (Булево) |
Картинка | Картинка из библиотеки картинок |
Поэтому запрос «добавить колонку в список значений» на практике означает одно из трёх:
- 📋 нужна таблица с несколькими полями в строке, а список выбрали по привычке;
- 🧩 нужно «прицепить» к элементу списка ещё один параметр, не меняя тип списка;
- 🖥 на форме нужна таблица, где состав колонок известен только во время работы.
Список значений хорош там, где нужен выбор из набора: выпадающий список, меню, отметка элементов флажками. Как только в строке больше двух смысловых полей, это уже таблица.
Чем заменить список значений: сравнение способов
| Способ | Когда подходит | Ограничения |
|---|---|---|
ТаблицаЗначений | Нужны именно колонки: код, сумма, дата | Не выпадающий список; для выбора нужно показать таблицу на форме |
Структура в Значение | Нужен список выбора, а к каждому пункту привязаны 1-2 параметра | Параметры не видны пользователю в списке |
Реквизит формы типа ТаблицаЗначений | Таблица должна быть на управляемой форме | Колонки создаются в конфигураторе или через ИзменитьРеквизиты |
Если сомневаетесь, начинайте с таблицы значений. Она закрывает большинство сценариев, а переделка списка в таблицу занимает несколько строк кода.
Способ 1. Колонка в таблице значений программно
Это основной путь. Таблица создаётся пустой, потом ей задаются колонки, потом заполняются строки.
Таб = Новый ТаблицаЗначений;
Таб.Колонки.Добавить("Код", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(10)));
Таб.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка"));
Таб.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Строка = Таб.Добавить();
Строка.Код = "00-001";
Строка.Наименование = "Договор поставки";
Строка.Сумма = 125000.50;
Метод Колонки.Добавить() принимает имя колонки, описание типов и заголовок (необязательный). Описание типов лучше задавать сразу: так колонка не станет «любой» и не наберёт мусорных значений.
⚠️ Имя колонки должно быть допустимым идентификатором: без пробелов и спецсимволов, не начинается с цифры. Для красивого названия на экране используйте третий параметр, заголовок.
Добавление колонки в уже заполненную таблицу
Колонку можно добавить и тогда, когда строки есть. Во всех существующих строках она получит пустое значение своего типа.
Таб.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка"));
Затем заполните значения циклом:
Для Каждого Строка Из Таб Цикл
Строка.Комментарий = "Проверено";
КонецЦикла;
Если колонка уже есть, повторное добавление с тем же именем вызовет ошибку. Проверяйте заранее: Таб.Колонки.Найти("Комментарий") = Неопределено.
Удаление и порядок колонок
Лишнюю колонку убирает Таб.Колонки.Удалить("Комментарий"). Порядок колонок в таблице определяется порядком добавления, а на форме его можно менять отдельно, уже в элементах.
Работа с новой колонкой: поиск, сортировка, итоги
Колонка нужна не сама по себе, а чтобы по ней что-то делать. Базовые операции с таблицей значений:
- 🔎
Таб.НайтиСтроки(Новый Структура("Код", "00-001"))возвращает массив строк, у которых в колонкеКодуказанное значение. Отбор можно делать по нескольким колонкам сразу. - ↕
Таб.Сортировать("Сумма Убыв")упорядочивает строки; по нескольким колонкам имена перечисляются через запятую. - ➕
Таб.Итог("Сумма")считает сумму по числовой колонке. - 🧮
Таб.Свернуть("Код", "Сумма")схлопывает строки с одинаковым кодом и суммирует числа. Первый параметр — колонки группировки, второй — колонки для суммирования. - ⚡
Таб.Индексы.Добавить("Код")ускоряет поиск по большой таблице: индекс строится по указанным колонкам.
Сортировка и свёртка меняют саму таблицу. Если исходный порядок нужен дальше, сначала сделайте копию: Копия = Таб.Скопировать().
Скопировать только структуру колонок
Бывает, что нужна пустая таблица с теми же колонками. Метод СкопироватьКолонки() создаёт её без строк:
Новая = Таб.СкопироватьКолонки();
Это удобно, когда вы разбиваете данные на группы и для каждой группы нужна таблица одинакового вида.
Загрузка и выгрузка целой колонки
Если значения колонки приходят массивом, их не нужно переносить циклом:
Коды = Новый Массив;
Коды.Добавить("00-001");
Коды.Добавить("00-002");
Таб.ЗагрузитьКолонку(Коды, "Код");
Метод заполняет колонку по порядку: первое значение массива идёт в первую строку и так далее. Количество строк таблицы и элементов массива лучше сверить заранее. Обратная операция, Таб.ВыгрузитьКолонку("Код"), отдаёт значения колонки массивом.
Пример из практики: список договоров с суммой
Допустим, нужно показать пользователю договоры контрагента и сумму по каждому, а потом получить выбранный. Список значений даёт только название, поэтому собираем таблицу: колонки Договор (тип — ссылка на справочник договоров) и Сумма, заполняем их из запроса и показываем на форме. Выбранную строку читаем через Элементы.Таблица.ТекущиеДанные.
Так пользователь видит обе колонки сразу, сортирует по сумме щелчком по шапке и не открывает каждый договор отдельно. Тот же результат через список значений пришлось бы собирать в одну строку представления, и сортировать по сумме стало бы нечем.
Способ 2. Превращаем готовый список значений в таблицу
Частый случай: список уже где-то собран, а колонки понадобились позже. Перенесите его в таблицу значений и добавьте нужные поля.
Таб = Новый ТаблицаЗначений;
Таб.Колонки.Добавить("Значение");
Таб.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Таб.Колонки.Добавить("Пометка", Новый ОписаниеТипов("Булево"));
Таб.Колонки.Добавить("Комментарий", Новый ОписаниеТипов("Строка"));
Для Каждого Элемент Из Список Цикл
Строка = Таб.Добавить();
Строка.Значение = Элемент.Значение;
Строка.Представление = Элемент.Представление;
Строка.Пометка = Элемент.Пометка;
КонецЦикла;
Колонка Значение без описания типов принимает значения любого типа, как и в списке. Новая колонка Комментарий добавлена от себя, остальные повторяют поля списка.
В обратную сторону работает метод ВыгрузитьЗначения(): он берёт одну колонку таблицы и выдаёт массив, который можно загрузить в список методом ЗагрузитьЗначения().
Способ 3. Дополнительный параметр внутри значения элемента
Если нужен именно выпадающий список или выбор из меню, колонку не добавляйте. Положите в Значение структуру: в ней может быть сколько угодно полей.
Список = Новый СписокЗначений;
Данные = Новый Структура;
Данные.Вставить("Код", "00-001");
Данные.Вставить("Сумма", 125000.50);
Список.Добавить(Данные, "Договор поставки");
Пользователь видит «Договор поставки», а код читает остальное:
Выбранный = Список.ВыбратьЭлемент();
Если Выбранный <> Неопределено Тогда
Сообщить(Выбранный.Значение.Код);
КонецЕсли;
Метод ВыбратьЭлемент() показывает список в диалоге. Если пользователь закрыл окно без выбора, вернётся Неопределено, поэтому проверка нужна.
⚠️ Структура — ссылочный объект в памяти. Если вы положите одну и ту же структуру в два элемента, изменение в одном отразится и в другом. Создавайте новую структуру на каждый элемент.
Когда значений-параметров всего два-три, такой способ проще таблицы: не нужен отдельный реквизит формы и колонки на экране.
Когда структуры недостаточно
Структура в значении элемента удобна, пока параметров мало и они нужны только коду. Выбирайте таблицу значений, если выполняется хотя бы одно условие:
- пользователь должен видеть дополнительные поля на экране;
- по этим полям нужна сортировка, отбор или итоги;
- строк много, и важна скорость поиска (у списка значений индексов нет, у таблицы они есть);
- данные нужно выгрузить в табличный документ или передать в запрос как временную таблицу.
Соответствие (Соответствие) годится, если параметры привязаны к ключу и порядок не важен. Но в список значений его кладут реже: структура читается понятнее, к полям обращаются по имени через точку.
Способ 4. Колонка в таблице на управляемой форме
На форме список значений показывается как реквизит типа СписокЗначений, и колонок у него тоже нет. Для таблицы с колонками создайте реквизит типа ТаблицаЗначений.
Через конфигуратор
- Откройте форму в конфигураторе и перейдите на закладку «Реквизиты».
- Добавьте реквизит, укажите тип
ТаблицаЗначений. - Правой кнопкой по реквизиту выберите добавление колонки, задайте имя и тип.
- Перетащите реквизит или его колонки в дерево элементов формы, чтобы они появились на экране.
Колонки задаются один раз, и состав их фиксирован на этапе разработки.
Динамически, во время работы
Если состав колонок зависит от данных (например, по числу месяцев в периоде), используйте метод формы ИзменитьРеквизиты() и работайте с элементами формы. Метод выполняется на сервере.
&НаСервере
Процедура ДобавитьКолонкуНаСервере()
Реквизиты = Новый Массив;
Реквизиты.Добавить(Новый РеквизитФормы("Комментарий",
Новый ОписаниеТипов("Строка"), "Таблица", "Комментарий"));
ИзменитьРеквизиты(Реквизиты);
Поле = Элементы.Добавить("ТаблицаКомментарий", Тип("ПолеФормы"), Элементы.Таблица);
Поле.Вид = ВидПоляФормы.ПолеВвода;
Поле.ПутьКДанным = "Таблица.Комментарий";
КонецПроцедуры
Здесь Таблица — имя реквизита формы с типом ТаблицаЗначений. Третий параметр РеквизитФормы указывает путь к родителю, то есть колонка добавляется именно в эту таблицу.
⚠️ Вызов ИзменитьРеквизиты() перестраивает форму: уже введённые, но не записанные данные в динамических реквизитах пропадают. Сначала сохраните нужное в переменную, потом меняйте состав.
Заголовок колонки на форме
Имя колонки в коде и подпись на экране можно разделить. В конфигураторе у колонки реквизита есть свойство «Заголовок»: пишите там обычный человеческий текст («Сумма договора»), а в имени оставляйте короткий идентификатор. В динамическом варианте заголовок задаётся четвёртым параметром РеквизитФормы, как в примере выше.
Тот же приём работает и в коде: третий параметр Колонки.Добавить() задаёт заголовок, и он попадает в шапку, когда таблицу показывают пользователю.
Расширения: что они дают, а что нет
В запросах встречается вариант «через расширения». Расширение конфигурации
(платформа 8.3.6 и новее) не умеет добавить колонку в СписокЗначений: тип остаётся прежним. Но оно может сделать смежное:
- ➕ добавить реквизит
типа
ТаблицаЗначенийна существующую форму типовой конфигурации и вывести его колонки; - 🔁 перехватить процедуру формы и дополнить таблицу своей колонкой;
- 🧱 добавить в справочник табличную часть с нужными полями.
После загрузки файла .cfe отдельным шагом выполняется «Обновить конфигурацию
базы данных»: без этого новые реквизиты в базе не появятся.
Типичные ошибки
| Симптом | Причина | Что сделать |
|---|---|---|
| «Поле объекта не обнаружено» | Колонка не создана или в имени опечатка | Проверьте Таб.Колонки и написание имени |
| Колонка есть в коде, но не видна на форме | Не создано поле формы | Добавьте элемент и укажите ПутьКДанным |
| Число превращается в строку | Описание типов не задано | Укажите ОписаниеТипов("Число", ...) |
| В списке выбора видна «Структура» | Пользователю показано Значение, а не Представление | Передавайте второй параметр в Добавить() |
| Данные пропали после добавления колонки на форме | Сработал ИзменитьРеквизиты() | Сохраните данные до вызова и загрузите обратно |
Не склеивайте число со строкой напрямую. Для вывода используйте Формат(Сумма, "ЧДЦ=2") или СтрШаблон("Сумма: %1", Сумма).
Частые вопросы
Можно ли добавить колонку в список значений через конфигуратор?
Чем таблица значений отличается от списка значений?
Как передать в список значений несколько параметров?
Значение структуру с нужными полями и задайте текст для пользователя в Представление.Как вывести таблицу значений на форму?
ТаблицаЗначений, добавьте колонки и перетащите реквизит в элементы формы.Можно ли поменять тип колонки уже созданной таблицы?
Как узнать, есть ли в таблице нужная колонка?
Таб.Колонки.Найти("Имя"): если вернулся Неопределено, колонки нет.