Мы сталкиваемся с распространенной задачей в разработке на платформе 1С:Предприятие 8.3 с использованием управляемых форм: необходимо изменить количество знаков после запятой у числового значения в колонке таблицы значений, но не для всей колонки сразу, а только для определенных строк. При этом часто возникает желание избежать программной настройки условного оформления, ищем альтернативные пути. Давайте вместе разберем эту ситуацию, выясним, почему прямые решения не всегда работают, и рассмотрим все доступные подходы.
Первоначально, мы имеем таблицу значений на форме, где тип колонки установлен как, например, "Число (10,2)". Наша цель — для некоторых строк этой таблицы визуально изменить формат числа на "Число (10,0)", чтобы не отображались ненужные нули после запятой. Казалось бы, простая задача, но платформа 1С накладывает определенные ограничения, которые мы должны учитывать.
Таблица, который отображает ТаблицуЗначений, обычно задается на уровне самой колонки. Это означает, что если мы попытаемся программно изменить тип колонки (например, с Число(10,2) на Число(10,0)), это изменение применится ко всей колонке, а не к отдельным строкам. Такое поведение не соответствует нашей задаче динамического форматирования для отдельных строк.Число(10,2), что означает число с точностью до двух знаков после запятой), и есть формат отображения этого числа на форме. Наша задача относится именно к изменению формата отображения, а не к изменению типа хранимых данных. Мы хотим, чтобы число 10.00 отображалось как 10, но его значение при этом оставалось 10.00.ПриВыводеСтроки, которое предоставляло широкие возможности для тонкой настройки оформления каждой строки таблицы непосредственно перед ее выводом. Однако в управляемых формах этого события нет. В результате, для динамического управления визуальным представлением данных на управляемых формах платформа предлагает использовать механизм условного оформления.Несмотря на то что у нас может быть первоначальное нежелание использовать условное оформление (например, из-за необходимости писать код или кажущейся избыточности), это наиболее подходящий, гибкий и поддерживаемый механизм для решения нашей задачи в управляемых формах 1С. Условное оформление позволяет нам задавать различные параметры отображения (цвет, шрифт, видимость, и, что важно для нас, формат числа) для конкретных ячеек или строк в зависимости от определенных условий.
Давайте подробно рассмотрим, как мы можем использовать условное оформление для решения нашей проблемы:
10.00), но отображаем его так, как требуется пользователю (например, 10 или 10.55) в зависимости от контекста строки.Формат. Это свойство принимает строку форматирования, аналогичную той, что используется в функции Формат(). Например, чтобы убрать дробную часть, мы можем указать ЧДЦ=0 (число десятичных знаков = 0). Чтобы отображать два знака, мы укажем ЧДЦ=2. Это позволяет нам полностью контролировать количество знаков после запятой для каждой ячейки.ВидДокумента, мы можем установить условие: "если ВидДокумента равно 'Приход', то применить формат ЧДЦ=0 к колонке 'Количество'". Если же ВидДокумента равно 'Расход', то применить формат ЧДЦ=2.Хотя мы и стремились избежать программного подхода, для нашей задачи это наиболее эффективный способ. Рассмотрим пошаговый пример, как мы можем настроить условное оформление в коде 1С.
Допустим, у нас есть элемент формы с именем ТаблицаЗначенийНаФорме, который отображает реквизит формы с именем ТаблицаЗначений. В этой таблице есть колонка Количество, и мы хотим, чтобы для строк, где значение колонки ВидОперации равно "Поступление", количество отображалось без десятичных знаков, а для остальных — с двумя.
Мы будем настраивать условное оформление на сервере, например, в обработчике события ПриСозданииНаСервере формы или в другой подходящей серверной процедуре, которая выполняется при обновлении данных.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ)
// Очищаем текущие настройки условного оформления, чтобы избежать дублирования
Элементы.ТаблицаЗначенийНаФорме.УсловноеОформление.Элементы.Очистить();
// --- Настройка оформления для строк с ВидОперации = "Поступление" (без дробной части) ---
// 1. Создаем новый элемент условного оформления
НовыйЭлементОформления = Элементы.ТаблицаЗначенийНаФорме.УсловноеОформление.Элементы.Добавить();
// 2. Устанавливаем свойства оформления
// Задаем формат отображения числа: 0 десятичных знаков, без разделителя групп
НовыйЭлементОформления.Оформление.Формат = "ЧДЦ=0; ЧРГ=Истина";
// 3. Указываем поля, к которым применяется оформление
ПолеОформления = НовыйЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("ТаблицаЗначений.Количество"); // Указываем путь к колонке
ПолеОформления.Использование = Истина;
// 4. Задаем условия, при которых оформление применяется
ЭлементУсловия = НовыйЭлементОформления.Условия.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаЗначений.ВидОперации"); // Путь к колонке условия
ЭлементУсловия.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементУсловия.ПравоеЗначение = "Поступление"; // Значение для сравнения
ЭлементУсловия.Использование = Истина;
// --- Настройка оформления для всех остальных строк (с двумя дробными знаками) ---
// Это необходимо, если в конфигураторе для колонки по умолчанию установлен другой формат,
// или мы хотим явно задать формат для "остальных" случаев.
// Создаем новый элемент условного оформления
НовыйЭлементОформленияПоУмолчанию = Элементы.ТаблицаЗначенийНаФорме.УсловноеОформление.Элементы.Добавить();
// Устанавливаем свойства оформления: 2 десятичных знака, без разделителя групп
НовыйЭлементОформленияПоУмолчанию.Оформление.Формат = "ЧДЦ=2; ЧРГ=Истина";
// Указываем поля, к которым применяется оформление
ПолеОформленияПоУмолчанию = НовыйЭлементОформленияПоУмолчанию.Поля.Элементы.Добавить();
ПолеОформленияПоУмолчанию.Поле = Новый ПолеКомпоновкиДанных("ТаблицаЗначений.Количество");
ПолеОформленияПоУмолчанию.Использование = Истина;
// Условия не задаем, чтобы оформление применялось всегда, но т.к. порядок имеет значение,
// это оформление будет перекрыто более специфичным оформлением выше.
// Либо можно явно указать условие "НЕ равно Поступление", если хотим быть более точными.
// В данном случае, платформа применяет оформления в порядке их добавления,
// поэтому, если первое условие срабатывает, оно имеет приоритет.
// Чтобы гарантировать применение этого формата для ВСЕХ остальных,
// можно явно установить для него Условие, например, "НЕ РАВНО Поступление"
// Пример явного условия для "остальных"
ЭлементУсловия2 = НовыйЭлементОформленияПоУмолчанию.Условия.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементУсловия2.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ТаблицаЗначений.ВидОперации");
ЭлементУсловия2.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
ЭлементУсловия2.ПравоеЗначение = "Поступление";
ЭлементУсловия2.Использование = Истина;
КонецПроцедуры
В этом примере мы видим, как создать два правила условного оформления: одно для случая "Поступление" (0 десятичных знаков) и второе для всех остальных случаев (2 десятичных знака). Важно, что правила применяются последовательно, и если несколько правил соответствуют одной ячейке, то применяются те свойства, которые установлены в правилах с более высоким приоритетом (в данном случае, более позднее правило может перекрыть раннее, если условия пересекаются, или наоборот - в зависимости от логики платформы). Поэтому при задании условий мы должны быть внимательны, чтобы правила не конфликтовали или явно обрабатывать приоритеты.
Хотя условное оформление является рекомендуемым решением, мы понимаем, что в некоторых специфических сценариях могут быть причины искать альтернативы. Давайте рассмотрим несколько обходных путей, а также их существенные недостатки.
Этот подход предполагает, что мы будем отображать не исходное числовое поле, а его строковое представление, отформатированное нужным образом.
Мы добавляем в нашу ТаблицуЗначений новую колонку, например, с именем КоличествоФорматированное, тип которой будет Строка. При заполнении таблицы (или изменении значений), мы для каждого числового значения в колонке Количество формируем его строковое представление с нужным количеством знаков после запятой, используя функцию Формат(), и записываем это строковое значение в колонку КоличествоФорматированное.
Затем, на форме, мы скрываем исходную числовую колонку Количество и отображаем пользователю новую строковую колонку КоличествоФорматированное.
// Допустим, у нас есть ТаблицаЗначений ТЗ
ТЗ.Колонки.Добавить("Количество", Тип("Число", 10, 2));
ТЗ.Колонки.Добавить("ВидОперации", Тип("Строка"));
ТЗ.Колонки.Добавить("КоличествоФорматированное", Тип("Строка")); // Новая колонка
// Заполнение данных
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Количество = 123.00;
НоваяСтрока.ВидОперации = "Поступление";
НоваяСтрока.КоличествоФорматированное = Формат(НоваяСтрока.Количество, "ЧДЦ=0"); // Форматируем без знаков
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Количество = 45.67;
НоваяСтрока.ВидОперации = "Расход";
НоваяСтрока.КоличествоФорматированное = Формат(НоваяСтрока.Количество, "ЧДЦ=2"); // Форматируем с двумя знаками
НоваяСтрока = ТЗ.Добавить();
НоваяСтрока.Количество = 89.00;
НоваяСтрока.ВидОперации = "Перемещение";
НоваяСтрока.КоличествоФорматированное = Формат(НоваяСтрока.Количество, "ЧДЦ=0"); // Форматируем без знаков
На форме в свойствах элемента ТаблицаЗначенийНаФорме мы делаем колонку Количество невидимой, а колонку КоличествоФорматированное видимой.
Количество. Если пользователь будет изменять значение в строковой колонке, нам потребуется дополнительный код для парсинга строки обратно в число и обновления исходной числовой колонки, что сопряжено с риском ошибок ввода.Если наша таблица на форме является динамическим списком (то есть источником данных для элемента формы Таблица служит не ТаблицаЗначений, а объект метаданных, например, регистр сведений или документ), то у нас есть событие ПриПолученииДанныхНаСервере. Этот обработчик позволяет нам программно изменять коллекцию строк динамического списка, включая их оформление, после получения данных, но до их отображения на форме.
В обработчике ПриПолученииДанныхНаСервере мы можем перебирать каждую строку полученных данных и для каждой строки программно устанавливать параметры оформления, включая формат числа. Это дает нам более тонкий контроль по сравнению с обычной ТаблицейЗначений, так как мы работаем непосредственно с объектами типа ДанныеФормыЭлементКоллекции.
&НаСервере
Процедура СписокПриПолученииДанныхНаСервере(Элемент, Данные, Отказ)
Для Каждого СтрокаДанных Из Данные Цикл
Если СтрокаДанных.ВидОперации = "Поступление" Тогда
// Устанавливаем формат для колонки "Количество"
// Для ДанныеФормыЭлементКоллекции_Строка (или аналогичного типа)
// можем получить доступ к коллекции оформления
// Этот подход сложнее, чем прямое условное оформление элемента формы,
// и часто сводится к тому же механизму условного оформления,
// но применяемого на уровне каждой строки данных.
// Необходимо получить доступ к объекту оформления соответствующей колонки в данной строке.
// Это может быть сделано через Свойства.Оформление (если применимо к конкретному объекту)
// или через явное создание УсловногоОформления, но уже на основе данных строки.
// Прямой установки формата для одной ячейки без УО в этом событии нет.
// Таким образом, это событие используется скорее для подготовки данных,
// которые затем будут обработаны стандартными механизмами оформления.
// Например, можно добавить временную колонку с флагом,
// по которому затем сработает УсловноеОформление.
КонецЕсли;
КонецЦикла;
КонецПроцедуры
В ходе обсуждения часто возникает вопрос: а что, если мы попытаемся изменить формат непосредственно через ДанныеФормыЭлементКоллекции? Например, при добавлении строки или при интерактивном изменении?
Теоретически, можно попытаться получить доступ к объекту, представляющему данные отдельной строки, и изменить его свойства форматирования. Однако в управляемых формах формат элемента (например, поля ввода) или колонки таблицы жестко привязан к его метаданным или свойствам самой колонки. ДанныеФормыЭлементКоллекции представляет собой ссылку на данные формы, а не на визуальный элемент с его оформлением. Свойства формата типа Число(10,2) являются частью описания типа данных реквизита или колонки, и их изменение программно для *отдельной строки* (без изменения всей колонки) крайне затруднительно или невозможно стандартными методами.
После детального анализа различных подходов мы приходим к однозначному выводу: для динамического изменения формата отображения числа в таблице значений на управляемой форме 1С для отдельных строк наиболее правильным, поддерживаемым и гибким решением является использование условного оформления. Несмотря на первоначальное нежелание программной настройки, именно этот механизм разработан платформой для таких задач и обеспечивает наилучшую интеграцию, производительность и поддерживаемость.
Обходные пути, такие как создание дополнительных строковых колонок, сопряжены с существенными недостатками: дублированием данных, усложнением логики, потерей функциональности и проблемами поддержания консистентности. Попытки глубокой модификации формата отдельных ячеек без использования условного оформления ведут к нестабильным и неподдерживаемым решениям.
Поэтому, если перед нами стоит задача красивого и контекстно-зависимого отображения чисел в таблицах управляемых форм, мы настоятельно рекомендуем освоить и применять программное условное оформление. Это обеспечит надежность вашего решения и упростит его поддержку в будущем.