При разработке и использовании конфигураций на платформе 1С:Предприятие 8.3 с управляемыми формами, мы, разработчики, часто сталкиваемся с парадоксальной ситуацией: имея в руках мощный инструмент для создания гибких и адаптивных интерфейсов, мы обнаруживаем, что некоторые базовые, казалось бы, функции, отсутствуют или реализованы неочевидным образом. Одна из таких проблем, вызывающая много вопросов и нареканий, — это "неуправляемая" табличная часть, а именно, отсутствие простого и эффективного способа автоматически уместить все колонки табличной части в видимую область формы, избегая горизонтальной прокрутки.
Давайте вместе разберем эту проблему, выясним, почему она возникает, и рассмотрим различные подходы, которые мы можем использовать для ее минимизации или обхода, учитывая текущие возможности платформы 1С.
Начнем с того, что именно является камнем преткновения. Как показывает практика и подтверждают обсуждения на форумах, в платформе 1С:Предприятие 8.3 для управляемых форм отсутствует прямая "галка" или свойство, которое бы автоматически регулировало ширину всех колонок табличной части таким образом, чтобы они полностью помещались в доступное пространство формы без появления горизонтальной полосы прокрутки. Мы, разработчики, перебираем все похожие свойства, но такого функционала не находим. Это вызывает фрустрацию, особенно когда пользователи, привыкшие к другим программам (например, к Microsoft Access, где подобная функциональность часто доступна), ожидают аналогичного поведения.
Эта особенность платформы приводит к значительному неудобству для конечных пользователей. Представьте себе табличную часть с множеством колонок, например, закладку "Параметры" в
Консоли запросов для УФ
Платформа 1С, конечно, пытается по умолчанию ставить ширину колонки в зависимости от ее содержимого, но это не означает автоматическое "сжатие" всех колонок под размер окна. Скорее, это попытка адекватно отобразить данные, но не решить проблему общей ширины табличной части.
Самый очевидный, но не всегда приемлемый способ контроля над шириной колонок — это ручное задание их размеров. Для каждой колонки табличной части мы можем установить свойство Ширина. Это свойство, задаваемое в символах, влияет на расчет макета формы:
Ширина. Если мы установим 0, платформа попытается определить ширину автоматически, исходя из содержимого, но, как мы уже говорили, это не решит проблему с общей шириной табличной части.Рассмотрим пример установки ширины колонок программно в модуле формы при создании на сервере или при открытии:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Устанавливаем ширину для конкретных колонок табличной части "МояТабличнаяЧасть"
// Например, если колонка "Наименование" должна быть шире, а "Количество" - уже
Если Элементы.Есть("МояТабличнаяЧасть") Тогда
Если Элементы.МояТабличнаяЧасть.Колонки.Есть("Наименование") Тогда
Элементы.МояТабличнаяЧасть.Колонки.Наименование.Ширина = 40; // Ширина в символах
КонецЕсли;
Если Элементы.МояТабличнаяЧасть.Колонки.Есть("Количество") Тогда
Элементы.МояТабличнаяЧасть.Колонки.Количество.Ширина = 15;
КонецЕсли;
// Добавляем пустую колонку для "растягивания", если требуется
Если Элементы.МояТабличнаяЧасть.Колонки.Есть("ПустаяКолонкаДляРастягивания") Тогда
// Убеждаемся, что она "растягивается"
Элементы.МояТабличнаяЧасть.Колонки.ПустаяКолонкаДляРастягивания.Растягивать = Истина;
// Делаем ее невидимой и без заголовка
Элементы.МояТабличнаяЧасть.Колонки.ПустаяКолонкаДляРастягивания.Видимость = Ложь;
Элементы.МояТабличнаяЧасть.Колонки.ПустаяКолонкаДляРастягивания.ОтображениеЗаголовка = Ложь;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Этот подход работает, но он не решает проблему динамической подстройки под изменяющийся размер формы или под разные разрешения экранов пользователей. Каждый раз при изменении размеров формы или окна, нам пришлось бы вручную пересчитывать и задавать ширину, что крайне неудобно.
Идеальным решением, которое бы удовлетворило нашу потребность в адаптивности, было бы наличие события, срабатывающего при изменении размеров формы, например, `ПриИзмененииРазмераФормы`. В таком обработчике мы могли бы программно пересчитывать и устанавливать ширину колонок пропорционально доступной ширине табличной части. Однако, к сожалению, подобного штатного события в управляемых формах 1С не предусмотрено.
Это ставит нас перед выбором: либо смириться с отсутствием автоматического подбора, либо городить "костыли". Теоретически, мы могли бы попытаться реализовать такой механизм самостоятельно:
Пример (концептуальный) кода, который бы выполнял пересчет ширины колонок, мог бы выглядеть так:
// Этот код является концептуальным и требует доработки,
// а также механизма отслеживания изменения размера формы.
&НаКлиенте
Процедура ОбновитьШиринуКолонокТабличнойЧасти()
// Получаем элемент табличной части формы
Перем ЭлементТабличнойЧасти;
Если Элементы.Есть("МояТабличнаяЧасть") Тогда
ЭлементТабличнойЧасти = Элементы.МояТабличнаяЧасть;
Иначе
Возврат;
КонецЕсли;
// Определяем доступную ширину (это самое сложное на клиенте без события ПриИзмененииРазмераФормы)
// Здесь нужен механизм получения текущей ширины контейнера или формы
// Предположим, что мы как-то получили доступнуюШиринуВПикселях
Перем ДоступнаяШиринаВПикселях;
// Например, можно получить ширину элемента, если он растянут на всю форму.
// ЭлементТабличнойЧасти.Ширина - это ширина в символах или единицах формы, не в пикселях.
// Для получения пиксельной ширины требуется более сложный обходной путь,
// например, через JavaScript в веб-клиенте или COM-объекты в толстом клиенте.
// Для простоты примера, допустим, мы ее знаем или получили через сервер
ДоступнаяШиринаВПикселях = 1000; // Примерное значение
Если ДоступнаяШиринаВПикселях <= 0 Тогда
Возврат;
КонецЕсли;
Перем ОбщаяТекущаяШиринаКолонок = 0;
Перем МассивКолонокДляРастягивания = Новый Массив;
Перем СуммарнаяШиринаНеРастягиваемых = 0;
Для Каждого Колонка Из ЭлементТабличнойЧасти.Колонки Цикл
// Пропускаем невидимые колонки
Если Не Колонка.Видимость Тогда
Продолжить;
КонецЕсли;
// Если колонка должна растягиваться, пока не учитываем ее в сумме
Если Колонка.Растягивать Тогда
МассивКолонокДляРастягивания.Добавить(Колонка);
Иначе
// Получаем текущую ширину колонки, или задаем минимальную
// Свойство Ширина задается в символах, что затрудняет точный пересчет пикселей
// Придется использовать среднюю ширину символа или эвристику
Перем ШиринаКолонкиВПикселях = Колонка.Ширина * 8; // Примерная конверсия символ -> пиксель
Если ШиринаКолонкиВПикселях = 0 Тогда // Автоматическая ширина
ШиринаКолонкиВПикселях = 50; // Минимальная ширина по умолчанию
КонецЕсли;
СуммарнаяШиринаНеРастягиваемых = СуммарнаяШиринаНеРастягиваемых + ШиринаКолонкиВПикселях;
КонецЕсли;
КонецЦикла;
Перем ОставшаясяШиринаДляРастягивания = ДоступнаяШиринаВПикселях - СуммарнаяШиринаНеРастягиваемых;
Если ОставшаясяШиринаДляРастягивания < 0 Тогда
ОставшаясяШиринаДляРастягивания = 0; // Не можем сжать меньше минимума
КонецЕсли;
Перем КоличествоРастягиваемыхКолонок = МассивКолонокДляРастягивания.Количество();
Если КоличествоРастягиваемыхКолонок > 0 Тогда
Перем ШиринаНаКаждуюРастягиваемую = ОставшаясяШиринаДляРастягивания / КоличествоРастягиваемыхКолонок;
Для Каждого КолонкаИзМассива Из МассивКолонокДляРастягивания Цикл
// Преобразуем пиксели обратно в "символы" или единицы формы
КолонкаИзМассива.Ширина = Цел(ШиринаНаКаждуюРастягиваемую / 8);
Если КолонкаИзМассива.Ширина < 5 Тогда // Задаем минимальную ширину
КолонкаИзМассива.Ширина = 5;
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Мы видим, что такой подход чрезвычайно сложен в реализации и может негативно сказаться на производительности отрисовки формы и нагрузке на процессор. Платформа 1С не предназначена для таких динамических манипуляций с интерфейсом в реальном времени. Поэтому, хотя теоретически это возможно, на практике это часто становится нецелесообразным.
Поскольку идеального автоматического решения нет, мы вынуждены искать компромиссы и использовать различные обходные пути, которые, хотя и не решают проблему "в лоб", значительно повышают удобство работы с табличной частью.
Один из наиболее эффективных методов, о котором упоминалось в обсуждении, — это предоставление пользователю возможности самому управлять видимостью колонок. Мы можем реализовать это несколькими способами:
Пример такого подхода (фрагмент кода для кнопки "Показать/Скрыть дополнительные колонки"):
&НаКлиенте
Перем ДополнительныеКолонкиВидимы;
&НаКлиенте
Процедура ПриСозданииНаСервереНаКлиенте(Отказ, СтандартнаяОбработка)
// Инициализация состояния видимости, например, по пользовательским настройкам
ДополнительныеКолонкиВидимы = Ложь; // Или загрузить из пользовательских настроек
// Обновить видимость колонок при открытии формы
ОбновитьВидимостьДополнительныхКолонок();
КонецПроцедуры
&НаКлиенте
Процедура ПереключитьВидимостьДополнительныхКолонок(Команда)
ДополнительныеКолонкиВидимы = Не ДополнительныеКолонкиВидимы;
ОбновитьВидимостьДополнительныхКолонок();
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьВидимостьДополнительныхКолонок()
// Предполагаем, что у нас есть колонки "ДопРеквизит1", "ДопРеквизит2" в табличной части "МояТабличнаяЧасть"
Если Элементы.Есть("МояТабличнаяЧасть") Тогда
Если Элементы.МояТабличнаяЧасть.Колонки.Есть("ДопРеквизит1") Тогда
Элементы.МояТабличнаяЧасть.Колонки.ДопРеквизит1.Видимость = ДополнительныеКолонкиВидимы;
КонецЕсли;
Если Элементы.МояТабличнаяЧасть.Колонки.Есть("ДопРеквизит2") Тогда
Элементы.МояТабличнаяЧасть.Колонки.ДопРеквизит2.Видимость = ДополнительныеКолонкиВидимы;
КонецЕсли;
// Можно также обновить текст кнопки или флажка, если они есть на форме
Если Элементы.Есть("Кнопка_ПереключитьДопКолонки") Тогда
Если ДополнительныеКолонкиВидимы Тогда
Элементы.Кнопка_ПереключитьДопКолонки.Заголовок = "Скрыть дополнительные";
Иначе
Элементы.Кнопка_ПереключитьДопКолонки.Заголовок = "Показать дополнительные";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В "Системе стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8" рекомендуется фиксировать наиболее важные колонки слева, если их много и они не помещаются на экране. Это значительно улучшает восприятие данных для пользователя, так как ключевые идентификаторы строки (например, номер по порядку, наименование) всегда остаются на виду, даже при активной горизонтальной прокрутке остальных колонок.
Для фиксации колонки мы можем использовать свойство Фиксированная:
// В модуле формы при создании на сервере или при открытии
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Элементы.Есть("МояТабличнаяЧасть") Тогда
// Фиксируем колонку "НомерСтроки"
Если Элементы.МояТабличнаяЧасть.Колонки.Есть("НомерСтроки") Тогда
Элементы.МояТабличнаяЧасть.Колонки.НомерСтроки.Фиксированная = Истина;
КонецЕсли;
// Фиксируем колонку "Наименование"
Если Элементы.МояТабличнаяЧасть.Колонки.Есть("Наименование") Тогда
Элементы.МояТабличнаяЧасть.Колонки.Наименование.Фиксированная = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Интересный дизайнерский прием, который позволяет контролировать распределение свободного пространства. В конце табличной части можно добавить пустую колонку со свойством ТолькоПросмотр = Истина и отключенным отображением заголовка (ОтображениеЗаголовка = НеИспользовать). Самое главное — для этой колонки устанавливаем свойство Растягивать = Истина. Эта колонка будет "забирать" на себя все оставшееся свободное пространство, не давая другим колонкам растягиваться сверх меры и обеспечивая более компактный вид табличной части, особенно на широких мониторах.
Пример настройки такой колонки в конфигураторе:
Данные: Не заполнять (оставьте пустым или свяжите с неиспользуемым реквизитом).ТолькоПросмотр: Истина.ОтображениеЗаголовка: Не использовать.Растягивать: Истина.Видимость: Установите по необходимости (можно сделать невидимой, если она нужна только для управления растягиванием).Мы увидим, что эта колонка эффективно поглощает излишки свободного пространства, улучшая визуальное представление.
Еще один важный аспект, который мы часто упускаем из виду, — это сам дизайн табличной части. Чтобы минимизировать необходимость в широких колонках и прокрутке, мы можем:
Важно помнить, что на мобильной платформе 1С поведение табличной части может отличаться. Вместо отображения полосы прокрутки при множестве колонок платформа может автоматически сжимать колонки, уменьшая их ширину. Это также может быть нежелательным поведением, приводящим к нечитаемости данных. Мы должны тестировать наши формы на различных устройствах и разрешениях.
Как мы выяснили, проблема автоматического адаптивного изменения ширины колонок табличной части в 1С Управляемых формах без горизонтальной прокрутки остается актуальной и не имеет простого штатного решения. Платформа 1С, решая свои стратегические задачи, возможно, не уделяет достаточного внимания тактическим вопросам фронтенда. Однако это не значит, что мы бессильны.
Мы, как разработчики, должны применять комплексный подход, используя сочетание:
Хотя "идеальная" автоматизация отсутствует, применив эти методы, мы сможем значительно улучшить пользовательский опыт и сделать наши управляемые формы более удобными и гармоничными.