Новые конструкторы коллекций

20.12.19

Разработка - Универсальные функции

Некоторые идеи, как добавить "синтаксического сахара" при создании коллекций в языке 1С.

Мне не нравятся стандартные конструкторы коллекций 1С.

И хотя язык давно застыл в своем развитии, можно добавить "синтаксического сахара" своими силами. Сразу к делу:

 

Массив

    Массив = Новый Массив;
    Массив.Добавить("Первый");
    Массив.Добавить("Второй");
    Массив.Добавить("Третий");

 

Что здесь можно придумать? Для частных случаев, когда массив состоит из строк, можно так:

   

Массив = СтрРазделить("Первый,Второй,Третий");

 

Но! Когда строка длинная, хочется сделать вот так:

 

    Массив = СтрРазделить("Первый,Второй,Третий,
                            |Четвертый, Пятый");

 

Проблема в том, что так делать нельзя - в одном из элементов массива появляется перенос строки :(

Для других типов ничего в голову не приходит. А хочется вот так:

 

    Массив = Массив(1, "Второй", Неопределено, "Четвертый");

 

Напишем такую функцию.

1) Очевидно, она должна находится в глобальном модуле для удобного использования.

2) Также ее имя должно быть уникально для всей конфигурации (именно для этого нужно добавить ей какой нибудь странный префикс, например "HS")

3) Она должна принимать достаточное количество параметров на вход для добавления в создаваемый массив. При этом не обязывать их передавать (больше 1).

Реализация такого метода - под спойлером

 
 Реализация HSМассив

 

Структура

Канонический конструктор:

 

Структура = Новый Структура("Ключ1,Ключ2,Ключ3", "Значение1", "Значение2", "Значение2");

 

Для простых случаев этого достаточно. Но в сложных, когда нужно задать много параметров и не испортить читаемость кода, лучше сделать так:

 

    Структура = Новый Структура;
    Структура.Вставить("Ключ1", "Значение1");
    Структура.Вставить("Ключ2", "Значение2");
    Структура.Вставить("Ключ3", "Значение3");

 

Напротив ключа - значение. Много строк, но читать такой код гораздо проще и нет кошмара пропущенных запятых. Плохой пример:

 

   Структура = Новый Структура("Ключ1,Ключ2,Ключ3",,, "Значение3");

 

Как совместить краткость и читаемость. Можно попробовать так:

 

    Структура = Структура(
                        "Ключ1", "Значение1",
                        "Ключ2", "Значение2",
                        "Ключ3", "Значение3");

 

Т.е. задавать пары Ключ-Значение с новой строки. Реализовать можно по аналогии с массивом

 
 Реализация HSСтруктура

 

Таблица значений

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

 

   СтруктураКолонок = HSСтруктура(
                            "ХешЗапроса",       HSОписаниеТиповСтрока(40),    // хеш запроса для поиска в таблице
                            "ТекстЗапроса",     HSОписаниеТиповСтрока(),      // текст запроса
                            "Количество",       HSОписаниеТиповЧисло(15, 0),  // количество выполнений запроса
                            "Время",            HSОписаниеТиповЧисло(15, 0),  // общее время выполнений запроса, мс.
                            "СамыйМедленный");
   ТаблицаЗамеров = HSТаблицаЗначений(СтруктураКолонок);    

                        

Т.е. создаем структуру из пар Имя колонки - тип колонки и создаем таблицу. Реализацию этого метода оставим за скобками, как очевидную. Методы создания описания типов - тоже

 

Спасибо за внимание! Чистого кода, приятного программирования.

См. также

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

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

23.06.2024    7448    bayselonarrend    20    

154

Универсальные функции Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Благодаря этим пяти строчкам можно больше не заморачиваться с загрузкой из внешних файлов. Пользуюсь везде, всегда и постоянно.

21.05.2024    20126    dimanich70    81    

144

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

Вы все еще регистрируете изменения только на Планах обмена и Регистрах сведений?

11.12.2023    11223    dsdred    44    

130

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

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

06.10.2023    23759    SeiOkami    48    

135

WEB-интеграция Универсальные функции Механизмы платформы 1С Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    14732    YA_418728146    7    

166

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    3580    56    progmaster    8    

4

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

Рассмотрим новую возможность 8.3.24 и как её можно эффективно использовать

