Последний раз про срез последних (на каждую дату в запросе)

Публикация № 1302246 15.02.21

Разработка - Инструментарий разработчика

срез замер производительность запрос эксперимент

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

На проведение данного исследования меня натолкнула статья «Срез на даты за период. Шаблон запроса» с комментариями. Суть статьи: автор привел два варианта решения известной задачи — традиционный и свой собственный («интервальный»). В комментариях оба варианта подверглись резкой критике за сложность — большой объем текста, временные таблицы. Цитирую критиков:

«давно уже подобную задачу решают одним запросом (без всяких временных таблиц) с двумя левыми соединениями»

«Не вникал в смысл задачи, но срез на дату чего-либо по периоду делается простым 1 запросом без всяких ВТ.»

Комментаторы оказались людьми слова и дела, предложили два своих варианта, без временных таблиц, в один запрос.

Изначально, я был сторонником традиционного способа — он давно известен, интуитивно понятен (но это не точно) и более-менее оптимальный по производительности (это тоже не точно). Вариант автора — тоже интересный, мне такая идея в голову не приходила, но, почему-то, он мне показался менее производительным.

Оба варианта из комментариев — короткие, лаконичные, но затратные по ресурсам, на мой взгляд.

Но вообще, интересно провести исследование, и цифрами показать, какой из вариантов лучше и на сколько.

Почти год я собирался с мыслями. Потом провел эксперимент. Еще почти год созревал изложить это в виде статьи. Наконец, созрел :)

По ходу изучения темы, мне попался еще один вариант в статье «Минимализмы» п.4. Тоже в один запрос, довольно диковинное решение, вряд ли применимое на практике, но интересное.

Итого получилось 5 вариантов.

На мой взгляд, все такие задачи в реальности примерно одного типа. Возьмем самую типичную:

  • организация продает товары (документ Реализация товаров);
  • их цена хранится в регистре (периодический регистр сведений Цены) и меняется во времени;
  • продавец может устанавливать скидку в момент продажи, но не более некоторого процентного значения;
  • в какой-то момент времени нужно проверить, что все скидки действительно не превышали этого порога;
  • если превышали, то где, когда, на сколько;
  • значения скидок в документах не хранятся (или хранятся, но мы им не доверяем), а считаем отношение цены из документа продажи к значению цены их регистра на дату.
 
Что ж, осталось собрать тестовый стенд и запустить наши запросы:

Железо (ноутбук):

  • процессор AMD Ryzen 5 2500U,
  • оперативная память 12 Gb,
  • диск SSD Samsung PM871b SATA3

Программное обеспечение:

  • Windows 10 Home (64)
  • Microsoft SQL Server 2017 14.0.2002.14 (X64) Developer Edition (64-bit) (для наглядности, я отключил параллельное использование ядер процессора: Max degree of parallelism = 1)
  • 1С:Предприятие 8.3 (8.3.15.1700) (64)

Создаем простую каркасную конфигурацию: «Номенклатура», «Контрагенты», «Продажа товаров», «Цены».

Конфигурация с обработкой инициализации опубликована здесь: github.com/boroda310/slice-slice-slice. В папке configuration — файлы конфигурации.

Инициализируем случайными данными.

1000 товаров:

 
Инициализация 1

Цены на начало периода, случайные переоценки в периоде:

 
Инициализация 2

Продажи в периоде:

 
Инициализация 3

Порог скидки для отбора данных принимаем равным 10, Чтобы не тратить время на вывод результатов, отобранные данные помещаем во временную таблицу и выводим только количество получившихся строк.

Файл для консоли запросов с текстами запросов опубликован здесь: github.com/boroda310/slice-slice-slice в папке requestconsole.

 
Запрос Вариант А (традиционный)
 
Запрос Вариант Б (интервальный)
 
Запрос Вариант В (в один запрос, без группировки)
 
Запрос Вариант Г (в один запрос, с группировкой)
 
Запрос Вариант Д («эшелонный» из ст. «Минимализмы»)

Я запускал все эти запросы за два периода — первый квартал 2020 г. и первое полугодие 2020 г. — на эти периоды генерировались случайные документы и цены. Замерял время выполнения. В ходе анализа планов запросов определился еще один важный показатель — количество обрабатываемых строк. Другие показатели оказались неинформативными.

Вот пример планов запроса для варианта А и варианта В, как наилучшего из однозапросных:

Вот такие результаты у меня получились:

Вариант

Время выполнения, с.

Обработано строк

  3 мес. 6 мес. 3 мес. 6 мес.
А (традиционный) 4.9 10.2 1 626 647 3 195 284
Б (интервальный) 4.3 10.3 1 626 647 3 195 284
В (без группировки) 10.0 26.2 2 107 110 13 596 463
Г (с группировкой) 20.1 105.0 4 387 711 27 379 466
Д (эшелонный) 20.8 71.6 4 897 463 15 876 311

 

Варианты А и Б лидируют и не сильно отличаются друг от друга. Результат остальных довольно безрадостен.

Можно заключить: срез последних в один запрос реализовать можно. Но лучше — не надо.

Репозиторий тестовой конфигурации: github.com/boroda310/slice-slice-slice

Отсылки:

Специальные предложения

Вознаграждение за ответ
Показать полностью
Лучшие комментарии
25. ildarovich 7333 17.02.21 21:42 Сейчас в теме +10 $m
(24) Нет, не так.

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

Кстати, а индексирование по измерению "Номенклатура" в регистре сведений "ЦеныНоменклатуры" когда и зачем было отключено? Ну или почему оно "ведущим" не было сделано? Я имею ввиду тестовую конфигурацию.

Хотелось еще, чтобы вы вот такие варианты запроса (В) на вашем стенде попробовали (включив индексацию, разумеется). Такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
			И 1 НЕ В 
			(ВЫБРАТЬ 1 ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2 
			ГДЕ (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период))
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А также такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
	И ЦеныНоменклатуры2.Период ЕСТЬ NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А мой запрос лучше применить вот в таком варианте:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Цена КАК ЦенаДокумента,
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) - МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много КАК Оверскидка,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовараТовары.Количество КАК Количество,
	ПродажаТовараТовары.НомерСтроки КАК НомерСтроки
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ЦеныНоменклатуры.Период <= ПродажаТовара.Дата)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода

