Как программно ограничить тип значения в ячейке табличной части 1С

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

В практике разработки на платформе 1С:Предприятие часто возникает задача, когда колонка табличной части имеет составной тип данных. Это удобно, когда в одну и ту же колонку необходимо записывать разные значения: строку, число, дату или ссылки на различные справочники. Однако с точки зрения интерфейса это создает неудобство для пользователя: при попытке ввода значения система открывает стандартное окно выбора типа. Если мы заранее знаем, какой тип данных должен быть в конкретной строке, мы можем избавить пользователя от лишних кликов, программно установив нужные ограничения. В этой статье мы разберем, как это реализовать для обычных и управляемых форм.

Постановка задачи и анализ ситуации

Представим ситуацию: у нас есть табличная часть, где в одной колонке хранятся параметры (например, «Вес», «Цвет», «Дата поставки»). Колонка «Значение» имеет составной тип. Если в текущей строке выбран параметр «Вес», мы хотим, чтобы в ячейке «Значение» можно было ввести только число. Если выбран «Цвет» — только ссылку на справочник «Цвета».

Основная сложность заключается в том, что свойство колонки ТипЗначения или ОграничениеТипа обычно относится ко всей колонке целиком. Чтобы изменить поведение конкретной ячейки, нам придется задействовать обработчики событий формы и манипулировать свойствами элементов управления в момент активизации строки или ячейки.

Решение для обычных форм (v8.2 и v8.3 в режиме обычного приложения)

В обычных формах работа с составом типов в ячейке строится на управлении свойствами ЭлементУправления конкретной колонки. Рассмотрим пошагово, как это сделать, основываясь на успешном опыте из обсуждения.

Для того чтобы при вводе данных система не предлагала выбрать тип, а сразу переходила к редактированию нужного нам типа, необходимо выполнить три действия:

  1. Установить программное ограничение типа для элемента управления колонки.
  2. Отключить возможность выбора типа пользователем (свойство ВыбиратьТип).
  3. Принудительно установить в саму ячейку «пустое» значение нужного типа, чтобы платформа поняла, какой редактор открывать.

Проанализируем пример кода, который лучше всего разместить в событии ПриАктивизацииСтроки или в специализированном обработчике, который срабатывает после изменения типа параметра в строке:


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

    // Определяем нужный нам тип на основании логики (например, из другой колонки)
    Если ТекущиеДанные.ИмяПараметра = "Комментарий" Тогда
        НужныйТип = Новый ОписаниеТипов("Строка");
        ТекущиеДанные.ЗначениеПараметра = ""; // Устанавливаем пустое строковое значение
    ИначеЕсли ТекущиеДанные.ИмяПараметра = "Количество" Тогда
        НужныйТип = Новый ОписаниеТипов("Число");
        ТекущиеДанные.ЗначениеПараметра = 0; // Устанавливаем число
    КонецЕсли;

    // Обращаемся к элементу управления колонки
    КолонкаЗначение = ЭлементыФормы.ТабличнаяЧасть.Колонки.ЗначениеПараметра;
    КолонкаЗначение.ЭлементУправления.ОграничениеТипа = НужныйТип;
    КолонкаЗначение.ЭлементУправления.ВыбиратьТип = Ложь;
КонецПроцедуры

Важный нюанс: если мы просто установим ОграничениеТипа, но в ячейке будет находиться значение Неопределено, система все равно может спросить тип. Поэтому принудительное присвоение значения правильного типа (пустая строка, ноль или пустая ссылка) является критически важным шагом.

Решение для управляемых форм (Такси)

В управляемых формах архитектура работы с интерфейсом изменилась. Здесь мы не можем напрямую менять свойства ЭлементУправления для каждой строки отдельно через коллекцию колонок так же просто, как в обычных формах, потому что элемент формы «Поле» один на всю колонку. Тем не менее, подход с использованием события ПриАктивизацииЯчейки остается рабочим.

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

  1. Используем событие ПриАктивизацииЯчейки или ПередНачаломИзменения.
  2. В обработчике динамически меняем свойство элемента формы ОграничениеТипа.
  3. Приводим текущее значение ячейки к нужному типу с помощью метода ПривестиЗначение().

Рассмотрим пример реализации:


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

    // Допустим, мы хотим ограничить ввод в колонке "Значение"
    Если Элемент.ТекущийЭлемент.Имя = "СписокПараметровЗначение" Тогда
        
        // Логика определения типа
        Если ТекущиеДанные.ТипДанных = "Число" Тогда
            МассивТипов = Новый Массив;
            МассивТипов.Добавить(Тип("Число"));
            КвалификаторыЧисла = Новый КвалификаторыЧисла(15, 3);
            НовоеОписание = Новый ОписаниеТипов(МассивТипов, , КвалификаторыЧисла);
            
            // Устанавливаем ограничение на элемент формы
            Элементы.СписокПараметровЗначение.ОграничениеТипа = НовоеОписание;
            
            // Если значение еще не задано или другого типа — приводим его
            Если ТипЗнч(ТекущиеДанные.Значение) <> Тип("Число") Тогда
                ТекущиеДанные.Значение = НовоеОписание.ПривестиЗначение(ТекущиеДанные.Значение);
            КонецЕсли;
        КонецЕсли;
        
    КонецЕсли;
КонецПроцедуры

Альтернативный способ: Связь по типу

Существует еще более элегантный способ, предусмотренный платформой 1С, который часто позволяет избежать написания кода. Это свойство Связь по типу.

Если в вашей табличной части есть колонка (например, ИмяПараметра), тип которой определяет тип данных в колонке Значение, вы можете настроить это в конфигураторе или программно:

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

Рекомендации и частые ошибки

Проанализируем несколько важных моментов, которые помогут избежать ошибок при реализации:

  1. Составной тип в метаданных: Помните, что вы не можете программно установить в ячейку тип, который не разрешен в метаданных (в определении табличной части в конфигураторе). Программное ограничение работает только как «фильтр» внутри уже разрешенного набора типов.
  2. Производительность: Код в событии ПриАктивизацииСтроки выполняется очень часто. Старайтесь избегать сложных запросов к базе данных внутри этого обработчика. Все необходимые данные для определения типа лучше держать в скрытых колонках этой же строки.
  3. Очистка значений: При смене типа в строке (например, пользователь сначала выбрал «Дата», а потом передумал и выбрал «Число»), не забывайте очищать или преобразовывать старое значение, иначе оно может конфликтовать с новым ограничением типа. Метод ОписаниеТипов.ПривестиЗначение() отлично справляется с задачей превращения неподходящего значения в «пустое» значение нужного типа.

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

← На главную