Разбор задачи с собеседования: раскрытие потенциала Списка значений

27.02.25

Разработка - Механизмы платформы 1С

В материале поделюсь решением задачи с собеседования на знание Списков значений.

Скачать файл

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

Наименование Бесплатно
Конфигурация
.cf 96,37Kb
4
4 Скачать бесплатно

Текст задачи:

В конфигурацию необходимо добавить справочник "Планерки" с реквизитами: начало встречи, окончание встречи и организатор (ссылка на спр. Физлица). В форме элемента реализовать список с участниками встречи (реализовать подбор незанятых на указанное время планерки сотрудников) с возможностью обновлять информацию об участниках без перезаписи самого элемента справочника.  У каждого участника должна отображаться иконка, фамилия и должность.

Также организатор встречи должен выбираться из списка участников и после выбора выделяться в списке как организатор; в списке должна отображаться информация о том, кто из участников уже подтвердил свое участие на встрече (информация должна обновляться интерактивно по кнопке).

ВАЖНО: количество реквизитов справочника ограничено списком из первого предложения. Запрещено изменять режим использования модальности (по умолчанию "не использовать").

 

 

Для упрощения буду использовать пустую конфигурацию, лишь добавлю справочник "ФизическиеЛица" и типовую картинку "КонтрагентФЛ2", которая пригодится нам для списка участников. Создаем справочник с указанными реквизитами и форму элемента. Поскольку сказано, что список участников на форме не может быть реквизитом, при этом нужна отметка "участия", интерактивное  изменение представления сотрудника (организатор / не организатор) и картинка, то сразу же на ум приходит воспользоваться Списком значений. Добавляем на форму СписокЗначений "Участники",  свойство реквизита "Тип значения" - СправочникСсылка.ФизическиеЛица. Поскольку нам все равно придется где-то хранить актуальные данные по участникам планерки, предлагаю создать независимый непериодический регистр сведений "СотрудникиНаПланерках"

(измерения "Планерка" и "Сотрудник" - ссылки на соответствующее справочники, ресурс - ПодтвердилУчастие (булево)).

 

 

Поскольку нам необходимо интерактивно изменять список на форме,  добавляем две кнопки: "Подобрать участников" и "Обновить". Первая будет открывать окно подбора, требуемое по заданию, вторая актуализировать информацию из регистра сведений. Для первой кнопки создаем клиентскую процедуру, в ней вызываем функцию, чтобы получить СписокЗначений доступных для выбора сотрудников. Выполняем контроль на пустой список и вызываем метод СпискаЗначений ПоказатьОтметкуЭлементов(). Данный метод откроет окно для множественного выбора из сформированного списка (если бы не было ограничения модальных окон, тогда можно было воспользоваться методом ОтметитьЭлементы() и обойтись без ОписанияОповещения):

 

[&НаКлиенте
Процедура ПодобратьУчастников(Команда)
	
	СписокДоступныхУчастников = СписокДоступныхУчастников(Объект.ВремяНачала, Объект.ВремяОкончания, Участники, Объект.Ссылка);
	Если СписокДоступныхУчастников.Количество() > 0 Тогда
		Оповещение = Новый ОписаниеОповещения("ВыполнитьВыборИзСписка", ЭтотОбъект);
		СписокДоступныхУчастников.ПоказатьОтметкуЭлементов(Оповещение, "Выберите участников планерки");	
	Иначе
		ПоказатьПредупреждение(, "Все сотрудники заняты");	
	КонецЕсли;	
	
КонецПроцедуры]

 

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

 
 В ней же мы для формируемого списка мы проставим флаги уже выбранных ранее сотрудников с помощью методов Скопировать() и ЗаполнитьПометки():

 

В функции запросом сначала отбираем всех занятых сотрудников на параллельных встречах, а затем формируем список всех сотрудников исключая занятых. Затем через выборку добавляем к уже выбранным ранее сотрудникам тех, которые доступны для выбора. Не забываем при этом подменять представление, чтобы отображать их должность. Для наглядности, в учебных целях еще можно отсортировать полученный список по представлению элементов. Вернемся к ОписаниюОповещения - его нужно обработать.