СГРУППИРОВАТЬ ПО
	ПродажаТовара.Ссылка,
	ПродажаТовараТовары.Номенклатура,
	ПродажаТовараТовары.Цена,
	ПродажаТовара.Контрагент,
	ПродажаТовараТовары.Количество,
	ПродажаТовараТовары.НомерСтроки

ИМЕЮЩИЕ
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) < МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать
Ну и еще установок цен, чтобы было ближе к реальности, нужно побольше. Например, не 24, а 124. Их можно на 2,5 года растянуть. Начав с 01.01.2019, например. Это я к тому, что 9 записей в РС на номенклатуру - это вообще ни о чем. Нечего оптимизировать, никакие хитрые приемы не нужны и конкурса именно по срезу последних не получается.
user1067792; Simonov_NPM; Serg O.; +3 1 Ответить
Остальные комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. kozusenok 34 15.02.21 13:09 Сейчас в теме
А мне ещё вот такой вариант приглянулся где-то тут на форуме
ВЫБРАТЬ
	ЦеныНоменклатуры.Период КАК Период,
	ЦеныНоменклатуры.Номенклатура КАК Номенклатура,
	ЦеныНоменклатуры.Цена КАК Цена
ПОМЕСТИТЬ ВсеЦеныНоменклатуры
ИЗ
	РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
ГДЕ
	ЦеныНоменклатуры.Период <= &КонецПериода
;

ВЫБРАТЬ
	Продажи.Регистратор КАК Документ,
	Продажи.Контрагент КАК Контрагент,
	Продажи.Номенклатура КАК Номенклатура,
	Продажи.Количество КАК Количество,
	ВсеЦеныНоменклатуры.Цена КАК Цена
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, Авто, ) КАК Продажи
	ЛЕВОЕ СОЕДИНЕНИЕ ВсеЦеныНоменклатуры КАК ВсеЦеныНоменклатуры
	ПО Продажи.Номенклатура = ВсеЦеныНоменклатуры.Номенклатура
		И ВсеЦеныНоменклатуры.Период В
			(ВЫБРАТЬ
				МАКСИМУМ(ЦеныНоменклатуры.Период)
			ИЗ
				ВсеЦеныНоменклатуры КАК ЦеныНоменклатуры
			ГДЕ
				ЦеныНоменклатуры.Период <= Продажи.ПериодСекунда
				И ЦеныНоменклатуры.Номенклатура = Продажи.Номенклатура)
Показать
ildarovich; +1 Ответить
2. randomus 207 15.02.21 15:28 Сейчас в теме
(1) надеюсь, это сарказм ;)
3. randomus 207 15.02.21 18:33 Сейчас в теме
(2) я не поленился и замерял этот вариант. За первый квартал время выполнения 23 сек.
это очень плохой вариант. План запроса:
Прикрепленные файлы:
t278; MGraf; shard; BigB; +4 Ответить
14. buganov 179 17.02.21 07:33 Сейчас в теме
(1) без обид, но запрос ужасный. Начиная от неограниченного количества кортежей снизу во временной таблице, заканчивая чтением регистра накопления как попало.
randomus; +1 Ответить
34. director04 3643 18.02.21 10:53 Сейчас в теме
(1) Использовать в соединении таблиц запрос - это губить производительность системы.
На малых объемах данных можно. На больших - повесите систему....
40. ildarovich 7333 19.02.21 10:05 Сейчас в теме
(34) Тем не менее, посмотрите результаты в (28). Объемы данных там не маленькие. Производительность не то, чтобы не погублена, а даже многократно спасена.
45. triviumfan 27 24.02.21 09:15 Сейчас в теме
(40) Опа, с возвращением! Сергей, можно ли от вас ждать новых статей? Совсем пропали.
4. Rustig 1184 16.02.21 17:04 Сейчас в теме
Почти год я собирался с мыслями. Потом провел эксперимент. Еще почти год созревал изложить это в виде статьи. Наконец, созрел :)

Коллеги, цените публикации!
у меня лично также - уходит много времени "чтобы собраться", "чтобы написать". реально, это труд.
Dunda; KEV8383; ardn; Drivingblind; randomus; biimmap; +6 Ответить
5. Rustig 1184 16.02.21 17:07 Сейчас в теме
(0) План запроса какой обработкой выводили? Что за зверь такой?
8. randomus 207 16.02.21 18:18 Сейчас в теме
(5) Стандартная консоль запросов с ИТС, галочка показать план запроса. Если что, в конфигурацию встроена. Не так красиво, как в профайлере, но для данного случая показателей достаточно
Serg O.; Rustig; +2 Ответить
6. Rustig 1184 16.02.21 17:18 Сейчас в теме
(0) Коллеги, не кидайте камнями. Но я пару-тройку подобных задач решал по другому.
Создал регистр сведений (иногда их несколько было, иногда одного достаточно - зависит от показателей отчета , который требуется Заказчику) - при проведении Реализации сохраняю в регистр сведений цены на каждый товар из реализации, скидку, цены на товар из общего регистра ЦеныНоменклатуры, ответственного.
Далее Отчет строю по этому регистру. Информация копится быстро, согласен, что сведения дублируются из других регистров -но такова суть управленческого учета - много регистров сведений и накоплений почти дублируют друг друг, отличаясь только одним-двумя измерениями.
Подобная схема реализации очень быстро внедряется, легко адаптируется при изменении ТЗ Заказчика.
Через год -два делаю свертку.

Плюс подобная задача возникает при расчете итоговых остатков на расчетных счетах на каждый день - для финансового учета и планирования. Подвести итоги пока не могу, процесс автоматизации финучета "для себя" временно приостановлен.
randomus; jONES1979; +2 Ответить
9. randomus 207 16.02.21 18:22 Сейчас в теме
(6) Конечно, если есть возможность хранить промежуточные результаты, то почему бы нет. Я просто протестил известные варианты известной вычислительной задачи.
16. Yashazz 4069 17.02.21 08:55 Сейчас в теме
(6) Разумеется, в общем случае архитектурное решение гораздо лучше, его заточить под конкретику можно. Но объём растёт. Равно как и поиграть с таблицами значений, пока они не убивают сеансовый кэш, иногда проще и в разы быстрее. Извечный поиск баланса между местом на диске, местом в кэше/оперативке и скоростью исполнения.
36. mixsture 18.02.21 11:17 Сейчас в теме
(6)
стр сведений (иногда их несколько было, иногда одного достаточно - зависит от показателей отчета , который требуется Заказчику) - при проведении Реализации сохраняю в регистр сведений цены на каждый товар из реализации, скидк


