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

26.08.25

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

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

Файлы

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

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

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

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

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

Вы можете заказать платную доработку или адаптацию этой разработки под вашу конфигурацию на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

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

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С:ERP Управление предприятием 2 1С:Управление холдингом 1С:Зарплата и Управление Персоналом 3.x 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Управление торговлей 11 Платные (руб)

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

31720 руб.

27.03.2025    85733    61    42    

72

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

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

5246 руб.

29.06.2020    25142    34    6    

53

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

Знакомая ситуация? Пользователи, особенно менеджеры, уверены: отборов много не бывает. Идут пожелания добавить в форму списка еще один быстрый фильтр, еще два, еще пять... В итоге интерфейс превращается в нагромождение полей отбора, а потребность в «самом главном» отборе, который «вот прямо сейчас нужен», все равно не закрыта. Универсальное расширение, которое решает эту проблему элегантно и технологично. С его помощью в любую форму списка можно легко добавить панель настраиваемых кнопок-закладок, каждая из которых применяет сложный фильтр-запрос, а так же показывает актуальное количество элементов в реальном времени.

6088 руб.

17.10.2025    2411    3    0    

2

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

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

36600 руб.

28.08.2025    8428    2    2    

6

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

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

20.08.2024    51186    mrXoxot    44    

139

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

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

27.05.2024    26960    smielka    39    

117

Инструментарий разработчика Работа с интерфейсом Программист 1С:Предприятие 8 1C:Бухгалтерия Абонемент ($m)

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

1 стартмани

10.04.2023    17819    182    acces969    31    

132

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

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

12.08.2022    13310    top_1c    39    

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

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

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

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