Создаем экспортную клиентскую процедуру ВыполнитьВыборИзСписка: 

[&НаКлиенте
Процедура ВыполнитьВыборИзСписка(СписокСотрудников, Параметры) Экспорт
	
	Если СписокСотрудников = Неопределено Тогда
		Возврат;	
	КонецЕсли;	
	
	Для Каждого СтрокаСотрудника Из СписокСотрудников Цикл
		ИскомыйУчастник = Участники.НайтиПоЗначению(СтрокаСотрудника.Значение);
		Если СтрокаСотрудника.Пометка И ИскомыйУчастник = Неопределено Тогда   //Добавляем отмеченных
			Участники.Добавить(СтрокаСотрудника.Значение,СтрокаСотрудника.Представление,,СтрокаСотрудника.Картинка);   
		ИначеЕсли Не СтрокаСотрудника.Пометка И ИскомыйУчастник <> Неопределено Тогда      //Удаляем неотмеченных
			Участники.Удалить(ИскомыйУчастник);
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры]

 

В ней мы перезаполняем список на форме, исходя из данных выбора. Теперь можно заняться Организатором. Нам потребуется событие элемента "НачалоВыборка". Создаем клиентскую процедуру "ОрганизаторНачалоВыбора". В ней отключаем стандартную обработку, чтобы не вызывать типовую форму выбора списка Физлиц, делаем проверку на заполненность списка участников и вызываем немодальный метод списка ПоказатьВыборЭлемента() для выбора организатора из перечня участников:

[&НаКлиенте
Процедура ОрганизаторНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь; 
	
	Если Участники.Количество() = 0 Тогда
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Организатора можно будет выбрать после заполнения списка участников";
		Сообщение.Сообщить();
	Иначе
		Оповещение = Новый ОписаниеОповещения("ОбработкаВыбораОрганизатора", ЭтотОбъект);
		Участники.ПоказатьВыборЭлемента(Оповещение, "Выберите организатора планерки");   
	КонецЕсли;

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

 

И снова требуется вызывать и обрабатывать оповещение. Для него создадим экспортную клиентскую процедуру "ОбработкаВыбораОрганизатора". В ней выбранный участник заполняет соответствующий реквизит "Организатор" и в списке методом НайтиПоЗначению() находим строчку этого участника и подменяем представление, добавив статус организатора мероприятия (а так же нужно не забыть затереть статус предыдущего организатора, если таковой был):

[&НаКлиенте
Процедура ОбработкаВыбораОрганизатора(ВыбранноеЗначение, Параметры) Экспорт
	
	Если ВыбранноеЗначение = Неопределено Тогда
		Возврат;	
	КонецЕсли;
	
	ПодстрокаОрганизатор = " - организатор";
	
	Если ЗначениеЗаполнено(Объект.Организатор) Тогда
		СтарыйОрганизатор = Участники.НайтиПоЗначению(Объект.Организатор);
		СтарыйОрганизатор.Представление = СтрЗаменить(СтарыйОрганизатор.Представление, ПодстрокаОрганизатор, ""); //снимаем старого организатора в списке
		Объект.Организатор = ПредопределенноеЗначение("Справочник.ФизическиеЛица.ПустаяСсылка");
	КонецЕсли;
	
	ВыбранноеЗначение.Представление = ?(СтрНайти(ВыбранноеЗначение.Представление, ПодстрокаОрганизатор,НаправлениеПоиска.СКонца) = 0,
	ВыбранноеЗначение.Представление + ПодстрокаОрганизатор,
	ВыбранноеЗначение.Представление);									  //назначаем нового организатора в списке
	
	Объект.Организатор = ВыбранноеЗначение.Значение; 
	
КонецПроцедуры]

 

Теперь необходимо при записи справочника сохранять данные участников. Буду это делать в событии "ПослеЗаписи". Создаю соответствующую клиентскую процедуру и вызываю из нее не контекстную  серверную:

[&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи) 
	
	ПослеЗаписиНаСервере(Объект.Ссылка, Участники.ВыгрузитьЗначения());
	
КонецПроцедуры


&НаСервереБезКонтекста
Процедура ПослеЗаписиНаСервере(Планерка, УчастникиМассив)
	
	НаборЗаписей = РегистрыСведений.СотрудникиНаПланерках.СоздатьНаборЗаписей();
	НаборЗаписей.Отбор.Планерка.Установить(Планерка);
	НаборЗаписей.Прочитать();
	Для Каждого СтрокаНабора Из НаборЗаписей Цикл 
		Если УчастникиМассив.Найти(СтрокаНабора.Сотрудник) = Неопределено Тогда
			НаборЗаписей.Удалить(СтрокаНабора);	
		КонецЕсли;	
	КонецЦикла;	   
	
	МассивСотрудниковНабора = НаборЗаписей.ВыгрузитьКолонку("Сотрудник");
	Для Каждого Участник Из УчастникиМассив Цикл
		Если МассивСотрудниковНабора.Найти(Участник) = Неопределено Тогда
			НоваяЗапись = НаборЗаписей.Добавить();
			НоваяЗапись.Планерка = Планерка;
			НоваяЗапись.Сотрудник = Участник;
		КонецЕсли;	
	КонецЦикла;	
	
	НаборЗаписей.Записать();
	
КонецПроцедуры]

 

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

 
 В серверной процедуре запросом получаем актуальные данные и отмечаем принявших приглашение сотрудников:

 

