Оглавление
- Работа с абстрактным массивом
- Массивы и абстрактные типы данных
- Абстрактные алгоритмы
- Функции как объекты первого класса
- Сортировка массива
- Простые примеры использования
- Текучий интерфейс для абстрактного массива
- Мутации
- Конструктор абстрактного типа данных массив
- Функции первого порядка
- Пример повышенной сложности
- Формирование списка подсистем
- Реализация команды "Выбрать объекты подсистемы"
- Поиск выбранной подсистемы
- Формирование списка объектов метаданных по выбранной подсистеме
- Пометка объектов метаданных по выбранной подсистеме
- Поддержка работы модели в контексте Клиент
- Следующий пример работает как на клиенте, так и на сервере
- Пример использования оператора Спрямить (flat)
- Пример использования абстракций Диапазон и Срез
- Вывод
- Поставка
Массивы и абстрактные типы данных
Все объекты окружающего нас мира реального или виртуального состоят из списков свойств. Базовым типом данных, описывающим списки в 1С является массив.
В 1С есть и другие типы данных, хранящие списки. Список значений - узкоспециализированный тип под задачи преставления списков в интерфейсе. Другие типы данных, такие как Структура и Соответствие являются прототипами абстрактного типа данных известного как Словарь. В первом случае это Словарь, в котором сопоставлено текстовое значение ключа, а во втором мы имеем дело с чистым ассоциативным массивом.
В мире программирования известны и другие абстрактные типы данных: Стек, Очередь, Список. Однако и они вполне могут быть реализованы на базе работы с массивом в 1С.
Абстрактные алгоритмы
Массив в отличии от структуры данных, является абстрактным типом. На практике в работе с массивами выделяют следующие абстрактные алгоритмы: сортировка, преобразование, отбор и агрегирование.
Дело в том, что структура данных описывает определенную предметную область, а массив сам по себе не привязан к какой-либо области. Фактически имея базовый набор абстрактных алгоритмов любой исходный массив можно преобразовать в любую необходимую структуру данных. Если принять во внимание, что любой объект данных также можно представить в виде массива свойств, то получаем универсальные алгоритмы для решения любой задачи.
Функции как объекты первого класса
Однако абстрактные алгоритмы не были бы абстрактными, если бы их реальное поведение нельзя было определять в соответствии с решаемой задачей. В функциональном подходе определенное поведение функции можно определить через другую функцию.
Функциональный подход подразумевает, что в языке есть функции первого класса. Такие функции можно передавать в другие функции наравне с обычными типами данных. В 1С нет поддержки такого рода функций, однако похожий механизм можно реализовать через выражения на языке 1С.
Наличие оператора Вычислить позволяет выполнить выражение на языке 1С. Эту возможность я и предлагаю рассмотреть для реализации абстрактных алгоритмов по работе с массивами.
Сортировка массива
Чего мне сильно не хватает в массивах на 1С - это метода сортировки. Казалось бы можно сортировать списки, даже по значению, сортировать таблицы значений, а вот массивы - нет!
Возможно именно отсутствие метода сортировки для массивов и сподвигло меня в конечном итоге к поиску такого решения, как представлено здесь.
Алгоритмы сортировки уже известны давно. Мне не пришлось даже ничего программировать, и я воспользовался публикацией по данной теме. Дальше мне оставалось лишь обобщить алгоритм для абстрактных структур данных. Так у меня появилась функция Сравнить. И здесь я снова ничего не придумал, а взял готовое решение из других языков программирования :)
Первые эксперименты произвели на меня эффект - алгоритм реально работал! :) Так я пришел к универсальному решению для 1С, когда массив с любыми объектами можно сортировать. Для массива с элементами простых типов реализация работает в базовой библиотеке.
Простые примеры использования
Помимо сортировки в представленной библиотеке реализованы все основные абстрактные алгоритмы.
Конструктор
Фрукты = РаботаСМассивом.АТДМассив(СтрРазделить("вишня, арбузы, бананы", ", ", Ложь));
Фрукты.ДляКаждого("Сообщить(Элемент)");// [вишня, арбузы, бананы]
Сортировать (sort)
Фрукты.Сортировать();
Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы, вишня]
Фрукты.Сортировать("Сравнить(Б, А)");// обратный порядок
Фрукты.ДляКаждого("Сообщить(Элемент)");// [вишня, бананы, арбузы]
Отобрать (filter)
Фрукты.Отобрать("СтрНайти(Элемент, ""а"") > 0");
Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы]
Отобразить (map)
Фрукты.Отобразить("ВРег(Лев(Элемент, 1)) + Прав(Элемент, СтрДлина(Элемент) - 1)");
Фрукты.ДляКаждого("Сообщить(Элемент)");// [Арбузы, Бананы]
Преобразовать (reduce)
Количество = Фрукты.Преобразовать("Накопитель + 1", 0);
Сообщить(Количество);// 2
Если эти примеры вам показались слишком абстрактными и не понятными, то рекомендую на этом пока и остановиться. Следующий материал уже пойдет с повышенной сложностью (если что - я вас предупредил :]).
Текучий интерфейс для абстрактного массива
Следующим шагом, после реализации абстрактных алгоритмов работы с массивом стало создание объектной модели массива. Объектная модель позволяет работать с данными в функциональном стиле, когда данные на входе проходят цепочку преобразований и результат можно получить на выходе.
Объектная модель также позволяет хранить свое состояние. Получается некоторая смесь объектно-ориентированного и функциональных парадигм. Из ООП здесь хранение данных и методов работы с ними в одном объекте - модели, а из функционального - реализация абстрактных алгоритмов. И все это в рамках языка 1С!
Вот следующие примеры использования классического подхода и функционального при конструировании составного типа из строки и ссылки на справочник Номенклатуры:
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("СправочникСсылка. _ДемоНоменклатура "));
МассивТипов.Добавить(Тип("Строка"));
ПараметрыСтроки = Новый КвалификаторыСтроки(20);
ДопустимыеТипы = Новый ОписаниеТипов(МассивТипов, , ПараметрыСтроки);
Конструктор на основе абстрактного массива:
ДопустимыеТипы = Новый ОписаниеТипов(РаботаСМассивом.АТДМассив()
.Положить(Тип("СправочникСсылка._ДемоНоменклатура"))
.Положить(ОбщегоНазначения.ОписаниеТипаСтрока(20))
.ВМассив())
;
Чтобы еще более разобраться в преимуществах функциональной парадигмы разберем пример. Вначале решим задачу в классическом процедурном стиле, затем в функциональном.
Итак, на входе у нас имеется файл в формате похожем на упрощенный markdown. Необходимо на выходе сформировать отчет в формате табличного документа 1С.
В классическом подходе создадим цикл прохода по строкам файла. Для каждой строки определим область табличного документа и выведем её.
Тоже решение в функциональном стиле подразумевает на вход подать файл, а на выходе получить табличный документ. Чтобы не переусложнять на вход начальной функции подготовим массив строк исходного файла. Далее преобразуем массив строк в массив областей табличного документа и наконец выведем области в табличный документ.
Это достаточно простой пример, однако уже здесь можно выделять главную особенность функционального подхода от обычного алгоритма. Предположим у нас уже есть готовое решение в двух вариантах: процедурный и функциональный. На этапе тестирования требований выяснилось, что файл подразумевает наличие пустых строк. Способ решения в двух подходах будет различным.
В первом случае у нас имеется цельный алгоритм. Здесь применим подход черного ящика, который необходимо вскрыть, т.к. изменить нужно алгоритм внутри. В алгоритме нет строго выделения блоков по работе с данными, алгоритм в общем случае представлен монолитно.
В случае функционального подхода алгоритм представлен последовательностью вызовов функций. Само решение формируется путем преобразования входа в выход последовательно от первой до последней функций. Все промежуточные варианты данных на стыке функций по сути и являются точками встраивания для изменения конечного результата. В данном примере перед формированием областей табличного документа добавим вызов функции фильтрации Отобрать для непустых строк.
Функциональный стиль позволяет представлять цельный алгоритм в виде конвейера преобразований. При таком подходе модификация алгоритма заключается в добавлении в цепочку преобразований дополнительных функций. При этом место добавления диктуется не структурой алгоритма, а структурой данных на данном этапе при передаче данных от одной функции к другой.
Пример решения в функциональном стиле:
Функция ТекстВОбласть(Элемент, Параметры) Экспорт
ИмяОбласти = Лев(Элемент, 2);
Если Параметры.Области.Найти(ИмяОбласти) <> Неопределено Тогда
Область = Параметры.ПолучитьОбласть(ИмяОбласти);
Область.Параметры.Текст = Прав(Элемент, СтрДлина(Элемент) - 4);
Иначе
Область = Параметры.ПолучитьОбласть("Строка");
Область.Параметры.Текст = Элемент;
КонецЕсли;
Возврат Область;
КонецФункции
Функция СформироватьОписание()
ТабличныйДокумент = Новый ТабличныйДокумент;
Текст = ПолучитьМакет("README").ПолучитьТекст();
Макет = ПолучитьМакет("Макет");
РаботаСМассивом.АТДМассив(СтрРазделить(Текст, Символы.ВК + Символы.ПС, Ложь))
.Отобрать("НЕ ПустаяСтрока(Элемент)")
.Отобразить("Контекст.ТекстВОбласть(Элемент, Параметры)", ЭтотОбъект, Макет)
.Положить(Макет.ПолучитьОбласть("Разделитель"))
.ДляКаждого("Контекст.Вывести(Элемент)", ТабличныйДокумент)
;
Возврат ТабличныйДокумент;
КонецФункции
Текст описания
h1 Работа с массивом как с абстрактным типом данных на 1С
Реализована библиотека по работе с массивом. В библиотеке доступны абстрактные функции: Отобрать (filter), НайтиЭлемент (find), Сортировать (sort), Отобразить (map), Преобразовать (reduce), Взять (pop), Положить (push), ДляКаждого (forEach).
Функции библиотеки доступны в серверном и клиентском контекстах.
Реализована также и объектная модель АТД массива. Объектная модель позволяет использовать при работе с АТД массивом текучий интерфейс.
Объектная модель доступна только в серверном контексте.
h1 Примеры
h2 Конструктор
Фрукты = Общий.АТДМассив(СтрРазделить("вишня, арбузы, бананы", ", ", Ложь));
Фрукты.ДляКаждого("Сообщить(Элемент)");// [вишня, арбузы, бананы]
h2 Сортировать (sort)
Фрукты.Сортировать();
Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы, вишня]
h2 Отобрать (filter)
Фрукты.Отобрать("СтрНайти(Элемент, ""а"") > 0");
Фрукты.ДляКаждого("Сообщить(Элемент)");// [арбузы, бананы]
h2 Отобразить (map)
Фрукты.Отобразить("ВРег(Лев(Элемент, 1)) + Прав(Элемент, СтрДлина(Элемент) - 1)");
Фрукты.ДляКаждого("Сообщить(Элемент)");// [Арбузы, Бананы]
h2 Преобразовать (reduce)
Количество = Фрукты.Преобразовать("Накопитель + 1", 0);
Сообщить(Количество);// 2
Отчет
Мутации
Мутации данных это всегда побочный результат работы грязных функций. В функциональной парадигме принято избегать мутаций. Чистые функции без побочных эффектов легко тестируются, могут безопасно использоваться при параллельных вычислениях. Обратной стороной медали являются менее эффективный расход ресурсов: избыточное использование памяти и снижение производительности. Однако последнее, как показывает общепризнанная практика, зачастую не является критичным, но это уже не является темой данной публикации.
Стоит заметить, что в некоторых случаях "побочный эффект" является и результатом работы функции. Но тут уж ничего не поделаешь: сложности тестирования и распараллеливания вам обеспечены :)
В предложенной реализации абстрактных алгоритмов работы с массивом я придерживался сложившейся практики в других языках. Все функции, за исключением Сортировать, Положить, Взять - являются чистыми.
Алгоритм сортировки является исключением из правила и является "грязным". Это сделано из соображений экономии памяти. Здесь я не стал отступать от общей практики распространенной на данный момент в других языках. Наверно это продиктовано не только из соображений экономии памяти, но и тем, что сами данные при сортировке не меняются, а изменение порядка элементов не является критичным побочным эффектом в большинстве случаев.
Конструктор абстрактного типа данных массив
Для работы с объектной моделью абстрактного массива необходимо вызвать функцию общего модуля АТДМассив(). В качестве параметра инициализации модели можно передать любую коллекцию, поддерживающую метод обхода элементов ДляКаждого. Обычно абстрактные алгоритмы сразу можно применять к такой коллекции, за исключением метода Сортировать. Последнее связано с тем, что функция сортировки является мутирующей и непосредственно изменяет массив, а значит рассчитана на работу с типом данных Массив.
Для снятия ограничения на работу мутирующих алгоритмов можно использовать метод Массив(). Этот метод преобразует коллекцию в массив элементов коллекции и дальнейшая работа уже может быть продолжена с чистым массивом элементов.
Коллекция может быть преобразована в массив также после использования одной из чистых абстрактных функций. Это возможно потому, что результатом абстрактной функции является массив. Исключением пожалуй здесь может быть функция Преобразовать (map), результатом которой может быть объект любого типа.
Функции первого порядка
Абстрактные алгоритмы потому и являются абстрактными, что содержат лишь часть общего алгоритма и используют в своей работе алгоритмы переданных им в качестве параметров функций. Однако встроенный язык 1С не содержит такого типа данных как Функция!
Несмотря на отсутствие в языке 1С функций как типа некоторые объекты платформы используют в качестве параметров имя функции и переданный контекст исполнения. Так обратные вызовы в 1С реализованы через использование объекта Описание оповещения, в конструктор которого передаются имя функции и контекст. Дополнительно в функцию обратного вызова можно передать параметры.
В предлагаемом подходе в абстрактные алгоритмы передается не просто имя функции, а выражение для вычисления. Такой подход позволяет не ограничиваться определенным интерфейсом функции, а использовать в каждом случае свой, наиболее подходящий для решения в задаче. Кроме того, выражение может вовсе не содержать вызов функции! В последнем случае мы практически получаем вариант анонимной функции.
Пример повышенной сложности
В следующем примере я постарался отразить возможные варианты использования модели по максимуму. Задача имеет практическое применение. Представленное решение естественно не единственное, но в данном исполнении хорошо иллюстрирует функциональный подход.
Пример взят из обработки формирования сценария выгрузки данных VanessaAutomation. Мне необходимо было сделать доработку для выделения в выгрузку объектов метаданных по определенной подсистеме, включая все подчиненные.
В демо-обработку я вынес алгоритм заполнения метаданных из обработки Ванессы. На форму добавил выбор подсистемы и команду "Выбрать метаданные по подсистеме".
На примере реализации команд "Заполнить подсистемы" и "Выбрать метаданные по подсистеме" я продемонстрирую использование абстрактных функций, функций первого порядка.
Формирование списка подсистем
Начнем с простого примера реализации команды "Заполнить подсистемы". Всю реализацию я буду демонстрировать с использованием модели абстрактного массива, а значит все выполнение будет у меня в контексте сервера.
Итак задача: необходимо заполнить массив полных имен по всем подсистемам метаданных. Для этого вызовем конструктор абстрактного массива с параметром верхнего узла Метаданные.Подсистемы.
Следующая наша функция Преобразовать на вход получает выражение функции контекста ДополнитьПодсистемыПоИмени с начальной инициализацией пустым абстрактным массивом. На выходе преобразования у нас получится также абстрактный массив. Это согласуется с тем, что начальное значение тоже является абстрактным массивом. В связи с последним обстоятельством цепочку функций можно продолжить в стиле текучего интерфейса.
Еще одной особенностью переданной функции является то, что она содержит в себе рекурсию через собственное преобразование в абстрактном массиве.
Следующая наша функция - ДляКаждого. Здесь в качестве функции первого порядка использована анонимная функция выполняющая метод списка выбора Добавить() для каждого элемента абстрактного массива. Побочным результатом последнего вызова будет заполненный список подсистем для выбора.
Функция ДополнитьПодсистемыПоИмени(Элемент, Накопитель, Путь = "") Экспорт
ТекущийПуть = Путь + "\" + Элемент.Имя;
Накопитель.Положить(ТекущийПуть);
Если Элемент.Подсистемы.Количество() = 0 Тогда
Возврат Накопитель;
КонецЕсли;
Подсистемы = РаботаСМассивом.АТДМассив(Элемент.Подсистемы)
.Преобразовать("Контекст.ДополнитьПодсистемыПоИмени(Элемент, Накопитель, Параметры)", РаботаСМассивом.АТДМассив(), ЭтотОбъект, ТекущийПуть)
.ВМассив()
;
Накопитель.ДополнитьМассив(Подсистемы);
Возврат Накопитель;
КонецФункции
Процедура КомандаЗаполнитьПодсистемыНаСервере()
СписокВыбора = Элементы.ВыбраннаяПодсистема.СписокВыбора;
СписокВыбора.Очистить();
РаботаСМассивом.АТДМассив(Метаданные.Подсистемы)
.Преобразовать("Контекст.ДополнитьПодсистемыПоИмени(Элемент, Накопитель)", РаботаСМассивом.АТДМассив(), ЭтотОбъект)
.ДляКаждого("Контекст.Добавить(Элемент)", СписокВыбора)
;
КонецПроцедуры
На этом заполнение списка подсистем завершено! Перейдем к следующей команде: "Выбрать объекты подсистемы"
Реализация команды "Выбрать объекты подсистемы"
Алгоритм команды условно поделен на три части: поиск подсистемы по полному имени, формирование списка объектов метаданных подсистемы и всех ей подчиненных, пометка выбора в дереве объектов метаданных. Рассмотрим их отдельно.
Поиск выбранной подсистемы
На входе у нас полный путь выбранной подсистемы. В конструктор абстрактного массива передадим массив составляющих пути. В следующей абстрактной функции Преобразовать передадим в качестве анонимной функции метод подсистемы Найти. На выходе преобразования будет объект метаданных Выбранная подсистема.
// Поиск подсистемы по полному имени
ОбъектМетаданныхВыбраннаяПодсистема = РаботаСМассивом.АТДМассив(СтрРазделить(ВыбраннаяПодсистема, "\", Ложь))
.Преобразовать("Накопитель.Подсистемы.Найти(Элемент)", Метаданные)
;
Формирование списка объектов метаданных по выбранной подсистеме
Следующим на очереди будет задача определить список имен объектов метаданных выбранной подсистемы, включая все подчиненные ей. Для этого создадим абстрактный массив с конструктором по умолчанию. Далее методом Положить() поместим в массив саму выбранную подсистему. Абстрактным методом Преобразовать последовательно сформируем вначале абстрактный массив с подчиненными подсистемами, затем преобразуем подсистемы в массив объектов метаданных этих подсистем. Последовательным вызовом абстрактного метода Отобразить вначале преобразуем массив объектов в массив структур {Тип, Имя}, а затем в массив наименований по шаблону "Тип.Имя" - теперь у нас сформирован полный список имен объектов метаданных по выбранной подсистеме, включая подчиненные ей.
Последнее преобразование можно было бы сделать и одно, однако во втором преобразовании используется внешний параметр по трансляции типа в английский эквивалент (TypeTranslation - это соответствие русского наименования типа объектов метаданных (Справочник, Константы и т.д.) в английский вариант).
// Добавляет подсистемы рекурсивно
Функция ДополнитьПодсистемы(Элемент, Накопитель) Экспорт
Накопитель.Положить(Элемент);
Если Элемент.Подсистемы.Количество() = 0 Тогда
Возврат Накопитель;
КонецЕсли;
Подсистемы = РаботаСМассивом.АТДМассив(Элемент.Подсистемы)
.Преобразовать("Контекст.ДополнитьПодсистемы(Элемент, Накопитель)", РаботаСМассивом.АТДМассив(), ЭтотОбъект)
.ВМассив()
;
Накопитель.ДополнитьМассив(Подсистемы);
Возврат Накопитель;
КонецФункции
// Добавляет состав метаданных подсистемы
Функция ДополнитьСостав(Элемент, Накопитель) Экспорт
Если Элемент.Состав.Количество() = 0 Тогда
Возврат Накопитель;
КонецЕсли;
Накопитель.ДополнитьМассив(Элемент.Состав, Истина);
Возврат Накопитель;
КонецФункции
// Разбивает полное имя объекта метаданных
Функция РазделитьПолноеИмя(Элемент) Экспорт
Состав = СтрРазделить(Элемент.ПолноеИмя(), ".");
Возврат Новый Структура("Type, Name", Состав[0], Состав[1]);
КонецФункции
// Формирование списка объектов метаданных по выбранной подсистеме
ОбъектыМетаданных = РаботаСМассивом.АТДМассив()
.Положить(ОбъектМетаданныхВыбраннаяПодсистема)
.Преобразовать("Контекст.ДополнитьПодсистемы(Элемент, Накопитель)", РаботаСМассивом.АТДМассив(), ЭтотОбъект)
.Преобразовать("Контекст.ДополнитьСостав(Элемент, Накопитель)", РаботаСМассивом.АТДМассив(), ЭтотОбъект)
.Отобразить("Контекст.РазделитьПолноеИмя(Элемент)", ЭтотОбъект)
.Отобразить("СтрШаблон(""%1.%2"", Контекст[Элемент.Type], Элемент.Name)", TypeTranslatiton)
;
Пометка объектов метаданных по выбранной подсистеме
Когда мы получили массив объектов метаданных в формате "Тип.Имя" останется найти их по этому имени в дереве метаданных и поставить по ним пометку выбора.
Предварительно необходимо сбросить все пометки выбора. Для этого необходимо инициализировать массив строками верхнего уровня, которые соответствуют типам метаданных: Справочники, Документы и т.д. Следующим преобразованием получим абстрактный массив подчиненных строк, содержащих уже имена объектов метаданных в формате "Тип.Имя" и для них также сбросим пометку выбора.
И последнее. Сделаем отбор по условию вхождения в массив, полученный на предыдущем этапе формирования списка выбранных объектов. По отобранным строкам проставим признак выбора.
// Добавляет только подчиненные строки дерева метаданных
Функция ДополнитьПодчиненныеСтроки(Элемент, Накопитель) Экспорт
Строки = Элемент.ПолучитьЭлементы();
Если Строки.Количество() = 0 Тогда
Возврат Накопитель;
КонецЕсли;
Накопитель.ДополнитьМассив(Строки);
Возврат Накопитель;
КонецФункции
// Обработка дерева объектов метаданных: пометка объектов метаданных по выбранной подсистеме
РаботаСМассивом.АТДМассив(MetadataList.ПолучитьЭлементы())
.ДляКаждого("Элемент.Use = Ложь")
.Преобразовать("Контекст.ДополнитьПодчиненныеСтроки(Элемент, Накопитель)", РаботаСМассивом.АТДМассив(), ЭтотОбъект)
.ДляКаждого("Элемент.Use = Ложь")
.Отобрать("Контекст.Найти(Элемент.FullName) <> Неопределено", ОбъектыМетаданных.ВМассив())
.ДляКаждого("Элемент.Use = Истина")
;
Поддержка работы модели в контексте Клиент
Теперь модель абстрактного массива доступна в любом контексте.
Конструктор модели перенесен в модуль РаботаСМассивом. Модуль Общий удален.
Убрана прямая доступность к элементам массива. Для установки элементов теперь можно использовать либо конструктор, либо оператор Установить(Коллекция).
Добавлены терминальные операторы ВМассив(), ВФиксированныйМассив().
Элементы.ДоговорКонтрагентов.СвязиПараметровВыбора = РаботаСМассивом.АТДМассив()
.Положить(Новый СвязьПараметраВыбора("Отбор.Владелец", "Объект.Организация"))
.ВФиксированныйМассив()
;
ДопустимыеТипы = Новый ОписаниеТипов(РаботаСМассивом.АТДМассив()
.Положить(Тип("СправочникСсылка._ДемоНоменклатура"))
.Положить(ОбщегоНазначения.ОписаниеТипаСтрока(20))
.ВМассив())
;
Добавлены методы: СортироватьПо, ДополнитьМассив.
Следующий пример работает как на клиенте, так и на сервере
Сотрудники = РаботаСМассивом.АТДМассив()
.Положить(Новый Структура("Фамилия, Имя, Отчество", "Иванов", "Иван", "Иванович"))
.Положить(Новый Структура("Фамилия, Имя, Отчество", "Иванов", "Иван", "Гермагенович"))
.Положить(Новый Структура("Фамилия, Имя, Отчество", "Савельев", "Иван", "Иванович"))
.Положить(Новый Структура("Фамилия, Имя, Отчество", "Андреев", "Иван", "Иванович"))
.Положить(Новый Структура("Фамилия, Имя, Отчество", "Андреев", "Андрей", "Андреевич"))
;
Сотрудники.СортироватьПо("Фамилия, Имя, Отчество");
Сотрудники.ДляКаждого("Сообщить(СтрШаблон(""%1 %2 %3"", Элемент.Фамилия, Элемент.Имя, Элемент.Отчество))"); // [Андреев Андрей Андреевич, Андреев Иван Иванович, Иванов Иван Гермагенович, Иванов Иван Иванович, Савельев Иван Иванович]
Пример с БСП:
Файлы = Новый Массив;
РаботаСФайлами.ЗаполнитьПрисоединенныеФайлыКОбъекту(СсылкаНаДокумент, Файлы);
СсылкаНаПрисоединенныйФайл = РаботаСМассивом.АТДМассив(Файлы)
.Отобрать("СтрНайти(Элемент.Наименование, ""##БДДС##"") > 0")
.Отобрать("НЕ Элемент.ПометкаУдаления")
.Взять()
;
Пример использования оператора Спрямить (flat)
МетаданныеРасширений = РаботаСМассивом.АТДМассив(СтрРазделить("Константы, Справочники, Документы, РегистрыСведений, РегистрыНакопления", ", ", Ложь))
.Отобразить("РаботаСМассивом.АТДМассив(Метаданные[Элемент]).Отобрать(""Элемент.РасширениеКонфигурации() <> Неопределено"").ВМассив()")
.Спрямить()
.Отобразить("Новый Структура(""ПолноеИмя, Расширение"", Элемент.ПолноеИмя(), Элемент.РасширениеКонфигурации().Имя)")
.Отобрать("НЕ СтрНачинаетсяС(Элемент.ПолноеИмя, ""Константа."")")
.ВМассив()
;
Сообщить(ОбщийКлиентСервер.ОбъектВJSON(МетаданныеРасширений));
Пример использования абстракций Диапазон и Срез
// Создание массива чисел от 1 до 100
ИсходныйМассив = РаботаСМассивом.Диапазон(1, 101);
Сообщить(ОбщийКлиентСервер.ОбъектВJSON(ИсходныйМассив));
// Формирование подмассивов по 10 чисел
Шаг = 10;
Для Каждого Индекс Из РаботаСМассивом.Диапазон(0, 100, Шаг) Цикл
Срез = РаботаСМассивом.Срез(ИсходныйМассив, Индекс, Индекс + Шаг);
Сообщить(ОбщийКлиентСервер.ОбъектВJSON(Срез));
КонецЦикла;
Вывод
В своей статье я хотел продемонстрировать, что абстрактные типы в 1С все-таки возможны .
Поставка
Решение доступно на github. Есть небольшая зависимость от общий функций БСП.
Объект метаданных | Контекст | Комментарий |
---|---|---|
ОбщийМодуль.РаботаСМассивом | Клиент, Сервер | Библиотека работы с абстрактным массивом |
ОбщийМодуль.РаботаСКоллекцией | Клиент, Сервер | Описание запланировано |
ОбщийМодуль.РаботаСМножеством | Клиент, Сервер | Абстрактные типы, множества, очереди. Примеры использования |
ОбщийМодуль.РаботаСОчередью | Клиент, Сервер | Абстрактные типы, множества, очереди. Примеры использования |
Обработка.АТДМассив | Клиент, Сервер | Реализует объектную модель абстрактного массива |
ВнешняяОбработка.ДемоАТДМассив | См. в демо-базе в разделе "Библиотека подсистем КА Демо" |