и я тоже за такое решение. Просто надо раз и навсегда признаться, что типовые сущности не позволяют выполнить такой запрос эффективно. Поэтому и следует использовать заранее подготовленные данные - этот подход очень распространен в конфигурациях, хорошо разделяет сложность задачи, убирая его с отчета, и хорошо модифицируется и поддерживается в дальнейшем.
Это, несомненно, сдвигает баланс системы с OLTP -> OLAP, что выливается в более долгое проведение доков при более быстром формировании отчетов.
randomus; Rustig; +2 Ответить
7. Rustig 1184 16.02.21 17:25 Сейчас в теме
(0) кому-то большие запросы - это неизбежность, с которой приходится мириться.... я стараюсь обходить большие запросы в прямом смысле слова - часто получаю ТаблицуЗначений из Запроса вместо Выборки. Далее в ТаблицеЗначений меняю сведения или обрабатываю строки, и далее окончательный результат возвращаю.
Опять-таки, не считаю что это единственно правильный метод, но архитектура красивого решения в этом и заключается, что мы используем баланс: минимум соединений таблиц в запросах - минимум физических таблиц для хранения информации.
Что-то подобное я пробовал описать в публикации, но при повторном прочтении, понимаю сам, что написал сложным языком. Поэтому соррян заранее: https://infostart.ru/1c/articles/195627/
mashinist; Yashazz; randomus; jONES1979; +4 Ответить
11. randomus 207 16.02.21 18:35 Сейчас в теме
(7) В таблицу значений - нормальное решение, тоже часто использую. С другой стороны, соединения - это основное назначение SQL-сервера. Он на них натаскан и оптимизирован :) Поэтому я наоборот стараюсь максимальное количество соединений отдать на выполнение SQL-серверу. Естественно, их надо грамотно строить и не использовать сложных условий в связях. Если не получается упростить условия, тогда лучше без них.
Со статьей ознакомлюсь, спасибо.
10. Rustig 1184 16.02.21 18:33 Сейчас в теме
(8) спасибо за статью и ответ. ловите вознаграждение.
randomus; +1 Ответить
12. randomus 207 16.02.21 18:47 Сейчас в теме
(10) спасибо! Мне пришла идея, как распорядится вознаграждением :) Я добавил еще 9 sm.
И все 10 получит тот, кто пришлет свой вариант решения, если он будет в один запрос и быстрее варианта В. Либо быстрее варианта А без ограничения количества запросов, подзапросов, временных таблиц
13. ilya2184 62 16.02.21 23:52 Сейчас в теме
Не пробовал индексировать поля соединения, например в традиционном варианте? Может получиться быстрее (а может и медленнее)
15. Yashazz 4069 17.02.21 08:51 Сейчас в теме
А кто-нибудь замерял, что в общем случае быстрее -
ПродажаТовара.Дата >= вт_ПериодыЦен.НачалоПериода И ПродажаТовара.Дата < вт_ПериодыЦен.КонецПериода
или
ПродажаТовара.Дата МЕЖДУ вт_ПериодыЦен.НачалоПериода И ДОБАВИТЬКДАТЕ(вт_ПериодыЦен.КонецПериода, СЕКУНДА, -1)

кто знает?
19. randomus 207 17.02.21 12:47 Сейчас в теме
(15) думаю, что примерно одинаково. позже проверю
20. randomus 207 17.02.21 15:28 Сейчас в теме
(15) проверил :) оценки в плане запроса одинаковые, но время выполнения у первого варианта немного меньше
22. Yashazz 4069 17.02.21 17:59 Сейчас в теме
(20) Спасибо. Вообще, Вам спасибо, дельная хорошая публикация.
17. Simonov_NPM 17.02.21 10:11 Сейчас в теме
Традиционный запрос
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ПродажиОбороты.Период КАК Дата
ПОМЕСТИТЬ вт_ДатыПродаж
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ЦеныНоменклатуры.Период,
	ЦеныНоменклатуры.Номенклатура,
	ЦеныНоменклатуры.Цена
ПОМЕСТИТЬ ВТ_Цены
ИЗ
	РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
ГДЕ
	ЦеныНоменклатуры.ТипЦен = &ТипЦен
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	МАКСИМУМ(ВТ_Цены.Период) КАК Период,
	ВТ_Цены.Номенклатура КАК Номенклатура,
	вт_ДатыПродаж.Дата КАК Дата
ПОМЕСТИТЬ вт_ДатыАктуальныхЦен
ИЗ
	вт_ДатыПродаж КАК вт_ДатыПродаж
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_Цены КАК ВТ_Цены
		ПО ВТ_Цены.Период <= вт_ДатыПродаж.Дата

СГРУППИРОВАТЬ ПО
	вт_ДатыПродаж.Дата,
	ВТ_Цены.Номенклатура
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ПродажиОбороты.Период КАК Период,
	ПродажиОбороты.Контрагент КАК Контрагент,
	ПродажиОбороты.Номенклатура КАК Номенклатура,
	ПродажиОбороты.КоличествоОборот КАК Количество,
	ПродажиОбороты.СтоимостьОборот,
	ВТ_Цены.Цена
ИЗ
	РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, День, ) КАК ПродажиОбороты
		ЛЕВОЕ СОЕДИНЕНИЕ вт_ДатыАктуальныхЦен КАК вт_ДатыАктуальныхЦен
		ПО ПродажиОбороты.Номенклатура = вт_ДатыАктуальныхЦен.Номенклатура
			И ПродажиОбороты.Период = вт_ДатыАктуальныхЦен.Дата
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Цены КАК ВТ_Цены
		ПО ПродажиОбороты.Номенклатура = ВТ_Цены.Номенклатура
			И (вт_ДатыАктуальныхЦен.Период = ВТ_Цены.Период)
Показать

показал время 287 на 6600 записях

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



показал время 84 на 6600 записях

в отличии от плохого запроса из первого комментария, в подзапросе условия соединения используется реальная таблица (РегистрСведений.ЦеныНоменклатуры) вместо временной

База УПП, Субд sql2012

