Универсальные коллекции значений 1С - это динамические структуры с данными, которые не хранятся в системе, а формируются на время работы какого-либо алгоритма. Как правило, они служат для вспомогательного сбора, группировки, анализа и обработки информации.
Типы универсальных коллекций 1С:
- Массив (и ФиксированныйМассив);
- Структура (и ФиксированнаяСтруктура);
- Соответствие (и ФиксированноеСоответствие);
- Список значений;
- Таблица значений;
- Дерево значений;
- COMSafeArray;
- КлючИЗначение;
- ФиксированнаяКоллекция.
Рисунки из курса https://ironskills.by/
Массив
Соответствие
Структура
Список значений
Таблица значений
Коллекция | Тип ключа |
Массив | Число (индекс, начиная с 0) |
Структура | Строка |
Соответствие | Любой тип |
Список значений | Число (индекс, начиная с 0) |
Коллекции могут:
- возвращаться в виде результата какой-либо функции (функция возвращает в качестве значения универсальную коллекцию);
- задаваться разработчиком непосредственно в коде (обратившись к конструктору
Новый
и создав экземпляр класса).
Например:
1 |
НашМассив = Новый Массив; |
Почти любую универсальную коллекцию можно создать с помощью конструктора (исключением являются табличные части, которые выступают в качестве объектов конфигурации). Конструкторы для многих универсальных коллекций являются параметризованными. Используя параметры конструктора, можно сразу задать желаемое поведение данного объекта. При этом параметры являются необязательными, разработчик может их не задавать и в дальнейшем определить поведение объекта так, как считает нужным.
Для универсальных коллекций существуют такие общие понятия, как индекс и номер:
- Каждый элемент коллекции имеет индекс. При этом индекс начинается с нуля.
- Для некоторых коллекций (преимущественно у тех, которые могут отображаться в интерфейсе пользователя) существует понятие номера строки. Номер строки начинается с единицы (например, для табличной части).
Таким образом, если мы знаем номер строки и хотим обратиться по индексу, то в качестве индекса следует использовать значение на единицу меньше номера строки.
Для всех коллекций используется обход элементов коллекции двумя способами:
- циклом Для;
- циклом Для каждого ... Из.
Методы большинства универсальных коллекций:
- Количество – метод, который возвращает количество элементов коллекции.
- Индекс - метод, который позволяет определить, какой индекс соответствует данной строке (т.е. текущую позицию строки в таблице). Значения индекса начинаются с нуля. Существует не у всех коллекций, а только у тех, на элементы которой можно сослаться.
Пример
В качестве примера можно привести
ТаблицуЗначений
.ТаблицаЗначений
– это определенная коллекция строк, в строках могут содержаться разные колонки с разными типами значений. Каждая строка представляет собой самостоятельную сущность. На нее можно получить ссылку, через эту строку можно обращаться к значениям колонок в данной строке. МетодИндекс()
позволяет определить, какой индекс соответствует данной строке (т.е. текущую позицию строки в таблице).[свернуть]
Массив
Массив - пронумерованная коллекция значений произвольного типа.
К элементу массива можно обращаться по его индексу, нумерация начинается с 0 (т.е. индекс первого элемента массива равен 0).
В качестве элементов массива могут выступать, в частности, другие массивы. Это позволяет создавать многомерные массивы.
Для того чтобы обратиться к элементу массива МойМассив
, можно использовать обращение по индексу, который указывается в квадратных скобках, или с помощью специального метода Получить()
, например:
1 2 3 |
Элемент3 = МойМассив[2]; // ИЛИ Элемент3 = МойМассив.Получить(2); |
Так как индекс начинается с нуля, система возвращает элемент массива с индексом 2, но третий (по порядку) элемент массива.
Особенности работы с массивами:
- При удалении элемента массива методом
Удалить()
происходит неявный сдвиг индексов (вверх на место удаленного элемента), что может привести к нарушению последовательности обхода элементов массива в цикле (с удалением элементов). Для исключения этого можно:- удалять элементы, просматривая массив с конца, или
- поместить удаляемые элементы в новый массив, а затем обходить исходный массив, удаляя элементы, совпадающие по значению с элементами нового массива.
пример123456789101112//удалить числа меньше 10МассивКУдалению = Новый Массив;Для каждого ТекЧисло Из МассивЧисел ЦиклЕсли ТекЧисло < 10 ТогдаМассивКУдалению.Добавить(ТекЧисло);КонецЕсли;КонецЦикла;Для каждого ТекЧисло Из МассивКУдалению ЦиклИндекс = МассивЧисел.Найти(ТекЧисло);//индекс удаляемого элемента в исходном массивеМассивЧисел.Удалить(Индекс);КонецЦикла;[свернуть]
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | Номенклатура.Ссылка КАК НоменклатурнаяГруппа |ИЗ | Справочник.Номенклатура КАК Номенклатура |ГДЕ | Номенклатура.ЭтоГруппа = ИСТИНА; РезультатЗапроса = Запрос.Выполнить(); Массив = РезультатЗапроса.Выгрузить().ВыгрузитьКолонку("НоменклатурнаяГруппа"); |
Структура
Структура - поименованная коллекция, состоящая из пар "ключ - значение", причем
- ключ может быть только строковым;
- а значение - произвольного типа.
Обычно используется для хранения небольшого количества значений, каждое из которых имеет некоторое уникальное имя.
К элементу структуры можно обращаться по значению его ключа, т.е. по имени.
1 2 |
ДанныеСотрудника = Новый Структура; ДанныеСотрудника = Новый Структура("ФИО,ДатаРождения,АдресПрописки,НомерПаспорта", "Иванов", '19910811', "г. Минск", "12141"); |
1 2 3 4 5 6 7 8 9 10 11 12 |
//Как найти значение в структуре РезультатПоиска = Неопределено; СвойствоНайдено = ДанныеСотрудника.Свойство("ФИО", РезультатПоиска); // Истина Сообщить(РезультатПоиска); //Как получить значение структуры ДатаРождения = ДанныеСотрудника["ДатаРождения"]; Адрес = ДанныеСотрудника["АдресПрописки"]; // или ДатаРождения = ДанныеСотрудника.ДатаРождения; Адрес = ДанныеСотрудника.АдресПрописки; |
1 2 3 4 |
// Обход элементов структуры Для каждого ЭлементСтруктуры Из МояСтруктура Цикл Сообщить(ЭлементСтруктуры.Ключ + ": " + ЭлементСтруктуры.Значение); КонецЦикла; |
Соответствие
Также как и структура, представляет собой коллекцию пар ключ - значение. Однако, в отличие от структуры, ключ может быть практически любого типа.
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 |
// Создать соответствие СоответствиеРазмеров = Новый Соответствие; // Вставить элемент в соответствие СоответствиеРазмеров.Вставить(36, "XS"); СоответствиеРазмеров.Вставить(38, "S"); СоответствиеРазмеров.Вставить(40, "M"); СоответствиеРазмеров.Вставить(42, "L"); // Получить количество элементов в соответствии Количество = СоответствиеРазмеров.Количество(); // Получить значение в соответствии РазмерМ = СоответствиеРазмеров.Получить(40); // M // или РазмерL = СоответствиеРазмеров[42]; // Обход всех элементов соответствия // (т.к. ключ - любого типа, в Сообщить() сначала пустая строка) Для каждого ЭлементСоответствия Из СоответствиеРазмеров Цикл Сообщить("" + ЭлементСоответствия.Ключ + " - " + ЭлементСоответствия.Значение); КонецЦикла; // Удалить элемент соответствия СоответствиеРазмеров.Удалить(47); // Очистить соответствие СоответствиеРазмеров.Очистить(); |
Список значений
Список значений позволяет строить динамические наборы значений и манипулировать ими (добавлять, редактировать, удалять элементы, сортировать). Используется, как правило, для решения интерфейсных задач (его можно разместить на форме для интерактивного ввода, выбора или отметки пользователем его элементов).
Особенности списка значений:
- может содержать значения любого типа;
- в одном списке типы хранимых значений могут быть разными.
Например, список значений может использоваться для выбора конкретного документа из списка возможных документов, сформированного по сложному алгоритму.
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 |
// Создать список значений ДниНедели = Новый СписокЗначений; // Добавить элементы в список значений ДниНедели.Добавить("Пн", "Понедельник", Истина, БиблиотекаКартинок.ВидРасчета); // Показать список значений пользователю для выбора одного значения ВыбранноеЗначение = МойСписокЗначений.ВыбратьЭлемент(); Если ВыбранноеЗначение = Неопределено Тогда //пользователь отказался от выбора Сообщить("Вы ничего не выбрали...Очень жаль"); Иначе Сообщить("Вы выбрали:" + ВыбранноеЗначение.Представление); КонецЕсли; // Показать список значений пользователю для отметки нескольких значений ПользовательВыбрал = МойСписокЗначений.ОтметитьЭлементы("Выберите..."); Если ПользовательВыбрал = Истина Тогда Сообщить("Вы выбрали:"); Для каждого Элемент Из МойСписокЗначений Цикл Если Элемент.Пометка = Истина Тогда Сообщить(Элемент.Представление); КонецЕсли; КонецЦикла; Иначе Сообщить("Вы ничего не выбрали...Очень жаль"); КонецЕсли; // Удалить элемент списка значений // по индексу ДниНедели.Удалить(6); // по значению Воскресенье = ДниНедели.НайтиПоЗначению("Вс"); Если Воскресенье <> Неопределено Тогда ДниНедели.Удалить(Воскресенье); КонецЕсли; |
Таблица значений
Таблица значений позволяет строить динамические наборы значений и манипулировать ими.
Особенности таблицы значений:
- недоступна в тонком клиенте (см. раздел "Доступность" в Справке);
- может быть наполнена значениями любого типа;
- в одной таблице типы хранимых значений могут быть разными.
Одним из примеров использования таблицы значений может служить организация представления в форме списка элементов справочника, отобранных по сложному алгоритму.
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 |
// Создать таблицу значений ТаблицаТовары = Новый ТаблицаЗначений; // Добавить колонки в таблицу значений ТаблицаТовары.Колонки.Добавить("Номенклатура"); ТаблицаТовары.Колонки.Добавить("Склад"); ТаблицаТовары.Колонки.Добавить("ВНаличии"); ТаблицаТовары.Колонки.Добавить("ВРезерве"); ТаблицаТовары.Колонки.Добавить("Остаток"); // Добавить элементы (строки) в таблицу значений НоваяСтрока = ТаблицаТовары.Добавить(); НоваяСтрока.Номенклатура = "Самсунг"; НоваяСтрока.Склад = "Основной"; НоваяСтрока.ВНаличии = 2; НоваяСтрока.ВРезерве = 0; НоваяСтрока.Остаток = 2; // Найти строку в таблице значений Самсунг = ТаблицаТовары.Найти("Самсунг", "Номенклатура"); // строка таблицы значений Если Самсунг = Неопределено Тогда //не нашли Сообщить("Товар Самсунг не найден"); Иначе Сообщить("Остаток:" + Самсунг.Остаток); КонецЕсли; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Создать таблицу значений (см. выше) // Добавить колонки в таблицу значений (см. выше) // Добавить элементы (строки) в таблицу значений (см. выше) // Найти все строки таблицы значений, которые удовлетворяют условию поиска СтруктураПоиска = Новый Структура("Номенклатура", "Самсунг"); МассивСтрок = ТаблицаТовары.НайтиСтроки(СтруктураПоиска); Если МассивСтрок.Количество() > 0 Тогда //строки найдены Для каждого СтрокаОстатка Из МассивСтрок Цикл Сообщить(СтрокаОстатка.Склад + ": " + СтрокаОстатка.Остаток); КонецЦикла; Иначе Сообщить("Товар ""Самсунг"" не найден в таблице"); КонецЕсли; |
1 2 3 4 5 6 7 8 |
// Поиск по сложному условию Номенклатура + Склад СтруктураПоиска = Новый Структура("Номенклатура, Склад", "Капуста белокочанная", "Торговый зал"); НайденныеСтроки = ТаблицаТовары.НайтиСтроки(СтруктураПоиска); Если НайденныеСтроки.Количество() > 0 Тогда Сообщить(НайденныеСтроки[0].Склад + ": " + НайденныеСтроки[0].Остаток); Иначе Сообщить("Товар Капуста белокочанная на складе Торговый зал не найден"); КонецЕсли; |
1 2 3 4 5 6 7 8 9 10 11 |
// Обход таблицы значений с неизвестными именами колонок Колонки = ТаблицаТовары.Колонки; Для каждого Строка Из ТаблицаТовары Цикл Для каждого ТекКолонка Из Колонки Цикл // получаем имя колонки ИмяКолонки = ТекКолонка.Имя; // получаем информацию из соответствующего поля (колонка-строка) // ВАЖНО! обращение "через точку" Строка.ИмяКолонки приведет к ошибке Сообщить(ИмяКолонки + ":" + Строка[ИмяКолонки]) КонецЦикла; КонецЦикла; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Копия всей таблицы значений с данными ПолнаяКопия = ТаблицаТовары.Скопировать(); // Копия таблицы значений (без данных) ПустаяКопия = ТаблицаТовары.СкопироватьКолонки(); // Копия выбранных колонок таблицы значений с данными КопияТолькоСклады = ТаблицаТовары.Скопировать(, "Склад, ВНаличии, ВРезерве, Остаток"); // Копия выбранных строк таблицы значений с данными КопияОстаткиКапуста = ТаблицаТовары.Скопировать(МассивСтрок); // Копия выбранных строк таблицы значений (синтаксис отбора) СтруктураОтбора = Новый Структура("Номенклатура", "Капуста белокачанная"); КопияОстаткиКапуста = ТаблицаТовары.Скопировать(СтруктураОтбора); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// Удаление одной строки таблицы значений // поиск строки СтрокаКУдалению = ТаблицаТовары.Найти("Кондиционер для белья", "Номенклатура"); // проверка (нашли/не нашли) Если СтрокаКУдалению <> Неопределено Тогда // удаление строки из таблицы ТаблицаТовары.Удалить(СтрокаКУдалению); КонецЕсли; // Удаление нескольких строк таблицы значений СтруктураПоиска = Новый Структура("Номенклатура", "Капуста белокочанная"); МассивСтрокКУдалению = ТаблицаТовары.НайтиСтроки(СтруктураПоиска); Для каждого СтрокаКУдалению Из МассивСтрокКУдалению Цикл ТаблицаТовары.Удалить(СтрокаКУдалению); КонецЦикла; |
1 2 3 4 5 |
ТаблицаЦен.Сортировать("Цена Убыв, Товар Возр"); // Пример с использованием объекта сравнения Альфа = Новый СравнениеЗначений; ТаблицаЦен.Сортировать("Цена Убыв", Альфа); |
1 2 3 |
// Получить итог по колонке числового типа ОстатокВсего = ТаблицаТовары.Итог("Остаток"); Сообщить("Общий остаток всех товаров: " + ОстатокВсего); |
ВАЖНО! Исходная таблица заменяется результатом свертки.
1 2 3 4 |
// Свертка таблицы // Склад - колонка группировки (обязательный) // ВРезерве,ВНаличии,Остаток - колонки суммирования (необязательный) ТаблицаТовары.Свернуть("Склад", "ВРезерве,ВНаличии,Остаток"); |
Дерево значений
Дерево значений представляет собой динамически формируемый набор значений любого типа, похожий на таблицу значений с иерархией.
Отличие от таблицы значений:
- строки дерева значений могут образовывать иерархические структуры: каждая строка дерева может иметь набор подчиненных строк, каждая из подчиненных строк, в свою очередь, также может иметь набор подчиненных строк, и так далее.
При этом поиск значений, сортировка, получение итогов могут осуществляться либо по текущему уровню иерархии, либо включая все подчиненные.
COMSafeArray
COMSafeArray представляет собой объектную оболочку над многомерным массивом SAFEARRAY из COM. Позволяет создавать и использовать SAFEARRAY для обмена данными между COM-объектами.
ФиксированныйМассив
Неизменяемый массив, который заполняется системой при инициализации объектов данного типа или разработчиком, с помощью конструктора.
ФиксированнаяКолекция
Системная коллекция значений. Используется в качестве значений свойств других объектов. Заполняется системой при инициализации объектов данного типа.
Набор свойств этого объекта определяется в зависимости от контекста его использования и описан подробнее в описании тех свойств, где он используется.
Создать этот объект средствами встроенного языка нельзя.
ФиксированноеСоответствие
В качестве ключа может выступать любое значение (рекомендуется значение примитивного типа или другого типа, значение которого может только присваиваться, но не может менять свое содержимое).
Если при обращении к элементу коллекции с помощью оператора [], указан несуществующий ключ, будет вызвано исключение.
В то же время метод Получить, в параметре которого указан несуществующий ключ, возвращает значение Неопределено.
ФиксированнаяСтруктура
Представляет собой фиксированную коллекцию пар КлючИЗначение.
При этом ключ может быть только строковым и должен удовлетворять требованиям, предъявляемым к именованию переменных встроенного языка.
К значениям структуры можно обращаться как к свойствам объекта. При этом ключ используется как имя свойства.
Предназначен для использования в качестве значений параметров сеанса.