[&НаКлиенте
Процедура Обновить(Команда)
	
	ОбновитьНаСервере();
	
КонецПроцедуры


&НаСервере
Процедура ОбновитьНаСервере()  
	
	КартинкаДляСписка = БиблиотекаКартинок.КонтрагентФЛ2;
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	СотрудникиНаПланерках.ПодтвердилУчастие,
	|	ФизическиеЛица.Ссылка,
	|	ФизическиеЛица.Должность,
	|	ФизическиеЛица.Представление
	|ИЗ
	|	РегистрСведений.СотрудникиНаПланерках КАК СотрудникиНаПланерках
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица КАК ФизическиеЛица
	|		ПО СотрудникиНаПланерках.Сотрудник = ФизическиеЛица.Ссылка
	|ГДЕ
	|	СотрудникиНаПланерках.Планерка = &Планерка";
	Запрос.УстановитьПараметр("Планерка", Объект.Ссылка);
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	Пока Выборка.Следующий() Цикл 
		ИскомыйУчастник = Участники.НайтиПоЗначению(Выборка.Ссылка);
		Если ИскомыйУчастник = Неопределено Тогда
			Представление = СтрШаблон("%1 (%2)",Выборка.Представление,Выборка.Должность);
			Участники.Добавить(Выборка.Ссылка,Представление,Выборка.ПодтвердилУчастие,КартинкаДляСписка);  
		Иначе
			ИскомыйУчастник.Пометка = Выборка.ПодтвердилУчастие;
		КонецЕсли;
	КонецЦикла;  
	
КонецПроцедуры]

 

 

Для удобства "ПриСозданииНаСервере" формы тоже будем отображать актуальный данные по списку:

[&НаСервере
Процедура ПриСозданииНаСервере(Отказ)   
	
	ОбновитьНаСервере(); 
	
	Если ЗначениеЗаполнено(Объект.Организатор) Тогда
		Организатор = Участники.НайтиПоЗначению(Объект.Организатор);
		Если Организатор <> Неопределено Тогда
			Организатор.Представление = СтрШаблон("%1 - организатор", Организатор.Представление);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры]

 

Теперь попробуем протестировать функционал. Создам новую планерку, заполняем время проведения и жмем «Подобрать участников».

 

 

В открывшемся окне выберем директора и двух разработчиков.

 

 

Теперь, после переноса выбранных сотрудников в список на форму, можно выбрать Организатора встречи, пусть это будет директор.

 

 

После выбора Организатора у директора соответствующим образом меняется представление в списке

 

 

Запишем справочник и посмотрим на записи регистра сведений. Для учебных целей добавил гиперссылку на записи регистра связанные с текущим справочником, чтобы можно было изменить записи РС без выхода из формы справочника (свойство "Ведущее" у соответствующего измерения регистра). Пусть директор примет приглашение первым, перезапишем его запись, проставив флаг участия.

 

 

