Программное перемещение колонки динамического списка

26.08.25

Разработка - Работа с интерфейсом

Базовый алгоритм прост - на клиенте определяем, у кого (пользователя и форму) и что (имя колонки) двигать; на сервере получаем настройки, разбираем их, формируем новое значение порядка колонок, заменяем "новое" на "старое", собираем настройки; на сервере без контекста сохраняем настройки; на сервере обновляем реквизиты формы.

Файлы

ВНИМАНИЕ: Файлы из Базы знаний - это исходный код разработки. Это примеры решения задач, шаблоны, заготовки, "строительные материалы" для учетной системы. Файлы ориентированы на специалистов 1С, которые могут разобраться в коде и оптимизировать программу для запуска в базе данных. Гарантии работоспособности нет. Возврата нет. Технической поддержки нет.

Наименование Скачано Купить файл
Программное перемещение колонки динамического списка:
.epf 10,78Kb
1 1 850 руб. Купить

Подписка PRO — скачивайте любые файлы со скидкой до 85% из Базы знаний

Оформите подписку на компанию для решения рабочих задач

Оформить подписку и скачать решение со скидкой

Есть несколько мест, на которых необходимо обратить внимание:

1. Алгоритм опирается на нерекомендуемую ИТС функцию "ЗначениеВСтрокуВнутр";

2. Работоспособность зависит от начальных действий - необходимо "для начала" руками изменить настройки формы;

3. В самом общем случае - когда используются пользовательские поля и синонимы - шаг "разбираем их" существенно усложняется;

4. Если имена колонок содержат "." или "_", шаг "разбираем их" усложняется еще больше.

&НаКлиенте
Процедура СдвинутьКолонку(Команда)
	
	ТекущаяКолонка = ЭтаФорма.ТекущийЭлемент.ТекущийЭлемент.Имя;
	КлючОбъекта = ЭтотОбъект.ИмяФормы + "/НастройкиФормы";
	Пользователь = Строка(ПользователиКлиент.ТекущийПользователь());
	
	СдвинутьКолонкуНаСервере(ТекущаяКолонка, КлючОбъекта, Пользователь);
	
КонецПроцедуры