Показатель i/o конечно значительно выше у плохого запроса.
46. triviumfan 27 24.02.21 09:21 Сейчас в теме
47. Simonov_NPM 24.02.21 10:00 Сейчас в теме
(46) Для того чтобы два раза не обращаться к физической таблице
18. BackinSoda 17.02.21 11:49 Сейчас в теме
А я думал, что "интервальный" является "традиционным".
Спасибо за статью !
21. ildarovich 7333 17.02.21 16:45 Сейчас в теме
Если разобраться: от чего зависит сравнительное время выполнения этих запросов, то результаты при заданных условиях окажутся очевидными без всякого вычислительного эксперимента. Кстати, коррелированный запрос (1), по-моему мнению, зря сбросили со счетов. По условиям эксперимента у вас одна номенклатура продается в среднем 18 раз за день, а меняет свою цену - раз в двадцать дней, то есть - 4,5 раза за квартал. Соединение самих с собой 4,5 записей с 4,5 записями (упрощаю, так как есть нелинейность) - это условия, в которых проблема тэта соединений вообще не заметна. То есть считать заново 18 раз в день то, что меняется раз в 20 дней просто глупо. Поэтому однозапросный метод, в котором на каждую дату все заново считается, здесь не подходит не про причине своей ущербности, а по причине избыточного повторения вычислений.

Мой запрос из "минимализмов" будет работать примерно на уровне других методов (а какие-то и опредит), когда продаж одной номенклатуры будет не больше одной в день, а ее переоценок хотя бы сотня (тысяча вообще хорошо). Понятно, что в жизни это бывает редко, но ведь кроме переоценок - продаж есть и другие сценарии.

Так что ваши выводы справедливы не в общем, а частном случае соотношения числа записей в периодическом регистре и количества требуемых дат в множественном срезе последних, ИМХО.

Ну и, пользуясь случаем, прорекламирую тут свой метод индексирования интервалов для борьбы с фамильной болезнью периодических регистров сведений - деградацией производительности при росте количества записей.
zqzq; Rustig; +2 Ответить
23. Yashazz 4069 17.02.21 18:01 Сейчас в теме
(21) Вот да, от бизнес-смысла каждой конкретной задачи плясать надо, и выбирать решение именно исходя из ситуации.
24. randomus 207 17.02.21 21:11 Сейчас в теме
(21) В реальной жизни условная "переоценка" всегда реже условной "продажи".
Хотелось бы увидеть хоть один реальный обратный пример. Соответственно, мои выводы справедливы - в реальной жизни :)
25. ildarovich 7333 17.02.21 21:42 Сейчас в теме +10 $m
(24) Нет, не так.

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

Кстати, а индексирование по измерению "Номенклатура" в регистре сведений "ЦеныНоменклатуры" когда и зачем было отключено? Ну или почему оно "ведущим" не было сделано? Я имею ввиду тестовую конфигурацию.

Хотелось еще, чтобы вы вот такие варианты запроса (В) на вашем стенде попробовали (включив индексацию, разумеется). Такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
			И 1 НЕ В 
			(ВЫБРАТЬ 1 ИЗ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2 
			ГДЕ (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период))
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А также такой:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Количество КАК Количество,
	100 * (ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) / ЦеныНоменклатуры.Цена КАК Скидка
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ПродажаТовараТовары.Цена < 0.9 * ЦеныНоменклатуры.Цена) 
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры.Период)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры2
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры2.Номенклатура)
			И (ПродажаТовара.Дата >= ЦеныНоменклатуры2.Период)
			И (ЦеныНоменклатуры2.Период > ЦеныНоменклатуры.Период)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода
	И ЦеныНоменклатуры2.Период ЕСТЬ NULL
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать

А мой запрос лучше применить вот в таком варианте:
ВЫБРАТЬ
	ПродажаТовара.Ссылка КАК Ссылка,
	ПродажаТовараТовары.Цена КАК ЦенаДокумента,
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) - МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много КАК Оверскидка,
	ПродажаТовара.Контрагент КАК Контрагент,
	ПродажаТовараТовары.Номенклатура КАК Номенклатура,
	ПродажаТовараТовары.Количество КАК Количество,
	ПродажаТовараТовары.НомерСтроки КАК НомерСтроки
ПОМЕСТИТЬ ВременнаяТаблица
ИЗ
	Документ.ПродажаТовара.Товары КАК ПродажаТовараТовары
		ЛЕВОЕ СОЕДИНЕНИЕ Документ.ПродажаТовара КАК ПродажаТовара
		ПО (ПродажаТовараТовары.Ссылка = ПродажаТовара.Ссылка)
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
		ПО (ПродажаТовараТовары.Номенклатура = ЦеныНоменклатуры.Номенклатура)
			И (ЦеныНоменклатуры.Период <= ПродажаТовара.Дата)
ГДЕ
	ПродажаТовара.Дата МЕЖДУ &НачалоПериода И &КонецПериода

СГРУППИРОВАТЬ ПО
	ПродажаТовара.Ссылка,
	ПродажаТовараТовары.Номенклатура,
	ПродажаТовараТовары.Цена,
	ПродажаТовара.Контрагент,
	ПродажаТовараТовары.Количество,
	ПродажаТовараТовары.НомерСтроки

ИМЕЮЩИЕ
	МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ) * &Много + 0.9 * ЦеныНоменклатуры.Цена - ПродажаТовараТовары.Цена) < МИНИМУМ(РАЗНОСТЬДАТ(ЦеныНоменклатуры.Период, &КонецПериода, ДЕНЬ)) * &Много
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(*) КАК Поле1
ИЗ
	ВременнаяТаблица КАК ВременнаяТаблица
Показать
Ну и еще установок цен, чтобы было ближе к реальности, нужно побольше. Например, не 24, а 124. Их можно на 2,5 года растянуть. Начав с 01.01.2019, например. Это я к тому, что 9 записей в РС на номенклатуру - это вообще ни о чем. Нечего оптимизировать, никакие хитрые приемы не нужны и конкурса именно по срезу последних не получается.
user1067792; Simonov_NPM; Serg O.; +3 1 Ответить
28. Serg O. 197 18.02.21 09:38 Сейчас в теме
согласен, товаров и установок цен должно быть больше

сравнил запрос А и Ваши запрос на "реальной" торговой базе за 1 месяц (январь 2021)
установки цен идут ежедневно по несколько 4-10 тыс. товаров (133 тыс. записей рс.ЦеныНоменклатурын за месяц )
результат запроса: 18 359

"лучший" запрос А - выполнялся: 65 - 66 сек,
Ваш 1 запрос: 2 сек !!!
Ваш 2 запрос: 15 сек
Ваш 3 запрос: 1,25 - 1,32 сек (при Много = 31 день) - наилучший результат!
ildarovich; +1 Ответить
32. randomus 207 18.02.21 10:01 Сейчас в теме
(28) откуда я знаю как вы адаптировали "мои" запросы к реальной базе?

И что такое "много = 31 день" в "моем 3 запросе"?

Много - это в запросе Ильдаровича, и оно не в днях измеряется а в рублях.
и 31 в таком случае это не много и запрос вероятно работает не правильн.

Похоже, надо запрещать комментарии, а то холивар разгорается :)

Напишите свою статью лучше. Может я прочитаю и прояснится в голове
38. Serg O. 197 19.02.21 07:41 Сейчас в теме
(32) за Вашу статью спасибо и большой +

Данные по времени из более наполненной базы торговли я привёл для (25) ildarovich
42. randomus 207 19.02.21 12:57 Сейчас в теме
(38) Извините, неправильно понял вас. Если это результаты запросов из (25) то действительно интересно, есть над чем подумать, спасибо.
39. ildarovich 7333 19.02.21 09:42 Сейчас в теме
(28) Спасибо, очень интересно, есть о чем подумать. И, возможно, еще скорректировать выводы в (37). Получается, работа с временной таблицей (созданием и выборкой из нее) достаточно много времени на этих данных отнимает.

Единственно, &Много действительно должно быть не 31, а больше (зависит от диапазона данных). Больше диапазона изменения ресурса. Поэтому 10 000, которые в тесте - надежнее. Проверить можно, сравнив количество в результате запроса.

Хотя, если разница между 0.9 установленной цены и ценой продажи не превышают 31 рубля, результат будет тем же. А на скорости это сказываться не должно.

Интересен результат коррелированного запроса.
29. randomus 207 18.02.21 09:48 Сейчас в теме
(25)
Нет, не так.


Все таки, настаиваю на своей формулировке :) Пока не получу реальный, а не фантазийный пример, когда "срезаемая" оценка некоей сущности на 2-3 порядка превосходит количество периодов среза.

Кстати, а индексирование по измерению "Номенклатура" в регистре сведений "ЦеныНоменклатуры" когда и зачем было отключено? Ну или почему оно "ведущим" не было сделано? Я имею ввиду тестовую конфигурацию.


Я начинаю сомневаться в продуктивности дальнейшего спора.

Не было оно отключено. В регистре сведений по умолчанию создается кластерный индекс по всем измерениям по порядку следования в конфигураторе, а затем - по периоду.
Стыдно этого не знать, минус в коммент за это.

Я, кстати, пробовал индексировать поле Номенклатура отдельно - результаты немного ухудшались. Возможно, сервер тратил время на выбор нужного индекса.

Зря вы так переживаете за свой вариант, он красивый, и с этой точки зрения мне нравится больше остальных. Но это - вычислительный казус, упражнение для ума, а этот эксперимент не про хитрые приемы, а про скучную обыденность :)

Ваши варианты я попробую, сейчас тестового стенда нет под рукой. Но мне кажется - там только косметические улучшения
33. ildarovich 7333 18.02.21 10:16 Сейчас в теме
(29)
Не было оно отключено
Знаете, мне очень понравилось оформление тестовой конфигурации - было удобно и приятно с ней работать. Еще удобнее то, что я скачал ее на гитхабе, куда вы ее так любезно выложили. И вот после того как я загрузил конфигурацию из файлов, я и получил снятый флажок в ведущем измерении "Номенклатура" и отключенный по нему индекс. - Попробуйте загрузить те же файлы в чистую конфигурацию - сами это увидите.
Стыдно этого не знать
Если бы мне было стыдно от всего, чего я не знаю - давно бы сгорел от этого стыда.
Переживаю я не за свой вариант, а, как всегда, за "научную истину".
35. randomus 207 18.02.21 11:07 Сейчас в теме
(33)Всё правильно, так и было задумано. Потому что, в данном случае, достаточно индексов, которые 1с создает по умолчанию.
В гугле поиск "индексы 1с" первая ссылка.
Можно проверить средствами SQL сервера
37. ildarovich 7333 18.02.21 13:58 Сейчас в теме
(35) Вот про это я и спрашивал в (25): почему было отключено. Посмотрел по ссылке, да, все так, индекс и без этого строится.

Вообще, ничего плохого статья не советует. Я бы вообще не спорил, если бы статья называлась: Когда выгодно использовать временные таблицы на типовом примере срезов последних. Обоснующий выигрыш здесь, в основном, не из-за разного подхода к срезу в этих запросах (за исключением Д), а из-за кэширования цен на каждый день.

Как только цены станут устанавливаться в разное время дня (периодичность с точностью до секунд), вам потребуется считать их на время каждого документа, то есть очень много раз, вся тяжесть запроса (А) перейдет в первый запрос пакета и разница с запросом (В) станет меньше. В запрос (Б) я не верю: там и в первом запросе тэта соединение и во втором. Не верю в (Г).

Получается, я был не совсем прав, говоря о том, что для выигрыша (В) или (Д) нужно больше записей в РС, дело больше в количестве продаж номенклатуры в день, ну или в периодичности регистра.

Очищая все эти запросы от шелухи (то есть ставя их в равные условия), получаем ключевой вопрос сравнения подходов (А) и (В): что выгоднее - использовать агрегат "максимум" и записать период цены во временную таблицу, а затем запросом по сверхселективному индексу извлечь цену или использовать второе тэта соединение? Думаю, когда записей станет больше и больше, (В) станет проигрывать, Остается (Д) - вычисления (их еще можно подкрутить, использовать функцию подсчета остатка) против подсчета максимума и записи во временную таблицу. Меня в свое время удивило, что подсчет максимума при наличии индекса по соответствующему полю его не использует. Если это так в каких-либо СУБД, то (Д) - в любом случае проигрывает.

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

По поводу конкурса на придумывания лучших запросов, чем (А) и (В) могу сказать, что то, что предложено в (25) - это своего рода читерство. Чтобы превзойти такой запрос как (А) в общем каким-либо новым хитрым способом нужны условия (а они бывают в жизни), когда записей в РС гораздо больше. Если согласуем такие условия - могу попробовать...
41. randomus 207 19.02.21 12:49 Сейчас в теме
(37) Согласен на ваши условия. Попробуйте.

Вообще, конечно, я согласен - мое исследование однобокое и неполное - границы применимости неплохо было бы определить.

Кстати, тот факт, что я отключил параллелизм, почему-то никто не отметил. Но в реалиях-то он есть, и какие-то запросы параллелятся лучше, какие-то хуже. Тоже надо исследовать, если по хорошему.

Тета-соединения в варианте Б меня тоже смущали, поэтому он и вызывал недоверие. Но, как ни странно, в моих условиях показал себя хорошо
44. randomus 207 23.02.21 22:25 Сейчас в теме
(25) Наконец дошли руки запустить эти запросы на первоначальном стенде.

Сразу только период 6 мес.:

1) 16 сек. - весьма неплохо. Но запрос не один - есть коррелированный.
2) 22.3 сек. - улучшенный мой (В) вариант, за счет доп. отбора в соединении.
3) 46.5 сек. - результат улучшен, математику оптимизировали.

Ну в общем, 2-й запрос удовлетворяет условиям конкурса.
Если других вариантов не будет, признаем его победителем.

Отмечу, что 1-й запрос - очень элегантное решение, мне понравилось. По сути, 1-й и 2-й запрос делают одно и тоже, но во втором приходится перебрать гораздо больше строк. И исправить без коррелированного запроса никак не получается. @ildarovich - отдельное спасибо за дельные комментарии.
27. Serg O. 197 18.02.21 08:57 Сейчас в теме
(24) вы не совсем правы
установки цен могут (и идут!) каждый (рабочий, хотя бы) день

и да, товаров может быть намного больше 30-50 тыс. товаров
и умножаем это на 5-10 и более типов "базовых" цен!

тогда за месяц уже 1-1,5 млн. записей будет по 1 типу цен!
т.е. 5-15 млн. в "нашей реальности"

анализ на 1,5 тыс. наверное будет отличаться от 1,5 млн.
(и SQL планировщик иногда сам "решит" как лучше)
условия в соединении таблиц - вообще зло... и "не рекомендуется 1С"

на "нашей" базе УТ - запрос А за 1 месяц (январь 2021) - 66 сек - результат 18 359
если заменить Документ.ПродажаТовара -> Документ.РеализацияТоваровУслуг

и ошибка в запросе А - деление на 0 в поле Скидка
100 * (ЦеныНоменклатуры.Цена - РеализацияТоваровУслугТовары.Цена) / ЦеныНоменклатуры.Цена

пришлось заменить на условие
выбор когда ЦеныНоменклатуры.Цена>0
тогда 100 * (ЦеныНоменклатуры.Цена - РеализацияТоваровУслугТовары.Цена) / ЦеныНоменклатуры.Цена
иначе -100
конец
30. randomus 207 18.02.21 09:50 Сейчас в теме
(27)
установки цен могут (и идут!) каждый (рабочий, хотя бы) день

зачем тогда нужен срез последних?
31. Serg O. 197 18.02.21 09:55 Сейчас в теме
(30) цены (для примера) могут расти... а реально меняются вверх-вниз!

и задача тестовая (которая в запросе А) не на срез последних на конец периода...
а на получение продаж со скидкой > 10%

+ документы часто могут перепроводить / менять цены "задним числом"
и нужны цены на старую дату постоянно
26. Serg O. 197 18.02.21 08:43 Сейчас в теме
согласен с ildarovich, надо массивы побольше анализировать
1,5 -3 тыс записей в регистре это маловато...

Сделайте установки на каждый (рабочий, хотя бы) день
и да, товаров надо побольше 30-50 тыс. товаров
тогда за месяц уже 1-1,5 млн. записей хотя бы будет
это "ближе" к реальности...

для случайности, можно для теста цены +1р. на каждый день сделать
или по курсу $ например сделать за период
(доллар падает, цены растут вопреки логике?!)

кстати группировка хоть и "накладнее", но "сворачивает" лишние записи...
и без неё иногда не обойтись, + группировка делает доп.индексацию в ВТ
только это делается по всем полям группировки! а их "слишком много" вроде бы
гляда на запрос Г и Д не очень понятно... зачем там поле НомерСтроки ?

и да, большой + за проделанную работу, очень интересная статья
43. avega67 23.02.21 17:38 Сейчас в теме
Замечательная статья. И подана тоже очень хорошо.

По варианту "Б" только, по-моему, во 2-ом запросе пакета при формировании врем.таблицы ВТ_ПериодыЦен нужно:
КОНЕЦПЕРИОДА(ЕСТЬNULL(МИНИМУМ(ЦеныЗаПериод_Конец.Период), &КонецПериода), ДЕНЬ) КАК КонецПериода
Оставьте свое сообщение

См. также

Аналог PIVOT в запросе 1С (как выполнить транспонирование таблицы в запросе 1С) Промо

Практика программирования v8 Бесплатно (free)

В статье показывается простой метод реализации аналога оператора PIVOT в запросе 1С без использования соединений.

12.12.2020    3501    Eugen-S    20    

Полезные примеры СКД, ч.2

Практика программирования v8 v8::СКД Бесплатно (free)

Еще несколько примеров решения задач в СКД.

06.04.2021    9636    Neti    8    

Обзор полезных методов БСП 3.1.4

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Бесплатно (free)

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

25.03.2021    34870    rayastar    51    

Звуковое управление в 1С 8.3

Практика программирования v8 1cv8.cf Бесплатно (free)

В данной статье описано создание библиотеки для звукового управления (выполнение команд голосом) для платформы 1С 8.3. Задача была поставлена так, чтобы модуль функционировал непосредственно на клиенте 1С, осуществляя управление формами, и взаимодействовал с интерфейсом.

16.03.2021    6647    velemir    31    

Использование классов .Net в 1С для новичков Промо

Практика программирования Разработка внешних компонент Универсальные функции v7.7 v8 Бесплатно (free)

Руководство для новичков. Написав статью http://infostart.ru/public/238584/, я понял, что многие не понимают того, что написано. Поэтому в этой статье постараюсь более подробно остановиться на азах и без кода на вражеском языке (C#)

