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