Как обратиться к ячейке табличной части и ограничить её редактирование в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке интерфейсов на управляемых формах в 1С 8.3 часто возникает задача обратиться к конкретной ячейке табличной части — например, чтобы проверить значение реквизита и запретить или разрешить редактирование цены для определенной строки. Однако попытки сделать это «в лоб» часто приводят к ошибкам вроде «Получение элемента по индексу для значения не определено» или «Значение не является значением объектного типа». Проанализируем, почему возникают эти ошибки, как правильно получать данные активной строки и как грамотно настроить запрет редактирования отдельных ячеек.

Основные ошибки при обращении к ячейкам и строкам

Рассмотрим частые промахи при попытке получить данные ячейки из элементов формы:

  1. Обращение к элементу формы как к массиву: конструкция Элементы.Товары[НомерСтроки] вызовет ошибку, так как Элементы.Товары — это элемент управления (таблица формы), а не коллекция данных. Обращаться по индексу нужно к объекту данных, например: Объект.Товары[НомерСтроки - 1] (учитывая, что индексация в коллекциях 1С начинается с 0).
  2. Использование идентификатора строки вместо индекса: свойство Элементы.Товары.ТекущаяСтрока возвращает числовой идентификатор строки, а не её порядковый номер в таблице. Для поиска строки по этому идентификатору в объекте используется метод НайтиПоИдентификатору().
  3. Обращение к отсутствующему полю в ТекущиеДанные: вызов Элементы.Товары.ТекущиеДанные.Код вернет ошибку, если колонка на форме является текстовой надписью или реквизитом, который не выгружен в состав колонок коллекции ТекущиеДанные.

Как правильно получить данные текущей строки на клиенте

Чтобы получить значение реквизита (например, ссылки на номенклатуру или её кода) из выделенной строки таблицы, используют свойство элемента таблицы ТекущиеДанные. Если реквизит Номенклатура добавлен в табличную часть, мы можем обратиться к нему напрямую:


&НаКлиенте
Процедура ТоварыПриАктивизацииЯчейки(Элемент)
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Получаем ссылку на номенклатуру из текущей строки
    НоменклатураСсылка = ТекущиеДанные.Номенклатура;
КонецПроцедуры

Если требуется получить реквизит ссылочного объекта (например, код номенклатуры), обращение к нему на клиенте через точку может вызвать обращение к серверу. Если вызывать серверную функцию необходимо, используйте директиву &НаСервереБезКонтекста, чтобы не передавать всю форму целиком и не замедлять работу интерфейса:


&НаСервереБезКонтекста
Функция ПолучитьКодТовара(Ссылка)
    Возврат Ссылка.Код;
КонецФункции

Однако лучшим решением для получения кода без лишних вызовов сервера является добавление реквизита Объект.Товары.Номенклатура.Код прямо в состав колонок таблицы формы в конфигураторе. В этом случае платформой будет выполняться опережающая выгрузка данных, и код будет сразу доступен в ТекущиеДанные.НоменклатураКод.

Почему свойство ТолькоПросмотр у элемента формы не подходит для одной строки

Распространенная ошибка — менять свойство Элементы.ТоварыЦена.ТолькоПросмотр = Истина в событии ПриАктивизацииЯчейки. Важно помнить: элемент формы ТоварыЦена управляет **всей колонкой целиком**, а не отдельной ячейкой конкретной строки. Изменяя это свойство, вы заблокируете или разблокируете колонку «Цена» для всех строк таблицы одновременно, что приведет к некорректному поведению интерфейса.

Решение 1: Запрет редактирования через Условное оформление (Рекомендуется)

Самый правильный и штатный способ сделать конкретную ячейку недоступной для редактирования в зависимости от условий — настроить **Условное оформление** формы. Это можно сделать как в конфигураторе, так и программно при открытии формы.

Разберем программное добавление условного оформления в событии ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Создаем новый элемент условного оформления
    ЭлементОформления = УсловноеОформление.Элементы.Добавить();
    
    // Устанавливаем свойство ТолькоПросмотр
    ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ТолькоПросмотр", Истина);
    
    // Настраиваем условие: Номенклатура.Код Равно "1" (или "000000001")
    ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый СоставноеПолеКомпоновкиДанных("Объект.Товары.Номенклатура.Код");
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = "1";
    
    // Указываем оформляемое поле (колонку Цена)
    ОформляемоеПоле = ЭлементОформления.Поля.Элементы.Добавить();
    ОформляемоеПоле.Поле = Новый ПолеКомпоновкиДанных("ТоварыЦена");

КонецПроцедуры

При таком подходе платформа 1С самостоятельно визуально заблокирует ячейку цены только в тех строках, где код товара соответствует условию, не задевая другие строки и не требуя кода в событии активизации ячейки.

Решение 2: Проверка перед началом изменения строки

Если необходимо жестко пресечь попытку редактирования ячейки (например, если пользователь пытается ввести значение с клавиатуры или через команды таблицы), используем событие табличной части ПередНачаломИзменения:


&НаКлиенте
Процедура ТоварыПередНачаломИзменения(Элемент, Отказ, Очистка, Замена)
    ТекущиеДанные = Элемент.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем, что редактируется именно колонка Цены
    Если Элемент.ТекущийЭлемент.Имя = "ТоварыЦена" Тогда
        // Проверяем условие по коду товара
        Если ТекущиеДанные.Номенклатура.Код = "1" Тогда
            Отказ = Истина; // Запрещаем редактирование
            ПоказатьПредупреждение(, "Для данного товара изменение цены запрещено!");
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Сочетание программного Условного оформления (для визуального блокирования ячейки) и обработки события ПередНачаломИзменения (для гарантированного запрета ввода) является наиболее надежным и стандартизированным решением в платформе 1С:Предприятие 8.3.

← На главную