27.06.2023    25525    SeiOkami    31    

113
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. acanta 20.12.19 17:56 Сейчас в теме
Спасибо большое. И ещё в свете программирования управляемых форм с их структурами, гуляющими между клиентом и сервером, сравнение структур, имхо, нашли бы куда применить.
15. Sashares 35 23.12.19 11:58 Сейчас в теме
(0)
Что здесь можно придумать? Для частных случаев, когда массив состоит из строк, можно так:
Массив = СтрРазделить("Первый,Второй,Третий");

Но! Когда строка длинная, хочется сделать вот так:
Массив = СтрРазделить("Первый,Второй,Третий,
|Четвертый, Пятый");


Ну, во-первых, в таком виде это в принципе не работает, т.к. необходимо указать второй параметр в СтрРазделить.
А, во-вторых, что мешает во втором параметре указать несколько символов - запятую, пробел, | и др?
16. VmvLer 23.12.19 13:30 Сейчас в теме
(15) просто тс не читает СП и ниасилил всю мощь системных методов, зато лепить
условные кейсы а ля бейсик 70-х - мастак.
18. user700211_a.straltsou 227 23.12.19 13:50 Сейчас в теме
(15) Вы конечно же правы, правильный вызов будет такой

СтрРазделить("Первый,Второй,Третий,
|Четвертый, Пятый", "," + Символы.ПС, Ложь);

Красиво? И это только для частного случая со строками. По существу заметки это ничего не меняет

А по существу конечно же понятно, почему авторы языка 1С сделали конструктор массива вида

Новый Массив(<КоличествоЭлементов1>,...,<КоличествоЭлементовN>)

Это древний стиль C/С++, где нужны возможности оптимизации по выделению памяти (выделяем память сразу, а не при добавлении элементов).
Только большинство разработчиков на 1С, вроде (16) осилили мощь системных методов и никогда конструктор массива с инициализацией памяти не используют.
sulfur17; +1 Ответить
19. VmvLer 23.12.19 14:30 Сейчас в теме
(18) большинство разработчиков 1С выросли на древнем стиле C/С++ и владеют способностями в системном программировании, в том числе способностями по прямому доступу к пямяти - именно поэтому на всяких оптимизаторов с их костылями смотрят как на слонов в посудной лавке.
2. ixijixi 1913 21.12.19 18:59 Сейчас в теме
Вот тут автора поклевали маленько за этот подход, 2012 год, на минуточку!
user1274438; +1 Ответить
3. AtPups000 21.12.19 23:53 Сейчас в теме
4. vadim1011985 101 22.12.19 11:19 Сейчас в теме
Я вот не вижу никакого «синтаксического сахара» в таком подходе хотя бы той причине что на примере массива - массив получится ограниченный по длине и это надо помнить. Сколько параметров прописали -столько и можем загнать , а если нужен массив на 1000 элементов. Тоже самое и по структуре.
user1274438; Sashares; pm74; +3 1 Ответить
6. dhurricane 23.12.19 09:18 Сейчас в теме
(4) Автор ведь не предлагает использовать приведенные конструкции повсеместно. Там, где они будут наглядны, в частности при создании небольших коллекций, там и используйте.

И признаться, я слабо себе представляю, в каких задачах Вам может потребоваться инициализация массива из 1000 заранее известных элементов.
9. vadim1011985 101 23.12.19 10:35 Сейчас в теме
(6) ну а где они будут нагляднее ? Где есть 3-5 значений , чем тогда от стандартного отличается - только тем что записано в одну строку ? Зато имеем лишний вызов функции ( которая в себе имеет стандартный конструктор массива )
+ скатерть блоков Если - конецЕсли для проверки каждого из параметров т.е. передали 2 параметра а проверили все 15.
user1274438; Sashares; +2 Ответить
13. dhurricane 23.12.19 10:47 Сейчас в теме
(9)
ну а где они будут нагляднее ? Где есть 3-5 значений
Да.
чем тогда от стандартного отличается - только тем что записано в одну строку ?
Да.
Зато имеем лишний вызов функции ( которая в себе имеет стандартный конструктор массива )
И что в этом плохого?
+ скатерть блоков Если - конецЕсли для проверки каждого из параметров т.е. передали 2 параметра а проверили все 15.
Ну скатерть и скатерть. Лежит себе тихонечко в отдельном модуле, никому глаза не мозолит.
10. user700211_a.straltsou 227 23.12.19 10:36 Сейчас в теме
(5) В точку, префикс лучше в той же кодировке сделать. А если кто-то себе в таком виде и скопирует (не переосмысливая) - пусть мучается, потому статья о идеях, а не готовом коде
12. dhurricane 23.12.19 10:43 Сейчас в теме
(10) Вы не тому ответили, но поддерживаю. :)
8. user700211_a.straltsou 227 23.12.19 10:28 Сейчас в теме
(4) Познакомьтесь, например, с СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку в любой типовой.
35. sulfur17 66 02.12.20 17:32 Сейчас в теме
(4)
и это надо помнить

зачем помнить, если вам конфигуратор сообщит об ошибке когда вы передадите больше параметров чем можно?
И в таком случае можно будет сразу доработать конструктор.

А про массив на 1000 элементов вообще на анекдот похоже))
Кто в здравом уме будет создавать такой массив конструктором?
5. sulfur17 66 23.12.19 09:10 Сейчас в теме
Мне все очень нравится кроме префикса HS. Чтобы набрать имя функции придется переключать язык.
7. Cерый 26 23.12.19 10:03 Сейчас в теме
Как Вы видите развитие языка? Модели СКД, диаграмм крайне замкнуты, практически вещи в себе, ООП в качестве следующего шага непредставим ...
11. user700211_a.straltsou 227 23.12.19 10:42 Сейчас в теме
(7) ООП не нужен. Я бы думал в том же русле, в котором Kotlin расширяет Java.
Функции-расширения, свойства-расширения, работа с коллекциями, лямбды - все эти идеи вписались бы в язык платформы 1С, ничего не ломая концептуально
22. Vortigaunt 97 25.12.19 11:37 Сейчас в теме
(7) Языку 1С реально есть куда развиваться. Стоит хотя бы на базовом уровне ознакомиться с другими языками, чтобы возжелать некоторых плюшек:
- Именованные параметры: как же утомляет определять десяток параметров, а потом считать запятые при вызове функции. Структуры помогают, но не дают такой наглядности.
- Валидация, типизация: давно уже хочется определять типы входных параметров и тип возвращаемого значения, да и чтоб конфигуратор проверял, что я хоть что-то возвращаю. Столько бы ошибок сразу же отбросилось.
- Возврат функциями нескольких значений (но это как "сахар", всегда можно выкрутиться возвратом структуры)
- Передача параметрами не только примитивов и объектов, но и функций с процедурами.
- Встроенный генератор прогрессии для цикла как в Пайтоне (хотя его очень просто и самому написать)
14. VmvLer 23.12.19 10:52 Сейчас в теме
да ерунда!

