
Царь-царевич, король-королевич… (Вывод нескольких значений в ячейку на 1С)
Новая задачка на сегодня. Имеется динамический список, мы хотим в одну из его колонок вывести список каких-то значений через запятую.
Для примера рассмотрим такую ситуацию. Есть конфигурация учёта библиотечных книг. В конфигурации имеется регистр накопления «Расположение книг» . Мы хотим видеть какие книги лежат на каждой полке (или находятся у читателя). Книг на полке может быть несколько, и нам нужно видеть в списке их в одной ячейке строки все сразу. В итоговом списке будет отображены поля «Полка» и «Состав» .
Для решения этой задачи создадим на форме динамический список. Установим настройку списка в виде произвольного запроса:
1 2 3 4 5 |
ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ КнижныеПолки.Ссылка КАК Полка, ВЫРАЗИТЬ("" КАК СТРОКА(75)) КАК СоставПредставление ИЗ Справочник.КнижныеПолки КАК КнижныеПолки |
Запрос получает все книжные полки из базы данных. Обратите внимание, что поле «СоставПредставление» заполняется пустой строкой — зарезервируем её для дальнейшего вывода состава полки. Составом будем называть входящие в полку книги.
Далее воспользуемся событием ПриПолученииДанныхНаСервере() динамического списка. Оно доступно в 1С, начиная с версии 8.3.10. Вызывается, когда динамический список обращается к базе данных за очередной порцией информации. Тут нужно сказать, что динамический список выводит таблицу не полностью, а малыми порциями. В целях экономии ресурсов, он ограничивает выборку по несколько десятков строк за раз, необходимых для вывода отображаемой пользователю информации. Выводимые в данный момент строки передаются в свойства «Строки» события ПриПолученииДанныхНаСервере().
Для начала получим из выводимых строк данные обо всех полках:
1 2 3 4 5 6 |
// Получение исходного массива полок. МассивПолок = Новый Массив; Для Каждого ТекСтроки Из Строки Цикл ТекПолка = ТекСтроки.Значение.Данные.Полка; МассивПолок.Добавить(ТекПолка); КонецЦикла; |
Теперь обратимся к БД и проверим наличие книг на отобранных полках:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Получение остатка книг на полках. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ | РасположениеКнигОстатки.Книга КАК Книга, | РасположениеКнигОстатки.КнижнаяПолка КАК КнижнаяПолка |ИЗ | РегистрНакопления.РасположениеКниг.Остатки(, КнижнаяПолка В (&КнижнаяПолка)) КАК РасположениеКнигОстатки |ГДЕ | РасположениеКнигОстатки.КоличествоОстаток > 0"; Запрос.УстановитьПараметр("КнижнаяПолка", МассивПолок); РезультатЗапроса = Запрос.Выполнить(); Выгрузка = РезультатЗапроса.Выгрузить(); |
Для каждой полки создадим строку-представление её состава. Сопоставим каждой полке её состав:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
// Получение соответствия представления состава полок. ВыгрузкаСвертка = Выгрузка.Скопировать(); ВыгрузкаСвертка.Свернуть("КнижнаяПолка"); МассивПолок = ВыгрузкаСвертка.ВыгрузитьКолонку("КнижнаяПолка"); СоответствиеПолок = Новый Соответствие; Для Каждого ТекМассивПолок Из МассивПолок Цикл СтрокаПолка = ""; СтруктураПоиска = Новый Структура; СтруктураПоиска.Вставить("КнижнаяПолка", ТекМассивПолок); НайденныеСтроки = Выгрузка.НайтиСтроки(СтруктураПоиска); Для Каждого ТекНайденныеСтроки Из НайденныеСтроки Цикл ТекКнига = ТекНайденныеСтроки.Книга; СтрокаПолка = СтрокаПолка + СокрЛП(Строка(ТекКнига)) + ", "; КонецЦикла; Если НЕ ПустаяСтрока(СтрокаПолка) Тогда СтрокаПолка = Лев(СтрокаПолка, СтрДлина(СтрокаПолка) - 2); Иначе // Не требуется удалять разделитель. КонецЕсли; СоответствиеПолок.Вставить(ТекМассивПолок, СтрокаПолка); КонецЦикла; |
Остаётся лишь вывести полученные данные назад в свойство «Строки»:
1 2 3 4 5 6 7 8 9 10 |
// Заполнение состава полок в список на форме. Для Каждого ТекСтроки Из Строки Цикл ТекПолка = ТекСтроки.Значение.Данные.Полка; НовоеПредставлениеКниг = СоответствиеПолок.Получить(ТекПолка); Если НовоеПредставлениеКниг <> Неопределено Тогда ТекСтроки.Значение.Данные.СоставПредставление = НовоеПредставлениеКниг; Иначе ТекСтроки.Значение.Данные.СоставПредставление = ""; КонецЕсли; КонецЦикла; |
Вот и всё! Итоговый результат выглядит примерно так:
PS. Полный листинг кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
&НаСервереБезКонтекста Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки) // Получение исходного массива полок. МассивПолок = Новый Массив; Для Каждого ТекСтроки Из Строки Цикл ТекПолка = ТекСтроки.Значение.Данные.Полка; МассивПолок.Добавить(ТекПолка); КонецЦикла; // Получение остатка книг на полках. Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ | РасположениеКнигОстатки.Книга КАК Книга, | РасположениеКнигОстатки.КнижнаяПолка КАК КнижнаяПолка |ИЗ | РегистрНакопления.РасположениеКниг.Остатки(, КнижнаяПолка В (&КнижнаяПолка)) КАК РасположениеКнигОстатки |ГДЕ | РасположениеКнигОстатки.КоличествоОстаток > 0"; Запрос.УстановитьПараметр("КнижнаяПолка", МассивПолок); РезультатЗапроса = Запрос.Выполнить(); Выгрузка = РезультатЗапроса.Выгрузить(); // Получение соответсвия представления состава полок. ВыгрузкаСвертка = Выгрузка.Скопировать(); ВыгрузкаСвертка.Свернуть("КнижнаяПолка"); МассивПолок = ВыгрузкаСвертка.ВыгрузитьКолонку("КнижнаяПолка"); СоответствиеПолок = Новый Соответствие; Для Каждого ТекМассивПолок Из МассивПолок Цикл СтрокаПолка = ""; СтруктураПоиска = Новый Структура; СтруктураПоиска.Вставить("КнижнаяПолка", ТекМассивПолок); НайденныеСтроки = Выгрузка.НайтиСтроки(СтруктураПоиска); Для Каждого ТекНайденныеСтроки Из НайденныеСтроки Цикл ТекКнига = ТекНайденныеСтроки.Книга; СтрокаПолка = СтрокаПолка + СокрЛП(Строка(ТекКнига)) + ", "; КонецЦикла; Если НЕ ПустаяСтрока(СтрокаПолка) Тогда СтрокаПолка = Лев(СтрокаПолка, СтрДлина(СтрокаПолка) - 2); Иначе // Не требуется удалять разделитель. КонецЕсли; СоответствиеПолок.Вставить(ТекМассивПолок, СтрокаПолка); КонецЦикла; // Заполнение состава полок в список на форме. Для Каждого ТекСтроки Из Строки Цикл ТекПолка = ТекСтроки.Значение.Данные.Полка; НовоеПредставлениеКниг = СоответствиеПолок.Получить(ТекПолка); Если НовоеПредставлениеКниг <> Неопределено Тогда ТекСтроки.Значение.Данные.СоставПредставление = НовоеПредставлениеКниг; Иначе ТекСтроки.Значение.Данные.СоставПредставление = ""; КонецЕсли; КонецЦикла; КонецПроцедуры |
Добавить комментарий