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