это не сахар, а брага - после кода в такой стилистике жуткое похмелье и есть
желание найти автора и предложить ему хороший самогон.
user1274438; pm74; +2 1 Ответить
17. Automatik 959 23.12.19 13:49 Сейчас в теме
Согдасен. Пора бы уже руководству 1С задуматься о дальнейшем развитии языка!
20. DrAku1a 1745 25.12.19 09:21 Сейчас в теме
Конструкции вида "Структура.Вставить(..." и Массив."Добавить(" в отдельных строках - более наглядны. Их переделывать не стоит.
Более интересно получение элемента структуры с параметром по-умолчанию (т.е. если нет свойства в структуре - вернуть параметр по-умолчанию). Также, полезны HSОписаниеТиповСтрока, HSОписаниеТиповЧисло - которые, вроде, только упоминаются в коде. Вроде, в БСП уже что-то подобное есть. Метод создания таблиц - тоже интересен, но и его следует поискать в БСП.
И это... ловите от меня велосипед:
Функция ЗапроситьСоответствие(ТекстЗапроса, ПараметрыЗапроса=Неопределено, ИмяПоляКлюч="Ключ", ИмяПоляЗначение="Значение")
	
	Запрос = новый Запрос(ТекстЗапроса);
	Если ПараметрыЗапроса<>неопределено Тогда
		Для каждого Параметр из ПараметрыЗапроса Цикл
			Запрос.УстановитьПараметр(Параметр.Ключ, Параметр.Значение);
		КонецЦикла;
	КонецЕсли;
	РезультатЗапроса = Запрос.Выполнить();
	
	Ответ = новый Соответствие;
	Если РезультатЗапроса.Пустой() Тогда
		Возврат Ответ;
	КонецЕсли;
	
	Выборка = РезультатЗапроса.Выбрать(ОбходРезультатаЗапроса.Прямой);
	Пока Выборка.Следующий() Цикл
		Ответ.Вставить(Выборка[ИмяПоляКлюч], Выборка[ИмяПоляЗначение]);
	КонецЦикла;
	
	Возврат Ответ;
	
