crown

Царь-царевич, король-королевич… (Вывод нескольких значений в ячейку на 1С)

Новая задачка на сегодня. Имеется динамический список, мы хотим в одну из его колонок вывести список каких-то значений через запятую.

Для примера рассмотрим такую ситуацию. Есть конфигурация учёта библиотечных книг. В конфигурации имеется регистр накопления «Расположение книг» . Мы хотим видеть какие книги лежат на каждой полке (или находятся у читателя). Книг на полке может быть несколько, и нам нужно видеть в списке их в одной ячейке строки все сразу. В итоговом списке будет отображены поля «Полка» и «Состав» .

Для решения этой задачи создадим на форме динамический список. Установим настройку списка в виде произвольного запроса:

ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
КнижныеПолки.Ссылка КАК Полка,
ВЫРАЗИТЬ("" КАК СТРОКА(75)) КАК СоставПредставление
ИЗ
Справочник.КнижныеПолки КАК КнижныеПолки

Запрос получает все книжные полки из базы данных. Обратите внимание, что поле «СоставПредставление» заполняется пустой строкой — зарезервируем её для дальнейшего вывода состава полки. Составом будем называть входящие в полку книги.

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

DynListQuery

Для начала получим из выводимых строк данные обо всех полках:

// Получение исходного массива полок.
МассивПолок = Новый Массив;
Для Каждого ТекСтроки Из Строки Цикл
ТекПолка = ТекСтроки.Значение.Данные.Полка;
МассивПолок.Добавить(ТекПолка);
КонецЦикла;

Теперь обратимся к БД и проверим наличие книг на отобранных полках:

// Получение остатка книг на полках.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| РасположениеКнигОстатки.Книга КАК Книга,
| РасположениеКнигОстатки.КнижнаяПолка КАК КнижнаяПолка
|ИЗ
| РегистрНакопления.РасположениеКниг.Остатки(, КнижнаяПолка В (&КнижнаяПолка)) КАК РасположениеКнигОстатки
|ГДЕ
| РасположениеКнигОстатки.КоличествоОстаток > 0";
Запрос.УстановитьПараметр("КнижнаяПолка", МассивПолок);
РезультатЗапроса = Запрос.Выполнить();
Выгрузка = РезультатЗапроса.Выгрузить();

Для каждой полки создадим строку-представление её состава. Сопоставим каждой полке её состав:

// Получение соответствия представления состава полок.
ВыгрузкаСвертка = Выгрузка.Скопировать();
ВыгрузкаСвертка.Свернуть("КнижнаяПолка");
МассивПолок = ВыгрузкаСвертка.ВыгрузитьКолонку("КнижнаяПолка");
СоответствиеПолок = Новый Соответствие;
Для Каждого ТекМассивПолок Из МассивПолок Цикл
СтрокаПолка = "";
СтруктураПоиска = Новый Структура;
СтруктураПоиска.Вставить("КнижнаяПолка", ТекМассивПолок);
НайденныеСтроки = Выгрузка.НайтиСтроки(СтруктураПоиска);
Для Каждого ТекНайденныеСтроки Из НайденныеСтроки Цикл
ТекКнига = ТекНайденныеСтроки.Книга;
СтрокаПолка = СтрокаПолка + СокрЛП(Строка(ТекКнига)) + ", ";
КонецЦикла;
Если НЕ ПустаяСтрока(СтрокаПолка) Тогда
СтрокаПолка = Лев(СтрокаПолка, СтрДлина(СтрокаПолка) - 2);
Иначе
// Не требуется удалять разделитель.
КонецЕсли;
СоответствиеПолок.Вставить(ТекМассивПолок, СтрокаПолка);
КонецЦикла;

Остаётся лишь вывести полученные данные назад в свойство «Строки»:

// Заполнение состава полок в список на форме.
Для Каждого ТекСтроки Из Строки Цикл
ТекПолка = ТекСтроки.Значение.Данные.Полка;
НовоеПредставлениеКниг = СоответствиеПолок.Получить(ТекПолка);
Если НовоеПредставлениеКниг <> Неопределено Тогда
ТекСтроки.Значение.Данные.СоставПредставление = НовоеПредставлениеКниг;
Иначе
ТекСтроки.Значение.Данные.СоставПредставление = "";
КонецЕсли;
КонецЦикла;

Вот и всё! Итоговый результат выглядит примерно так:

Книжные полки

PS. Полный листинг кода:

&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
// Получение исходного массива полок.
МассивПолок = Новый Массив;
Для Каждого ТекСтроки Из Строки Цикл
ТекПолка = ТекСтроки.Значение.Данные.Полка;
МассивПолок.Добавить(ТекПолка);
КонецЦикла;
// Получение остатка книг на полках.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| РасположениеКнигОстатки.Книга КАК Книга,
| РасположениеКнигОстатки.КнижнаяПолка КАК КнижнаяПолка
|ИЗ
| РегистрНакопления.РасположениеКниг.Остатки(, КнижнаяПолка В (&КнижнаяПолка)) КАК РасположениеКнигОстатки
|ГДЕ
| РасположениеКнигОстатки.КоличествоОстаток > 0";
Запрос.УстановитьПараметр("КнижнаяПолка", МассивПолок);
РезультатЗапроса = Запрос.Выполнить();
Выгрузка = РезультатЗапроса.Выгрузить();
// Получение соответсвия представления состава полок.
ВыгрузкаСвертка = Выгрузка.Скопировать();
ВыгрузкаСвертка.Свернуть("КнижнаяПолка");
МассивПолок = ВыгрузкаСвертка.ВыгрузитьКолонку("КнижнаяПолка");
СоответствиеПолок = Новый Соответствие;
Для Каждого ТекМассивПолок Из МассивПолок Цикл
СтрокаПолка = "";
СтруктураПоиска = Новый Структура;
СтруктураПоиска.Вставить("КнижнаяПолка", ТекМассивПолок);
НайденныеСтроки = Выгрузка.НайтиСтроки(СтруктураПоиска);
Для Каждого ТекНайденныеСтроки Из НайденныеСтроки Цикл
ТекКнига = ТекНайденныеСтроки.Книга;
СтрокаПолка = СтрокаПолка + СокрЛП(Строка(ТекКнига)) + ", ";
КонецЦикла;
Если НЕ ПустаяСтрока(СтрокаПолка) Тогда
СтрокаПолка = Лев(СтрокаПолка, СтрДлина(СтрокаПолка) - 2);
Иначе
// Не требуется удалять разделитель.
КонецЕсли;
СоответствиеПолок.Вставить(ТекМассивПолок, СтрокаПолка);
КонецЦикла;
// Заполнение состава полок в список на форме.
Для Каждого ТекСтроки Из Строки Цикл
ТекПолка = ТекСтроки.Значение.Данные.Полка;
НовоеПредставлениеКниг = СоответствиеПолок.Получить(ТекПолка);
Если НовоеПредставлениеКниг <> Неопределено Тогда
ТекСтроки.Значение.Данные.СоставПредставление = НовоеПредставлениеКниг;
Иначе
ТекСтроки.Значение.Данные.СоставПредставление = "";
КонецЕсли;
КонецЦикла;
КонецПроцедуры

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *