В процессе разработки в системе 1С:Предприятие часто возникает задача программного анализа данных в табличной части документа или справочника. Одной из типичных ошибок начинающих разработчиков является попытка сравнения значения типа Перечисление с обычной текстовой строкой. Разберем подробно, почему так происходит, и как правильно реализовать эту логику в управляемом приложении.
Рассмотрим ситуацию: в табличной части документа есть колонка ВидРезки с типом данных ПеречислениеСсылка.ВидыРезки. Разработчик пытается написать код:
Если ТекущаяСтрока.ВидРезки = "Ангар" Тогда ... КонецЕсли;
Проанализируем причину неудачи: тип данных Перечисление в 1С является ссылочным типом, а не строковым. В базе данных хранится ссылка на конкретный объект метаданных, а не текст, который видит пользователь в интерфейсе. Следовательно, сравнение ссылки со строкой "Ангар" всегда будет возвращать значение Ложь, так как это принципиально разные типы данных. Чтобы код заработал, нам необходимо сравнить значение в таблице с конкретным программным идентификатором этого перечисления.
Наиболее универсальный способ обращения к значениям перечислений, который работает как на клиенте, так и на сервере, — это использование встроенной функции ПредопределенноеЗначение(). Эта функция принимает в качестве аргумента строковое имя объекта метаданных и возвращает ссылку на него.
Разберем по шагам правильный синтаксис:
&НаКлиенте
Процедура ТабличнаяЧасть1ВидРезкиПриИзменении(Элемент)
ТекущаяСтрока = Элементы.ТабличнаяЧасть1.ТекущиеДанные;
Если ТекущаяСтрока.ВидРезки = ПредопределенноеЗначение("Перечисление.ВидыРезки.Ангар") Тогда
ТекущаяСтрока.СуммаРезки = 14;
Иначе
ПоказатьОповещениеПользователя("Выбран другой вид резки");
КонецЕсли;
КонецПроцедуры
Обратите внимание: внутри кавычек указывается путь в формате "Перечисление.ИмяПеречисленияВКонфигураторе.ИмяЗначения". Важно не допускать опечаток в написании имен, иначе система выдаст ошибку во время выполнения кода.
Если ваша логика выполняется в серверном контексте (например, в процедуре &НаСервере или в модуле объекта), вы можете обращаться к перечислениям напрямую через точку. Это более удобный способ, так как конфигуратор поддерживает контекстную подсказку (Ctrl+Space).
Проанализируем пример серверного кода:
&НаСервере
Процедура РассчитатьСуммуНаСервере()
Для Каждого СтрокаТЧ Из Объект.ТабличнаяЧасть1 Цикл
Если СтрокаТЧ.ВидРезки = Перечисления.ВидыРезки.Ангар Тогда
СтрокаТЧ.СуммаРезки = 14;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Использование конструкции Перечисления.Имя.Значение работает быстрее и позволяет избежать ошибок в написании строкового параметра, так как платформа проверяет существование такого значения еще на этапе компиляции.
Посмотрим на частую ошибку в логике обработки событий. Часто разработчики используют цикл Для Каждого внутри события ПриИзменении конкретной строки. Это приводит к тому, что при изменении одной строки система заново пересчитывает всю таблицу. Если в документе будут сотни строк, это вызовет заметные задержки («фризы») интерфейса.
Выясним причину, почему лучше использовать ТекущиеДанные:
Для получения доступа к редактируемой строке используйте конструкцию:
ТекущаяСтрока = Элементы.ИмяВашейТаблицы.ТекущиеДанные;
Как справедливо отмечают опытные разработчики, записывать конкретные значения (например, цену «14») прямо в программном коде — это плохая практика, называемая «hardcoding». Если завтра цена изменится, вам придется открывать конфигуратор, править код и заново выпускать обновление базы данных.
Рассмотрим более профессиональные варианты решения задачи:
Рано или поздно вам потребуется использовать перечисления не только в коде формы, но и в запросах (например, при формировании отчета или поиске данных). В языке запросов 1С синтаксис отличается.
Рассмотрим пример условия в запросе:
ВЫБРАТЬ
Продажи.Номенклатура,
Продажи.Сумма
ИЗ
РегистрНакопления.Продажи КАК Продажи
ГДЕ
Продажи.ВидОперации = ЗНАЧЕНИЕ(Перечисление.ВидыОпераций.Продажа)
Здесь используется ключевое слово ЗНАЧЕНИЕ(), которое позволяет обратиться к предопределенному объекту базы данных напрямую внутри текста запроса без использования параметров.
Подведем итоги нашего анализа:
ПредопределенноеЗначение("Перечисление.Имя.Значение").Перечисления.Имя.Значение.ЗНАЧЕНИЕ(Перечисление.Имя.Значение).ТекущиеДанные вместо обхода всей таблицы в цикле.Соблюдение этих простых правил сделает ваш код надежным, быстрым и устойчивым к ошибкам при обновлении конфигурации.