КонецФункции
Показать
Применяю при необходимости закэшировать небольшой справочник или что-то специфическое. В основном, при загрузке данных.
//Пример: 
	СоотвОрганизации = ЗапроситьСоответствие("ВЫБРАТЬ РАЗЛИЧНЫЕ
	                                         |	Организации.ИНН КАК ИНН,
	                                         |	Организации.Ссылка КАК Организация
	                                         |ИЗ
	                                         |	Справочник.Организации КАК Организации
	                                         |ГДЕ
	                                         |	НЕ Организации.ПометкаУдаления
	                                         |	И Организации.ИНН <> """"",, "ИНН", "Организация");
Показать
21. ImHunter 327 25.12.19 09:51 Сейчас в теме
// Функция - Новый массив
// Создание нового массива согласно переданным параметром. Первый параметр используется всегда.
// Параметры:
//  Парам1	 - 	 - 
//  Парам2	 - 	 - 
//  Парам3	 - 	 - 
//  Парам4	 - 	 - 
//  Парам5	 - 	 - 
//  Парам6	 - 	 - 
//  Парам7	 - 	 - 
//  Парам8	 - 	 - 
//  Парам9	 - 	 - 
//  Парам10	 - 	 - 
// 
// Возвращаемое значение:
//  Массив - Созданный массив
//
Функция НовыйМассив(Парам1, Парам2 = Неопределено, Парам3 = Неопределено, Парам4 = Неопределено, Парам5 = Неопределено, 
		Парам6 = Неопределено, Парам7 = Неопределено, Парам8 = Неопределено, Парам9 = Неопределено, Парам10 = Неопределено) Экспорт
	
	Результат = Новый Массив;
	Результат.Добавить(Парам1);
	ВставлятьЗначения = Ложь;
	
	Если Парам10<>Неопределено Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам10);
	КонецЕсли;
	
	Если Парам9<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам9);
	КонецЕсли;
	
	Если Парам8<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам8);
	КонецЕсли;
	
	Если Парам7<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам7);
	КонецЕсли;
	
	Если Парам6<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам6);
	КонецЕсли;
	
	Если Парам5<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам5);
	КонецЕсли;
	
	Если Парам4<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам4);
	КонецЕсли;
	
	Если Парам3<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам3);
	КонецЕсли;
	
	Если Парам2<>Неопределено Или ВставлятьЗначения Тогда 
		ВставлятьЗначения = Истина;
		Результат.Вставить(1, Парам2);
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции
Показать
23. user700211_a.straltsou 227 26.12.19 09:06 Сейчас в теме
(21) Значение параметров по умолчанию "Неопределено" - это проблема.
24. ImHunter 327 26.12.19 09:17 Сейчас в теме
(23) Есть такая полу-проблема. Частично решена тем, что значения Неопределено вполне вставляются, если после них происходит вставка !=Неопределено.
Да и ситуаций, когда сплошняком Неопределено нужно вставить, крайне мало. А хардкодить какие-то неплатформенные значения - ну не люблю, коробит как-то.
25. DrAku1a 1745 09.01.20 05:08 Сейчас в теме
(24) Замените Неопределено на NULL - он намного реже используется. И не очень понятна логика обратного порядка от Парам10 к Парам2, со вставкой... Зачем так сделано?
26. ImHunter 327 09.01.20 06:28 Сейчас в теме
(25) Насчет использования NULL - тоже думал. Но решил не использовать. И уже в своем коде переделывать не буду - маловероятно, но что-то может и косякнуть.
Насчет обратного перехода - это для того, чтобы все же можно было Неопределено вставлять в массив, если после них есть значения <>Неопределено.
27. user700211_a.straltsou 227 09.01.20 09:54 Сейчас в теме
(26) Выбирая для значения по умолчанию NULL или Неопределено, вы закладываете баг в код. Ведь не всего значения могут передаваться в конструктор явно

Массив = НовыйМассив(1, 2, 3)

В конструктор могут быть переданы и переменные

Массив = НовыйМассив(Перем1, Перем2, Перем3);
Сообщить(Массив[2]); // выход за границы массива, если Перем3 = Неопределено

Это дефект кода 100%
28. ImHunter 327 09.01.20 10:02 Сейчас в теме
(27) В "скользких" случаях создаем и наполняем массив обычным способом. Делов-то...
29. gmw 24.07.20 19:10 Сейчас в теме
(28)"Маленькие причины - большие последствия" - говорил дедушка, поскользнувшись на кожуре банана и лёжа на больничной койке...
Взято из книги "Радио? Это очень просто!"
30. ImHunter 327 27.07.20 08:24 Сейчас в теме
(29) Брррр.... И дедушка, и банан, и радио, и все это в контексте конструкторов;)
Товарищ, вам вообще тогда код писать противопоказано.
31. gmw 27.07.20 11:03 Сейчас в теме
(30)"В "скользких" случаях создаем и наполняем массив обычным способом."
Я предлагаю избегать "скользких" случаев при любых обстоятельствах. (27) прав.
32. ImHunter 327 27.07.20 12:08 Сейчас в теме
(31) Уж извините за троллинг:) Но просто не могу удержаться.
Любой программный код может привести к дефектам. Например, можно в параметры запроса передать Неопределено вместо Null или пустой ссылки. А потом потратить кучу времени в поисках ошибки.
В любом случае, программист думает (обычно), когда пишет код. Если в СП указывается, что есть ограничение для НовыйМассив(..), то это тоже нужно иметь в виду. Вот и все!
Я свой вариант НовыйМассив вообще нечасто использую. Но в некоторых случаях с ним значительно проще. Что делать, если Массив.Добавить() не возвращает дополненный массив...
33. gmw 27.07.20 16:22 Сейчас в теме
(32)
Любой программный код может привести к дефектам.

Не согласен. Если техника исправна, то все операции выполняются так, как записано в тексте программы. Следовательно, дефектов, то есть отклонений результатов от текста, быть не может.
Могут быть дефекты в тексте программы? Могут быть синтаксические ошибки, но на исполнение они не попадут.
То есть, на исправной технике синтаксически правильный текст программы не может дать неправильный результат.
Тогда в чём может быть дефект, то есть отклонение полученного результата от ожидаемого нами? Получается, что дефект содержится только в наших ожиданиях.

"Что такое: Был произведён ядерный взрыв от 20 до 150 килотонн? - Мы думали - 20, а оно ка-ак бабахнет!"

Значит, не текст программы приводит к дефектам, а наши ожидания того, к чему он приведёт при исполнении.
В чём же, в общих чертах, наши ожидания?
В контексте языка 1С мы ожидаем, что можем написать почти всё, что угодно, а волшебный интеллект интерпретатора 1С поймёт, что нам надо и сделает всё хорошо!
Ни "Неопределено", ни "NULL" машина не поймёт, их нет в исполняемом коде, это просто наши фантазии на языке высокого уровня. Нам захотелось, чтобы они были, как хочется и то, чтобы одной переменной можно было присваивать значения разных типов, и многое другое - язык 1С идёт нам навстречу, почти никаких "строгостей"!
В результате мы сами должны всё предусматривать, если это не зашито в интерпретатор 1С.

Поэтому для данного случая (тема статьи) лучшим вариантом будет попросить разработчиков платформы предусмотреть вышеописанные коллизии, чтобы они учитывались автоматически.
(19) ОЧЕНЬ ПРАВ!
34. ImHunter 327 28.07.20 06:22 Сейчас в теме
(33) Насчет "(19) ОЧЕНЬ ПРАВ!" - вы просто не поняли, для чего такие самодельные конструкторы. Тут дело вообще не в "оптимизации", а в удобстве. Например, при отладке в табло нужно написать какое-то достаточно сложное выражение, где используется заполненный массив. Ну или в СКД использовать. Или в каких-то скриптовых выражениях-функциях. Платформенным конструктором (массива) такое не сделаешь.
Для этих же целей у меня есть и конструктор НовыйЗапрос, куда можно передать параметры запроса.
Оставьте свое сообщение