При разработке механизмов загрузки данных из внешних файлов, таких как Microsoft Excel, программисты часто сталкиваются с задачей динамического построения интерфейса. Мы создаем таблицу значений, наполняем ее данными и хотим, чтобы пользователь видел в шапке таблицы ровно те же названия, что и в исходном файле. Однако возникает проблема: 1С «съедает» пробелы в названиях колонок. В этой статье мы разберем, почему это происходит, и как правильно настроить программное создание реквизитов, чтобы сохранить читаемость интерфейса.
Прежде всего, давайте проанализируем ситуацию с точки зрения архитектуры платформы 1С. Любой объект метаданных или программно созданный реквизит имеет два ключевых строковых свойства: Имя и Заголовок. Разберем их различия подробнее:
Проблема в коде автора из сообщения заключается в том, что при создании реквизита и элемента формы используется только имя, полученное напрямую из первой строки Excel, которое платформа вынуждена «нормализовать», удаляя пробелы.
Рассмотрим подробнее метод ИзменитьРеквизиты. Это мощный инструмент управляемых форм, который позволяет «на лету» добавлять колонки в таблицу. Для того чтобы сохранить пробелы, нам нужно четко разделить создание внутреннего идентификатора и внешнего описания.
Посмотрим на пример того, как должен выглядеть процесс подготовки массива реквизитов. Вместо того чтобы просто передавать имя колонки, мы будем формировать объект РеквизитФормы, используя расширенный набор параметров. Конструктор выглядит так: Новый РеквизитФормы(<Имя>, <Тип>, <Путь>, <Заголовок>).
Проанализируем исправленный цикл создания реквизитов:
// Предположим, что в переменной "ТекстИзExcel" хранится строка "Цена за еду"
Для Каждого Колонка Из Таблица.Колонки Цикл
// 1. Формируем безопасное имя (убираем пробелы)
ИмяБезПробелов = СтрЗаменить(Колонка.Имя, " ", "");
// 2. В четвертом параметре передаем оригинальный текст с пробелами как Заголовок
НовыйРеквизит = Новый РеквизитФормы(ИмяБезПробелов, Колонка.ТипЗначения, "ТаблицаТоваров", Колонка.Имя);
МассивРеквизитов.Добавить(НовыйРеквизит);
КонецЦикла;
После того как реквизиты добавлены в структуру формы с помощью метода ИзменитьРеквизиты, нам необходимо отобразить их визуально. Здесь мы используем коллекцию Элементы и метод Добавить. Важно понимать, что элемент формы (тип ПолеФормы) также имеет свойство Заголовок, которое по умолчанию может подтягиваться из реквизита, но для надежности его стоит установить явно.
Рассмотрим по шагам, как правильно добавить визуальные колонки в таблицу на форме:
Для Каждого Колонка Из Таблица.Колонки Цикл
// Генерируем то же самое имя без пробелов для связи
ИмяБезПробелов = СтрЗаменить(Колонка.Имя, " ", "");
// Добавляем элемент на форму
НовыйЭлемент = Элементы.Добавить(ИмяБезПробелов, Тип("ПолеФормы"), ТаблицаПолейВыбора);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
// Указываем путь к данным, который мы создали ранее
НовыйЭлемент.ПутьКДанным = "ТаблицаТоваров." + ИмяБезПробелов;
// Устанавливаем заголовок, который будет содержать пробелы
НовыйЭлемент.Заголовок = Колонка.Имя;
НовыйЭлемент.Ширина = 10;
КонецЦикла;
Выясним причину, по которой данные могут теряться еще на этапе чтения. Если вы используете COM-объект Excel.Application, то при чтении ячейки через Cells(1, i).Value вы получаете «чистую» строку. Если же используется чтение через ADO (как к базе данных), драйвер может самостоятельно заменять пробелы в именах полей на символы решетки #.
Поэтому мы рекомендуем использовать современный объект 1С ТабличныйДокумент. Он позволяет прочитать файл Excel напрямую и получить доступ к каждой ячейке как к объекту, сохраняя все форматирование и символы.
Рассмотрим пример правильного получения заголовков из ТабличногоДокумента:
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
// Допустим, заголовки в первой строке
Для НомерКолонки = 1 По ТабДок.ШиринаТаблицы Цикл
ТекстЗаголовка = ТабДок.Область(1, НомерКолонки).Текст;
// Теперь ТекстЗаголовка содержит пробелы, и мы можем использовать его
// для создания Заголовка колонки, как описано выше.
КонецЦикла;
Соберем все наши знания в единый алгоритм работы. Проанализируем комплексный код, который решает задачу «под ключ»:
&НаСервере
Процедура ЗагрузитьКолонкиИзТаблицы(ТаблицаДанных)
// 1. Очистка старых колонок
МассивУдаления = Новый Массив;
Для Каждого Реквизит Из ЭтаФорма.ПолучитьРеквизиты("ТаблицаТоваров") Цикл
МассивУдаления.Добавить("ТаблицаТоваров." + Реквизит.Имя);
КонецЦикла;
// 2. Подготовка новых реквизитов
МассивДобавления = Новый Массив;
Для Каждого Кол Из ТаблицаДанных.Колонки Цикл
// Создаем программное имя без спецсимволов
ПрограммноеИмя = "Кол_" + СтрЗаменить(Кол.Имя, " ", "_");
// 4-й параметр — это Заголовок с пробелами!
НовыйРеквизит = Новый РеквизитФормы(ПрограммноеИмя, Кол.ТипЗначения, "ТаблицаТоваров", Кол.Имя);
МассивДобавления.Добавить(НовыйРеквизит);
КонецЦикла;
// Применяем изменения структуры
ИзменитьРеквизиты(МассивДобавления, МассивУдаления);
// 3. Создание визуальных элементов
Для Каждого Кол Из ТаблицаДанных.Колонки Цикл
ПрограммноеИмя = "Кол_" + СтрЗаменить(Кол.Имя, " ", "_");
НовыйЭлемент = Элементы.Добавить(ПрограммноеИмя, Тип("ПолеФормы"), Элементы.ТаблицаТоваров);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "ТаблицаТоваров." + ПрограммноеИмя;
// Установка заголовка для пользователя
НовыйЭлемент.Заголовок = Кол.Имя;
КонецЦикла;
// 4. Загрузка данных
ЗначениеВРеквизитФормы(ТаблицаДанных, "ТаблицаТоваров");
КонецПроцедуры
Важный момент: Обратите внимание, что при создании ПрограммноеИмя мы добавили префикс Кол_. Это хорошая практика, так как заголовок в Excel может начинаться с цифры (например, «2023 год»), что недопустимо для имени реквизита в 1С. Префикс гарантирует, что имя всегда будет валидным идентификатором.
Таким образом, разделяя логику именования переменных в коде и логику отображения текстов для пользователя, мы получаем гибкий и отказоустойчивый интерфейс, который корректно обрабатывает любые данные из Excel.