При разработке различных интерактивных обработок — таких как сетки расписания, шахматки занятости сотрудников, матрицы распределения ресурсов или динамические отчеты — разработчики часто сталкиваются с необходимостью динамически формировать структуру колонок в объекте ТаблицаЗначений. Попытка добавить колонку, используя произвольную строку (например, полное наименование или ФИО сотрудника), нередко приводит к исключительным ситуациям платформы.
Разберем детально, почему возникают ошибки «Неверное имя колонки» и «Поле объекта не обнаружено», как устроена работа с коллекцией колонок и какие правильные подходы существуют для реализации динамических колонок.
Рассмотрим типовой сценарий, в котором возникает ошибка. Разработчик выбирает запросом список сотрудников и пытается создать для каждого из них персональную колонку:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
Табличка.Колонки.Добавить(ВыборкаДетальныеЗаписи.Сотр);
КонецЦикла;
При выполнении этой строки платформа 1С:Предприятие генерирует исключение: «Ошибка при вызове метода контекста (Добавить) по причине: Неверное имя колонки».
Выясним причину такого поведения. Первый параметр метода Колонки.Добавить() — это Имя колонки, которое служит её программным идентификатором. К имени колонки предъявляются жесткие требования синтаксиса встроенного языка 1С:
_.Когда в метод передается строка вида "Иванов Иван Иванович", наличие пробелов нарушает правила синтаксиса идентификаторов, что и вызывает ошибку платформы.
Посмотрим на следующую распространенную ошибку при попытке обойти проблему:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
НоваяСтрока = Табличка.Добавить();
ИмяКолонки = Лев(ВыборкаДетальныеЗаписи.сотр, 4);
НоваяСтрока[ИмяКолонки] = " ";
КонецЦикла;
В этом фрагменте кода генерируется ошибка «Поле объекта не обнаружено». Проанализируем причину: разработчик пытается присвоить значение в строку таблицы через обращение по индексу НоваяСтрока[ИмяКолонки], однако сама колонка с таким именем в коллекцию Табличка.Колонки еще не была добавлена.
Изучим синтаксис метода добавления колонок в коллекцию КолонкиТаблицыЗначений:
Добавить(<Имя>, <Тип>, <Заголовок>, <Ширина>)
Для корректного отображения данных пользователю необходимо четко разделять:
Разберем несколько надежных способов генерации имен колонок.
Самый простой и надежный подход — формировать программное имя по счетчику колонок, а исходную строку передавать в заголовок:
Табличка = Новый ТаблицаЗначений;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Формируем валидный программный идентификатор: Колонка1, Колонка2 и т.д.
ИмяКолонки = "Колонка" + СокрЛП(Табличка.Колонки.Количество() + 1);
ЗаголовокКолонки = ВыборкаДетальныеЗаписи.Сотр;
// Добавляем колонку с указанием валидного имени и читаемого заголовка
Табличка.Колонки.Добавить(ИмяКолонки, Новый ОписаниеТипов("Строка"), ЗаголовокКолонки);
КонецЦикла;
Если в дальнейшем требуется сопоставлять колонку с конкретной ссылкой из базы данных (например, со справочником сотрудников), удобно включать в имя колонки уникальный код или идентификатор объекта:
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Добавляем префикс, чтобы имя не начиналось с цифры
ИмяКолонки = "Сотр_" + СокрЛП(ВыборкаДетальныеЗаписи.СотрудникКод);
ЗаголовокКолонки = ВыборкаДетальныеЗаписи.СотрудникНаименование;
Табличка.Колонки.Добавить(ИмяКолонки, , ЗаголовокКолонки);
КонецЦикла;
Если используется уникальный идентификатор ссылки УникальныйИдентификатор(), в нем содержатся дефисы, которые также являются недопустимыми символами в идентификаторах. В таком случае дефисы заменяются на символ подчеркивания:
ИдентификаторСтрокой = СтрЗаменить(Строка(ВыборкаДетальныеЗаписи.Сотрудник.УникальныйИдентификатор()), "-", "_");
ИмяКолонки = "Сотр_" + ИдентификаторСтрокой;
Табличка.Колонки.Добавить(ИмяКолонки, , ВыборкаДетальныеЗаписи.Сотрудник.Наименование);
Для оптимизации работы и предотвращения ошибок типизации рекомендуется явно задавать объект ОписаниеТипов при создании колонок. Рассмотрим пример создания колонок со строковым типом ограниченной длины:
Квалификаторы = Новый КвалификаторыСтроки(150);
ОписаниеТипаСтрока = Новый ОписаниеТипов("Строка", , Квалификаторы);
Табличка.Колонки.Добавить("Колонка1", ОписаниеТипаСтрока, "Иванов И.И.", 20);
В зависимости от типа используемых форм в 1С:Предприятии вывод динамических колонок имеет свои особенности:
ТаблицаЗначений необходимо вызвать перестроение колонок интерфейсного элемента:
ЭлементыФормы.Табличка.СоздатьКолонки();
ТаблицаЗначений на клиенте напрямую не отображается. Для создания динамической сетки на сервере управляемой формы используется связка методов ИзменитьРеквизиты() (для создания реквизитов формы) и Элементы.Добавить() (для создания визуальных полей таблицы формы с привязкой через ПутьКДанным).Если конечной целью является вывод расписания, бронирования или загрузки сотрудников по времени, создание шахматки на динамической ТаблицеЗначений — не единственный и зачастую не самый удобный инструмент. Рассмотрим специализированные штатные альтернативы:
Вывести() и Присоединить()), визуально оформлять границы и цвет ячеек, а также обрабатывать интерактивный клик пользователя через событие Выбор и параметр Расшифровка.