При использовании стандартных или самописных обработок для загрузки данных из Excel в 1С разработчики часто сталкиваются с проблемой заполнения реквизитов, имеющих тип ПеречислениеСсылка. В отличие от простых строковых или числовых данных, перечисление — это жестко заданный в конфигураторе список значений. Просто передать текст «Мужской» в такое поле не получится, так как система ожидает ссылку на конкретный объект метаданных.
В данной статье мы разберем несколько эффективных способов решения этой задачи, проанализируем типичные ошибки и выясним, как сделать процесс загрузки максимально надежным.
Разберем ситуацию: в файле Excel в колонке «Пол» указано значение «Мужской». В конфигурации 1С существует перечисление ПолФизическихЛиц со значениями Мужской и Женский. Когда обработка считывает ячейку, она получает строку. Попытка напрямую присвоить строку ссылочному типу приводит к тому, что поле остается пустым или возникает ошибка несоответствия типов. Нам необходимо «объяснить» системе, какому именно значению перечисления соответствует данный текст или индекс.
Самый простой с точки зрения кода способ — использование индекса значения. В 1С значения перечисления имеют внутренний порядок, начинающийся с нуля. Например:
Если в вашем файле Excel вместо текста проставлены соответствующие цифры, мы можем использовать вычисляемое выражение. Проанализируем пример кода для обработки:
// В ячейке Excel указано число 0 или 1
Результат = Перечисления.ПолФизическихЛиц[Число(ТекстЯчейки)];
Важный нюанс: использование метода Число() обязательно, так как данные из ТекстЯчейки часто приходят в строковом формате. Если передать строку в квадратные скобки коллекции, система будет искать значение по Имени (идентификатору), а не по индексу, что приведет к ошибке «Поле объекта не обнаружено».
Как было отмечено в обсуждении на форуме, метод Получить() является альтернативой прямому обращению через квадратные скобки. Он также работает с числовым индексом.
Результат = Перечисления.ПолФизическихЛиц.Получить(Число(ТекстЯчейки));
Этот метод возвращает ссылку на значение перечисления по его порядковому номеру. Рассмотрим ситуацию, когда индекс может быть некорректным. Чтобы избежать аварийного завершения загрузки, рекомендуется добавить проверку:
ПорядковыйНомер = Число(ТекстЯчейки);
Если ПорядковыйНомер < Перечисления.ПолФизическихЛиц.Количество() Тогда
Результат = Перечисления.ПолФизическихЛиц.Получить(ПорядковыйНомер);
Иначе
Результат = Перечисления.ПолФизическихЛиц.ПустаяСсылка();
КонецЕсли;
Чаще всего в файлах Excel содержатся именно текстовые представления («Мужской», «Женский»), а не индексы. В этом случае использовать индексы неудобно. Рассмотрим, как прописать условие в вычисляемом выражении:
ТекстДляПроверки = СокрЛП(ТекстЯчейки);
Результат = ?(ТекстДляПроверки = "Мужской", Перечисления.ПолФизическихЛиц.Мужской, Перечисления.ПолФизическихЛиц.Женский);
Здесь мы используем тернарный оператор ?(). Метод СокрЛП() крайне важен, так как в Excel часто встречаются невидимые пробелы в конце строки, которые могут нарушить сравнение. Также стоит помнить о регистре символов.
Если перечисление содержит много значений (например, статусы заказов или виды документов), писать вложенные условия Если...ИначеЕсли нерационально. Рассмотрим более продвинутый способ: динамический поиск соответствия в метаданных. Мы можем перебрать все значения перечисления и сравнить их синонимы с текстом из файла.
ТекстИзФайла = СокрЛП(ТекстЯчейки);
Результат = Перечисления.ПолФизическихЛиц.ПустаяСсылка();
Для Каждого ЗначениеМетаданных Из Метаданные.Перечисления.ПолФизическихЛиц.ЗначенияПеречисления Цикл
Если ЗначениеМетаданных.Синоним = ТекстИзФайла Тогда
// Находим имя значения и получаем ссылку по имени через коллекцию
Результат = Перечисления.ПолФизическихЛиц[ЗначениеМетаданных.Имя];
Прервать;
КонецЕсли;
КонецЦикла;
Этот программный код позволяет сделать загрузку независимой от порядка значений в конфигураторе. Даже если программист добавит новое значение в середину списка, логика загрузки не сломается, в отличие от способа с индексами (0, 1, 2...).
Если в Excel записаны технические имена (идентификаторы), которые заданы в конфигураторе (например, Muzhskoy), то задача упрощается до одной строки:
Результат = Перечисления.ПолФизическихЛиц[СокрЛП(ТекстЯчейки)];
Однако помните: Имя и Синоним — это разные вещи. Имя пишется без пробелов и обычно латиницей (хотя в 1С разрешена кириллица в именах), а Синоним — это то, что видит пользователь в интерфейсе. Для загрузки из файлов, подготовленных обычными пользователями, этот способ подходит редко.
Проанализируем основные правила, которые помогут избежать ошибок при импорте данных:
СокрЛП(). Пробел в начале или конце ячейки Excel — самая частая причина того, что 1С «не видит» значение.Число("") вызовет ошибку. Используйте конструкцию ПустаяСтрока(ТекстЯчейки).ВРег() (приведение к верхнему регистру), чтобы «мужской», «Мужской» и «МУЖСКОЙ» воспринимались системой одинаково.Выясним, какой метод лучше. Если вы делаете разовую загрузку и полностью контролируете файл — индексы (Способ 1) подойдут идеально. Если вы разрабатываете инструмент для постоянного использования бухгалтерией — используйте поиск по синониму (Способ 4), так как он наиболее дружелюбен к пользователю и устойчив к изменениям в структуре базы данных.