27.01.2016    84626    Serginio    113    

Serverless (Faas) в 1С. Создание и вызов Yandex Cloud Functions

Универсальные функции Практика программирования v8 Бесплатно (free)

"Я не могу просто взять и скопировать код с гитхаба", "у нас 1С микросервисами окружена", "возможностей мало" - частые фразы 1С разработчиков. которым не хватает возможностей платформы в современном мире. Faas, конечно, история не новая, но нас сдерживало 152ФЗ и задержки по пингам. Для того, чтобы действительно использовать в 1С код, к примеру, на Python, надо было приложить усилия. Теперь всё намного проще - берём и используем.

28.12.2020    8319    comol    31    

Базовые вещи БСП, которые облегчат жизнь программисту 1С

Практика программирования БСП (Библиотека стандартных подсистем) v8 1cv8.cf Россия Бесплатно (free)

В данной публикации я опишу полезные процедуры и функции модуля общего назначения библиотеки стандартных подсистем, обязательные к использованию любым программистом 1С.

30.08.2020    18884    quazare    34    

Форма выбора (подбор) в управляемых формах

Практика программирования v8 v8::УФ 1cv8.cf Россия Бесплатно (free)

Разбор небольших примеров того, как правильно открывать форму выбора (подбора) в управляемых формах, не прибегая к модальным окнам.

08.05.2020    69514    user5300    19    

Использование программных перечислений, ч.1: строковые константы Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Часто ли у вас возникает необходимость в коде выполнять сравнение на строку?

10.12.2016    40664    unichkin    74    

Программная работа с настройками СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Нюансы программной работы с настройками системы компоновки данных в отчетах и динамических списках. Обзор всех видов настроек компоновки. Что в каких случаях правильно применять. В качестве примера рассмотрена работа с отборами и группировками.

27.01.2020    61242    ids79    26    

[СКД] Программное создание схемы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Сделаем отчет на СКД полностью программно, без использования макета "схема компоновки данных".

15.01.2020    41462    John_d    22    

Последовательности событий при проведении документа 1С. Шпаргалка + про формы + про расширения

Практика программирования v8 Россия Бесплатно (free)

Собрал информацию о событиях/подписках/расширениях в одном месте.

30.12.2019    33130    kuzyara    38    

Вспомогательные инструкции в коде 1С Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Помогаем редактору кода 1С помогать нам писать и анализировать код.

15.10.2018    35529    tormozit    106    

Сходство Джаро - Винклера. Нечеткое сравнение строк

Универсальные функции v8 Россия Бесплатно (free)

В области информатики и статистики сходство Джаро - Винклера представляет собой меру схожести строк для измерения расстояния между двумя последовательностями символов. В публикации рассмотрены некоторые особенности алгоритма, и представлен вариант его реализации на языке 1С.

25.12.2019    8228    brooho    19    

30 задач. Странных и не очень

Практика программирования v8 Бесплатно (free)

30 задач на знание языка программирования 1С и некоторого поведения платформы. Маленьких. Странных и не очень.

02.12.2019    23215    YPermitin    62    

Как передать IP адрес, который вызвал HTTP запрос в 1C (для веб-сервера Apache)

Практика программирования v8 Бесплатно (free)

Столкнулся с задачей получения IP адреса, который вызывает http сервис 1С. Итак, решение:

22.11.2019    11836    Sibars    19    

Оформление и рефакторинг сложных логических выражений Промо

Практика программирования v8 Россия Бесплатно (free)

В сложных логических выражениях нередко самому автору спустя какое-то время тяжело разобраться, не говоря уже о других программистах. Предлагаемая методика позволяет повысить наглядность таких выражений путем оформления в виде И-ИЛИ дерева и одновременно выполнять их рефакторинг.

20.09.2012    82374    tormozit    131    

Полезные процедуры и функции для программиста

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

Все мы пишем программный код и часто используем процедуры, облегчающие его написание. Ниже приведена выборка таких полезных процедур и функций.

07.10.2019    38686    HostHost    41    

Таблица значений. Нюансы

Практика программирования v8 Бесплатно (free)

Обзор некоторых аспектов использования общеизвестного инструмента 1С.

01.10.2019    51067    Yashazz    56    

[Шпаргалка] Программное создание элементов формы

Практика программирования Работа с интерфейсом v8 1cv8.cf Бесплатно (free)

Программное создание практически всех популярных элементов формы.

06.09.2019    95366    rpgshnik    75    

Запись значения в поле ввода/формы со срабатыванием события ПриИзменении Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Иногда возникает необходимость после записи значения в какое либо поле ввода/формы вызвать для него обработчик события ПриИзменении, а о вызове самого события приходится только мечтать. В этой статье приводится программный способ вызова этого события.

11.07.2007    53694    tormozit    51    

Агрегатные функции СКД, о которых мало кто знает

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Пользуетесь ли Вы всеми возможными агрегатными функциями, которые предоставляет система компоновки данных? Если Вы используете только: СУММА, КОЛИЧЕСТВО, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, то эта статья для Вас.

05.09.2019    74152    ids79    55    

Регистры бухгалтерии. Общая информация

Практика программирования Математика и алгоритмы v8 v8::БУ БУ Бесплатно (free)

Общая информация о внутреннем устройстве регистров бухгалтерии.

05.09.2019    44368    YPermitin    25    

Три костыля. Сказ про фокусы в коде

Практика программирования v8 Бесплатно (free)

Три интересных (или странных) костыля в коде, которые могут помочь в повседневных и не очень задачах.

03.09.2019    29796    YPermitin    81    

Как сделать из &НаКлиентеНаСервереБезКонтекста почти &НаКлиентеНаСервере Промо

Практика программирования v8 1cv8.cf Россия Бесплатно (free)

Как сделать метод формы, доступный на клиенте и на сервере одновременно, и сохранить при этом удобство разработки

10.09.2017    50456    tormozit    74    

Отслеживание выполнения фонового задания

Практика программирования Универсальные функции Разработка v8 1cv8.cf Бесплатно (free)

Запуск фонового задания из модуля внешней обработки. Отслеживание выполнения задания в виде прогресса, расположенного на форме.

17.08.2019    43890    ids79    19    

Функции СКД: ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Подробное описание и использование внутренних функций системы компоновки данных: Вычислить, ВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений.

