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