Вернемся на основную вкладку формы и нажмем Обновить. Флаг у директора успешно поставился. Аналогичный результат будет при повторном открытии формы элемента.

 

 

Если попытаться создать другую встречу с пересечением по времени, при подборе участников наложится отбор и отобразятся только свободные сотрудники.

 

 

Готово! В форме реализован функционал подбора участников встречи, используя только указанные в задании реквизиты. Конечно, воспользоваться ТаблицейЗначений было бы удобнее, но данный вариант может подойти например для АРМ интерфейсов высоконагруженных систем, где открытие списков выбора может занять длительное время или для ограничения функциональности сотрудника (минималистичный интерфейс позволит быстро обучить сотрудника).

В материале рассмотрели основные методы коллекции СпискаЗначений, для закрепления:

  • ПоказатьОтметкуЭлементов() (ОтметитьЭлементы() если модально) — открывает интерактивное окно для проставления отметок списка значений
  • ПоказатьВыборЭлемента() (ВыбратьЭлемент() если модально) — вызывает окно для интерактивного выбора одного из элементов списка значений
  • Количество() — получает количество элементов списка значений
  • НайтиПоЗначению() — осуществляет поиск элемента списка по его значению. Возвращает ЭлементСпискаЗначений или Неопределено
  • Добавить() — добавляет новый элемент с возможностью указать значение, представление, отметку и картинку
  • Удалить() — удаляет элемент из списка. В параметрах метода указывается либо сам элемент, либо его индекс.
  • Скопировать() — создает на основании указанного списка значений новый список с данными исходного.
  • ЗаполнитьПометки() — проставляет или снимает флаг у всех списка разом в зависимости от параметра метода.
  • СортироватьПоПредставлению() — сортирует элементы списка по алфавиту в зависимости от параметра метода по убыванию или возрастанию.

 

Автор: Егор М., разработчик 1С.

 

*Приложенная конфигурация тестировалась на релизе платформы 8.3.17.1496.

См. также

Механизмы платформы 1С Программист Платформа 1С v8.3 Бесплатно (free)

В платформе 8.3.27 появилась возможность использовать WebSocket-клиент. Давайте посмотрим, как это все устроено и чем оно нам полезно.

14.01.2025    7264    dsdred    57    

96

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Эта небольшая статья - некоторого рода шпаргалка по файловым потокам: как и зачем с ними работать, какие преимущества это дает.

23.06.2024    11035    bayselonarrend    21    

161

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 1C:Бухгалтерия Бесплатно (free)

Пример использования «Сервисов интеграции» без подключения к Шине и без обменов.

13.03.2024    7676    dsdred    18    

82

Механизмы платформы 1С Программист Стажер Платформа 1С v8.3 Бесплатно (free)

Все мы используем массивы в своем коде. Это один из первых объектов, который дают ученикам при прохождении обучения программированию. Но умеем ли мы ими пользоваться? В этой статье я хочу показать все методы массива, а также некоторые фишки в работе с массивами.

24.01.2024    26080    YA_418728146    33    

73

Механизмы платформы 1С Программист Бесплатно (free)

Язык программирования 1С содержит много нюансов и особенностей, которые могут приводить к неожиданным для разработчика результатам. Сталкиваясь с ними, программист начинает лучше понимать логику платформы, а значит, быстрее выявлять ошибки и видеть потенциальные узкие места своего кода там, где позже можно было бы ещё долго медитировать с отладчиком в поисках источника проблемы. Мы рассмотрим разные примеры поведения кода 1С. Разберём результаты выполнения и ответим на вопросы «Почему?», «Как же так?» и «Зачем нам это знать?». 

06.10.2023    25903    SeiOkami    48    

136
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. lada2011 28.02.25 10:38 Сейчас в теме
за решение 5, задача на 2 - секретарша задание составляла?
2. bulpi 217 28.02.25 11:40 Сейчас в теме
А зачем на форме список значений, а не динамический список регистра сведений с отбором ? Было бы проще на порядок
Оставьте свое сообщение