08.08.2019    143297    ids79    75    

Фоновое выполнение кода в 1С - это просто

Практика программирования v8 1cv8.cf Бесплатно (free)

Как легко запускать выполнение в фоне, не прибегая к долгому описанию фоновых процедур.

02.08.2019    57996    avalakh    26    

Выгрузка документа по условию Промо

Практика программирования Разработка v8 Бесплатно (free)

Что делать, если документы нужно выгружать не все подряд, а по какому-то фильтру: статусу, дате, набору условий... А что если он соответствовал этим условиям, а потом перестал? А если потом опять начал? Такие ситуации заставили попотеть не одного программиста.

25.04.2019    17746    m-rv    3    

Разбираемся с параметрами редактирования СКД

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Связь по типу, Параметры выбора, Связи параметров выбора

31.07.2019    39647    json    15    

СКД - наборы данных и связи между ними, создание собственной иерархии, вложенные отчеты

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Набор данных объект. Использование в схеме компоновки нескольких наборов данных. Различные варианты связи наборов: объединение, соединение. Использование иерархии в отчетах на СКД. Создание собственной иерархии, иерархия детальных записей. Использование вложенных схем в отчетах на СКД.

26.07.2019    100686    ids79    16    

Управление качеством кода

Математика и алгоритмы Рефакторинг и качество кода SonarQube EDT v8 Бесплатно (free)

О SonarQube, АПК, EDT. Какие преимущества дает их использование. Для каких команд подходит.

22.07.2019    19173    Stepa86    40    

Как прикрутить ГУИД к регистру сведений Промо

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 Бесплатно (free)

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

16.04.2019    22976    m-rv    18    

СКД - использование расширений языка запросов, секция ХАРАКТЕРИСТИКИ

Инструментарий разработчика Практика программирования v8 v8::СКД Бесплатно (free)

Автоматическое и не автоматическое заполнение полей компоновки данных. Использование расширений языка запросов для СКД «{…}», секция ВЫБРАТЬ, секция ГДЕ, параметры виртуальных таблиц. Автоматизированное использование дополнительных данных в запросе: секция ХАРАКТЕРИСТИКИ.

17.07.2019    47058    ids79    27    

Регистры сведений. За кулисами

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Небольшие заметки по внутреннему устройству регистров сведений.

09.07.2019    33090    YPermitin    14    

"Меньше копипаста!", или как Вася универсальную процедуру писал

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Программист Вася разбирает подход создания универсальных методов на примере программного вывода СКД.

04.07.2019    22246    SeiOkami    53    

Как сделать запрос на изменение данных Промо

Практика программирования v8 v8::Запросы 1cv8.cf Бесплатно (free)

В статье приведены особенности внутренней архитектуры и примеры работы с расширением языка запросов 1С.

01.06.2018    36177    m-rv    23    

Работа с настройками системы компоновки данных

Практика программирования v8 v8::СКД 1cv8.cf Бесплатно (free)

Варианты отчетов, работа с настройками вариантов: структура группировок, поля отчета, отборы, сортировка, условное оформление, другие настройки, настройки отображения диаграмм.

02.07.2019    80491    ids79    18    

Создание отчетов с помощью СКД - основные понятия и элементы

Практика программирования Математика и алгоритмы v8 v8::СКД Бесплатно (free)

Основные принципы работы СКД. Понятия схемы компоновки и макета компоновки. Описание основных элементов схемы компоновки: наборы данных, поля, вычисляемые поля, ресурсы, параметры.

25.06.2019    73469    ids79    28    

Регистры накопления. Структура хранения в базе данных

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Структура хранения регистров накопления в базе данных для платформы 1С:Предприятие 8.x. Первая часть в серии публикаций.

16.05.2019    61207    YPermitin    31    

Метод формирования движений в типовых регистрах нетиповыми регистраторами Промо

Практика программирования v8 1cv8.cf Бесплатно (free)

Вариант решения задач с проведением по типовым регистрам нетиповыми регистраторами. Зачем - чтобы при сравнении конфигурации не обращать внимание на свойства регистров и исключить вероятность допущения горькой оплошности при обновлении информационных баз, заменив типы регистраторов основной конфигурации типами конфигурации поставщика. Для программных продуктов, имеющих в своем составе метаданных документ "Корректировка регистров"("Корректировка записей регистров").

05.12.2017    30563    itriot11    34    

О расширениях замолвите слово...

Практика программирования Разработка v8 Бесплатно (free)

О чём стоит задуматься при принятии решения о создании расширения конфигурации…

07.04.2019    41909    ellavs    131    

Git-репозитории для 1С-кода (опыт использования при небольших проектах)

Практика программирования v8 Бесплатно (free)

Инструкции по взаимодействию с Git-репозиторием, которые писались для тех наших программистов, которые вообще никогда не работали с Git (руководства в духе "Как получить код из git-репозитория?", "Как отправить код в git-репозиторий")...

28.03.2019    31530    ellavs    90    

Трюки с внешними источниками данных

Практика программирования Разработка v8 1cv8.cf Бесплатно (free)

Некоторые трюки для преодоления ограничений внешних источников данных.

14.03.2019    40309    YPermitin    53    

Разработка и сценарное тестирование с Vanessa-ADD. Отчетность Allure. Автоматизация запуска сценариев

Практика программирования BDD/TDD-тестирование, Vanessa v8 Россия Бесплатно (free)

Формируем отчетность о результатах выполнения сценариев. Автоматизируем запуск.

26.02.2019    27876    Vladimir Litvinenko    28    

Возможности типовых шаблонов ограничения доступа на уровне записей (RLS)

Практика программирования БСП (Библиотека стандартных подсистем) Роли и права v8 v8::Права Бесплатно (free)

Краткий обзор применения типовых шаблонов ограничения доступа на уровне записей в конфигурациях, созданных на базе БСП: #ПоЗначениям, #ПоНаборамЗначений, #ПоЗначениямРасширенный, #ПоЗначениямИНаборамРасширенный

03.02.2019    62325    ids79    11    

Новый подход к обмену данными EnterpriseData

Практика программирования Обмен через XML v8 v8::УФ Россия Бесплатно (free)

Хочу предложить Вашему вниманию цикл статей, посвященных обмену данными через универсальный формат (EnterpriseData или ED).

14.12.2018    51488    ids79    82