В процессе разработки на платформе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда код, успешно работающий в файловой базе под администратором, начинает выдавать ошибки при появлении пользователей или в клиент-серверном режиме. Типичный пример — ошибка «Значение не является значением объектного типа (Ссылка)» в обработчике события динамического списка. Давайте подробно проанализируем причины возникновения этой проблемы и разберем по шагам, как правильно реализовать передачу параметров в динамический список при активации строки.
Рассмотрим ситуацию: у нас есть форма списка, в которой при выборе строки (активизации) должен обновляться другой список или выполняться какой-либо расчет на основе выбранного значения. Код автора выглядит следующим образом:
Процедура СписокПриАктивизацииСтроки(Элемент)
Список.Параметры.УстановитьЗначениеПараметра("П", Элементы.Список1.ТекущиеДанные.Ссылка);
КонецПроцедуры
Ошибка возникает потому, что в определенные моменты (например, при открытии формы, при обновлении данных или когда список пуст) свойство ТекущиеДанные элемента формы Таблица принимает значение Неопределено. Попытка обратиться к свойству .Ссылка у значения Неопределено и приводит к аварийному завершению программы. Почему это проявляется при создании пользователей? Дело в том, что механизмы проверки прав доступа (RLS) и инициализация интерфейса могут происходить с небольшими задержками по сравнению с работой под полными правами «без пользователей», что делает момент отсутствия текущих данных более явным.
Проанализируем первый и самый важный шаг исправления — внедрение защитного программирования. Прежде чем обращаться к свойствам текущей строки, мы должны убедиться, что строка действительно существует и выбрана. Рассмотрим правильный вариант написания процедуры СписокПриАктивизацииСтроки:
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
// Получаем текущие данные один раз, чтобы избежать лишних обращений
ТекущиеДанные = Элементы.Список1.ТекущиеДанные;
// Проверяем, не пустая ли строка
Если ТекущиеДанные = Неопределено Тогда
Возврат;
КонецЕсли;
// Теперь обращение к .Ссылка безопасно
Список.Параметры.УстановитьЗначениеПараметра("П", ТекущиеДанные.Ссылка);
КонецПроцедуры
Важный нюанс: Событие ПриАктивизацииСтроки вызывается платформой очень часто. Мы рекомендуем всегда добавлять проверку на Неопределено, чтобы избежать «падения» интерфейса при поиске, фильтрации или очистке списка пользователем.
Иногда даже при наличии строки обращение к ТекущиеДанные.Ссылка может вернуть ошибку или пустое значение. Разберем, почему так происходит. Платформа 1С оптимизирует запросы динамического списка и получает из базы данных только те поля, которые визуально отображены в колонках таблицы на форме. Если вы используете поле Ссылка в коде, но удалили его из видимых колонок, платформа может исключить его из выборки на клиенте.
Чтобы гарантировать наличие данных в ТекущиеДанные, выполним следующие действия:
Ссылка.После этого поле будет принудительно считываться из базы данных независимо от его видимости в интерфейсе.
Рассмотрим вторую ошибку, с которой столкнулся автор: «Не задано значение параметра "П"». Эта проблема возникает при инициализации формы. Динамический список начинает выполнять запрос сразу после создания, еще до того, как пользователь успеет нажать на какую-либо строку и сработает событие ПриАктивизацииСтроки. Если в тексте запроса указано условие ГДЕ ... В (&П), параметр &П должен быть определен заранее.
Посмотрим, как правильно инициализировать параметры на сервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Устанавливаем пустое значение по умолчанию, чтобы запрос не выдавал ошибку
// Если используется оператор "В", лучше передать пустой массив
ПустойМассив = Новый Массив;
Список.Параметры.УстановитьЗначениеПараметра("П", ПустойМассив);
КонецПроцедуры
Проанализируем текст запроса, который использовал автор: ГДЕ СправочникСотрудники.Подразделение В (&П). В языке запросов 1С оператор В ожидает массив, таблицу значений или результат вложенного запроса. Хотя платформа часто «прощает» передачу одиночной ссылки вместо массива, преобразуя условие в «равно», правильным подходом будет использование массива.
Изменим наш клиентский код для работы с массивом:
&НаКлиенте
Процедура СписокПриАктивизацииСтроки(Элемент)
ТекущиеДанные = Элементы.Список1.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
// Оборачиваем ссылку в массив для корректной работы оператора "В"
МассивПараметров = Новый Массив;
МассивПараметров.Добавить(ТекущиеДанные.Ссылка);
Список.Параметры.УстановитьЗначениеПараметра("П", МассивПараметров);
КонецЕсли;
КонецПроцедуры
Для стабильной работы динамического списка при взаимодействии с другими элементами формы необходимо придерживаться следующих правил:
ТекущиеДанные на Неопределено перед обращением к свойствам строки.ПриСозданииНаСервере, передавая в них пустые значения или значения по умолчанию.В, в параметр следует передавать Массив.Соблюдение этих рекомендаций позволит избежать ошибок объектного типа и обеспечит корректную работу программы в любых режимах запуска и при любых настройках прав доступа пользователей.