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