&НаСервере
Процедура СдвинутьКолонкуНаСервере(Знач ТекущаяКолонка, Знач КлючОбъекта, Знач Пользователь)

	НастройкиФормы = ПолучитьНастройкиФормы(КлючОбъекта, Пользователь);
	Если НастройкиФормы = "" Тогда
		ОбщегоНазначения.СообщитьПользователю("Перед началом иллюстрации работы механизма необходимо 
			|зайти в настройки формы и передвинуть одну из колонок.");
		Возврат;
	КонецЕсли;
	
	ОригинальнаяСекцияПорядкаКолонок = СекцияПорядкаПолей(НастройкиФормы);
	СтараяСекцияИзменений = ЭлементыСекцииПорядкаПолей(ОригинальнаяСекцияПорядкаКолонок)[8];
	НоваяСекцияИзменений = ПереместитьКолонку(ОригинальнаяСекцияПорядкаКолонок, ТекущаяКолонка, -1);
	НовыеНастройкиФормы = СтрЗаменить(НастройкиФормы, СтараяСекцияИзменений, НоваяСекцияИзменений);
	
	СохранитьНастройкиФормы(КлючОбъекта, Пользователь, НовыеНастройкиФормы); 
	ИзменитьРеквизиты();
	
КонецПроцедуры

 

Разложим текущие настройки формы в строку "скобочного формата". Порядок колонок динамического списка хранится в последней секций описания. (Еще раз - описываем простой случай).
Описание порядка делится на две части - "изменения" и "порядок по умолчанию". Секция изменений содержит пары "имя поля + новое положение". 

 

{"Список",
{
{0,0,1,1,
{1,0},
{1,0},0,1,0,0,60,0,1,0,0,2,0,0,1,0,
{0}
},
{
{3,"ОбъектУчета",1,"Поле6",7,"Поле8",9},
{11,"Картинка","ОбъектУчета","Поле1","Поле2","Поле3","Поле4","Поле5","Поле6","Поле7","Поле8","Поле9"}
}
}
}

 

Готовим "виртуальный обновленный порядок" и сверяем с порядком по умолчанию. Для построения списка изменений применяется следующая эвристика:

"если индекс поля не соответствует позиции по умолчанию, то поле заносится в список перемещенных колонок".

Пример реализации в приложенной обработке.

 

P.S.

 
 Текст модуля иллюстрации 

 


#Область СдвинутьКолонку

&НаКлиенте
Процедура СдвинутьКолонку(Команда)
	
	ТекущаяКолонка = ЭтаФорма.ТекущийЭлемент.ТекущийЭлемент.Имя;
	КлючОбъекта = ЭтотОбъект.ИмяФормы + "/НастройкиФормы";
	Пользователь = Строка(ПользователиКлиент.ТекущийПользователь());
	
	СдвинутьКолонкуНаСервере(ТекущаяКолонка, КлючОбъекта, Пользователь);
	
КонецПроцедуры

&НаСервере
Процедура СдвинутьКолонкуНаСервере(Знач ТекущаяКолонка, Знач КлючОбъекта, Знач Пользователь)

	НастройкиФормы = ПолучитьНастройкиФормы(КлючОбъекта, Пользователь);
	Если НастройкиФормы = "" Тогда
		ОбщегоНазначения.СообщитьПользователю("Перед началом иллюстрации работы механизма необходимо 
			|зайти в настройки формы и передвинуть одну из колонок.");
		Возврат;
	КонецЕсли;
	
	ОригинальнаяСекцияПорядкаКолонок = СекцияПорядкаПолей(НастройкиФормы);
	СтараяСекцияИзменений = ЭлементыСекцииПорядкаПолей(ОригинальнаяСекцияПорядкаКолонок)[8];
	НоваяСекцияИзменений = ПереместитьКолонку(ОригинальнаяСекцияПорядкаКолонок, ТекущаяКолонка, -1);
	НовыеНастройкиФормы = СтрЗаменить(НастройкиФормы, СтараяСекцияИзменений, НоваяСекцияИзменений);
	
	СохранитьНастройкиФормы(КлючОбъекта, Пользователь, НовыеНастройкиФормы); 
	ИзменитьРеквизиты();
	
КонецПроцедуры

// важный нюанс - без контекста!
&НаСервереБезКонтекста
Процедура СохранитьНастройкиФормы(Знач КлючОбъекта, Знач Пользователь, Знач НовыеНастройкиФормы)
	
	НоваяНастройкаФормы = ЗначениеИзСтрокиВнутр(НовыеНастройкиФормы);
	ХранилищеСистемныхНастроек.Сохранить(КлючОбъекта,, НоваяНастройкаФормы,, Пользователь);
	
КонецПроцедуры

&НаСервере
Функция ПолучитьНастройкиФормы(Знач КлючОбъекта, Знач Пользователь)
	
	НастройкиФормы = ХранилищеСистемныхНастроек.Загрузить(КлючОбъекта,,, Пользователь);
	НастройкиФормыСтрокой = ЗначениеВСтрокуВнутр(НастройкиФормы);
	
	Возврат НастройкиФормыСтрокой;
	
КонецФункции

&НаСервере
Функция СекцияПорядкаПолей(Знач НастройкиФормыСтрокой, Знач ИмяДинамическогоСписка = "Список")

	СтрокаПоиска = "{""" + ИмяДинамическогоСписка + """,";
	НачалоСекции = СтрНайти(НастройкиФормыСтрокой, СтрокаПоиска, НаправлениеПоиска.СКонца);
	
	Если НЕ НачалоСекции = 0 Тогда
		СекцияОписанияПорядкаПолей = ПрочитатьСекцию(НастройкиФормыСтрокой, НачалоСекции);
	Иначе
		СекцияОписанияПорядкаПолей = "";
	КонецЕсли;
	
	Возврат СекцияОписанияПорядкаПолей;
	
КонецФункции

&НаСервере
Функция ЭлементыСекцииПорядкаПолей(Знач СекцияПорядкаПолей)
	
	РазделительЭлементовСекции = "{}" + Символы.ПС;
	
	Возврат СтрРазделить(СекцияПорядкаПолей, РазделительЭлементовСекции, ЛОЖЬ);
	
КонецФункции

&НаСервере
Функция ПорядокПолейПоУмолчанию(СекцияПорядкаПолей)

	РазделительДанныхСекции = """,""";
	ПорядокПолейПоУмолчанию = 10;
	
	Возврат СтрРазделить(СекцияПорядкаПолей[ПорядокПолейПоУмолчанию], РазделительДанныхСекции, ЛОЖЬ);

КонецФункции

&НаСервере
Функция ПеремещенныеПоля(Знач СекцияПорядкаПолей)
	
	РазделительДанныхСекции = """,""";
	ПеремещенныеПоля = 8;

	Возврат СтрРазделить(СекцияПорядкаПолей[ПеремещенныеПоля], РазделительДанныхСекции, ЛОЖЬ);

КонецФункции

&НаСервере
Функция ПереместитьКолонку(Знач СекцияПорядкаКолонок, Знач ИмяКолонки, Знач Сдвиг)
	
	СекцияПорядкаПолей = ЭлементыСекцииПорядкаПолей(СекцияПорядкаКолонок);
	ПорядокПоУмолчанию = ПорядокПолейПоУмолчанию(СекцияПорядкаПолей);
	Перемещения = ПеремещенныеПоля(СекцияПорядкаПолей);
	
	АктуальныйПорядок = ПостроитьАктуальныйСписок(ПорядокПоУмолчанию, Перемещения);
	АктуальныйПорядок.Удалить(0);
	
	АктуальнаяПозиция = АктуальныйПорядок.Найти(ИмяКолонки);
	НоваяПозиция = АктуальнаяПозиция + Сдвиг;
	
	ПеремещениеНеВызоветПереполнения = (НоваяПозиция >= 0)
		И (НоваяПозиция <= АктуальныйПорядок.ВГраница());
	
	Если ПеремещениеНеВызоветПереполнения Тогда
		
		СписокПеремещений = ПостроитьСписокПеремещений(Перемещения, ИмяКолонки, НоваяПозиция);
		
	КонецЕсли;
	
	Возврат СписокПеремещений;
	
КонецФункции

&НаСервере
Функция ПостроитьАктуальныйСписок(Знач ПорядокПоУмолчанию, Знач Перемещения)
	
	МассивВозврата = Новый Массив;
	Для Каждого ЭлементМассива Из ПорядокПоУмолчанию Цикл
		МассивВозврата.Добавить(ЭлементМассива);
	КонецЦикла;
	
	ГраницаМассива = Перемещения.ВГраница();
	Итератор = 1;
	Пока Итератор <= ГраницаМассива Цикл
		МестоВШаблоне = МассивВозврата.Найти(Перемещения[Итератор]);
		Если МестоВШаблоне = Неопределено Тогда
			МассивВозврата.Добавить(Перемещения[Итератор]);
			МестоВШаблоне = МассивВозврата.ВГраница();
		КонецЕсли;
		СдвинутьВМассиве(МассивВозврата, МестоВШаблоне, Число(Перемещения[Итератор + 1]) + 1);
		Итератор = Итератор + 2;
	КонецЦикла;
	
	Возврат МассивВозврата;
	
КонецФункции

&НаСервере
Функция ПостроитьСписокПеремещений(Знач Перемещения, Знач ИмяКолонки, Знач НоваяПозиция)

	ФорматнаяСтрока = "ЧГ=";
	
	ВПеремещениях = Перемещения.Найти(ИмяКолонки);
	Если ВПеремещениях = Неопределено Тогда
		Перемещения.Добавить(ИмяКолонки);
		Перемещения.Добавить(Формат(НоваяПозиция, ФорматнаяСтрока));
		Перемещения[0] = Формат(Число(Перемещения[0]) + 1, ФорматнаяСтрока);
	Иначе
		Перемещения[ВПеремещениях + 1] = (Формат(НоваяПозиция, ФорматнаяСтрока));
	КонецЕсли;
	
	Для Итератор = 0 По Перемещения.ВГраница() Цикл
		Если НЕ СтроковыеФункцииКлиентСервер.ТолькоЦифрыВСтроке(Перемещения[Итератор]) Тогда
			Перемещения[Итератор] = """" + Перемещения[Итератор] + """";
		КонецЕсли;
	КонецЦикла;
	
	Возврат СтрСоединить(Перемещения, ",");
	
КонецФункции

&НаСервере
Процедура СдвинутьВМассиве(МассивЗначений, Знач ЧтоДвигать, Знач КудаДвигать)
	Перем БуферЗначения, Двигатель, ШагИтерации;

	Если ЧтоДвигать = КудаДвигать Тогда
		Возврат;
	КонецЕсли;

	БуферЗначения = МассивЗначений[ЧтоДвигать];
	Двигатель = ЧтоДвигать;
	ШагИтерации = ?(КудаДвигать > ЧтоДвигать, 1, -1);

	Пока Двигатель <> КудаДвигать Цикл
		МассивЗначений[Двигатель] = МассивЗначений[Двигатель + ШагИтерации];
		Двигатель = Двигатель + ШагИтерации;
	КонецЦикла;
	МассивЗначений[КудаДвигать] = БуферЗначения;

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

&НаСервере
Функция ПрочитатьСекцию(Знач СтрокаОписанияНастроек, Знач ПозицияНачалаСекции)
	
	СтекСкобок = 1;
	Сдвиг = 1;
	Пока СтекСкобок <> 0 Цикл
		РабочийСимвол = Сред(СтрокаОписанияНастроек, ПозицияНачалаСекции + Сдвиг, 1);
		Если РабочийСимвол = "{" Тогда
			СтекСкобок = СтекСкобок + 1;
		ИначеЕсли РабочийСимвол = "}" Тогда
			СтекСкобок = СтекСкобок - 1;
		КонецЕсли;
		Сдвиг = Сдвиг + 1;
	КонецЦикла;
	
	Возврат Сред(СтрокаОписанияНастроек, ПозицияНачалаСекции, Сдвиг);
	
КонецФункции

#КонецОбласти

 

 

 

Проверено на следующих конфигурациях и релизах:

  • 1С:Зарплата и кадры бюджетного учреждения, релизы 1.0.121.2

Вступайте в нашу телеграмм-группу Инфостарт

Динамический список Управляемые формы Перемещение колонки

См. также

Работа с интерфейсом Анализ учета Мониторинг 1С:Предприятие 8 1С 8.3 1C:Бухгалтерия 1С:Бухгалтерия 3.0 1С:Библиотека стандартных подсистем 1С:ERP Управление предприятием 2 1С:Управление холдингом 1С:Зарплата и Управление Персоналом 3.x 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 11 Платные (руб)

Создайте свой функциональный интерфейс в любой конфигурации 1С с помощью расширения Infostart Dashboard. Настраивайте панели виджетов с метриками, индикаторами и показателями на начальном экране. Узнайте возможность внедрения подсистемы у себя в конфигурации с помощью бесплатной обработки "Анализ внедрения подсистемы 1С Infostart Dashboard"!

28800 руб.

27.03.2025    56336    31    25    

45

Разработка Инструментарий разработчика Работа с интерфейсом Адаптация типовых решений Нейросети 1C:Бухгалтерия 1C:ERP 1С:ЗУП 1С:КА 1С:УНФ 1С:УТ 1С:Розница 1С:ДО 1С:ERP Управление предприятием 2 Платные (руб)

Разработка "Дизайнер форм 1С" реализована в виде расширения 1С и является универсальным инструментом для разработки прототипа форм с целью демонстраций, технических заданий и т.д. Без участия разработчика с возможностью экспорта в файл внешней обработки и генерации формы используя искусственный интеллект.

36000 руб.

28.08.2025    2661    1    2    

4

Работа с интерфейсом Системный администратор Программист 1С:Предприятие 8 1C:Бухгалтерия Платные (руб)

Расширение «Динамическое управление доступом к элементам форм объектов 1С8» предназначен для обеспечения возможности оперативного управления видимостью и доступностью элементов форм документов и справочников продуктов фирмы «1С» «1С:Предприятие 8». Решение универсальное, встраивается в любую конфигурацию с минимальными доработками, что позволяет без проблем обновлять типовые решения.

6000 руб.

14.01.2016    58233    20    25    

46

Работа с интерфейсом Программист 1С:Предприятие 8 1C:Бухгалтерия 1С:ERP Управление предприятием 2 Платные (руб)

Обработка предназначена для создания и управления дашбордами (виджетами) в 1С.

5160 руб.

29.06.2020    22859    32    6    

51

Работа с интерфейсом Программист 1С:Предприятие 8 1C:Бухгалтерия Россия Платные (руб)

Редактор графов в 1С - внешний отчет, который формирует графы на основе таблицы значений, используя рисунки табличного документа. Есть возможность добавления, редактирования объектов графа и выгрузки результата в таблицу значений.

5040 руб.

06.10.2020    12849    8    8    

14

Работа с интерфейсом Программист Стажер 1С:Предприятие 8 Бесплатно (free)

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

20.08.2024    43370    mrXoxot    44    

138

Работа с интерфейсом Программист 1С:Предприятие 8 Бесплатно (free)

Пример простого и симпатичного прогресс-бара в динамическом списке, без картинок, используя редактирование запроса.

27.05.2024    24830    smielka    38    

111
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Avatarzorro 64 26.08.25 09:50 Сейчас в теме
какая дичь. Пишешь что на сервере без контекста, однако вызываешь с контекстом. Да и в целом вся эта бесполезная писанина умещается в 2 строки. Если пользователю надо настроить свой порядок, то это делается без конфигуратора.

Еще большим бредом здесь выглядит вызов ИзменитьРеквизиты(). Зачем он тут в принципе нужен не понятно.

Много вопросов и так мало ответов
2. rnobody 4 26.08.25 11:13 Сейчас в теме
Приведенный фрагмент кода иллюстрирует только общий порядок действий - "под капотом" довольно много кода. Так и не понял, к сожалению, как бесплатно приложить файл.
"Без контекста" вызывается фрагмент записи модифицированных настроек формы, иначе никак. Без "ИзменитьРеквизиты()" интерфейс не обновится.
Само по себе движение колонки да, согласен, бесполезно. Но если потребуется "двигать" группы колонок, да в списке с парой сотен реквизитов, да по нескольку раз в день - тут, к сожалению, без помощи программиста не обойтись.

И, пожалуйста, если не затруднит - прикиньте эту "пару строк" в комментарий.
3. rnobody 4 26.08.25 14:50 Сейчас в теме
(2) Подскажите, как текст модуля в спойлер убрать - добавлю в публикацию.
Для отправки сообщения требуется регистрация/авторизация