Простой способ индексирования интервалов

Публикация № 551583

Разработка - Практика программирования

Ускорение запросов интервалы индексы

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

Общая задача поиска интервалов, включающих заданное значение.

Рассмотрим следующую, достаточно общую задачу:

Пусть имеется таблица с колонками: "ключ", "начало интервала", "конец интервала", "значение". 

Таблица "Дано":

Ключ Начало интервала Конец интервала Значение
1 D11 D12 X1
2 D21 D22 X2
... ... ... ...
N DN1 DN2 XN

Требуется выбрать записи, актуальные на заданный момент времени.

Запрос, решающий данную задачу, имеет вид

ВЫБРАТЬ * ИЗ Дано 
ГДЕ &МоментВремени МЕЖДУ НачалоИнтервала И КонецИнтервала

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

Теоретически для решения подобных задач в разных СУБД обычно применяются spatial индексы или R-деревья. Spatial индексы предполагают введение некоторой сетки, а R-деревья - использование специальной структуры данных. Хотя и то и другое возможно смоделировать имеющимися в 1С средствами, предлагается несколько другой путь.

Он основан на следующем жизненном наблюдении: при удалении от отрезка на большое расстояние он начинает выглядеть как точка, при этом близкие точки на большом удалении сливаются. То есть для возможности определения попадания точки на отрезок их нужно рассмотреть с расстояния, когда отрезок превратится в точку. Если результат превращения отрезка будет "сливаться" с заданной точкой, то существует вероятность их пересечения.

Практически "рассмотреть отрезок издалека, чтобы он превратился в точку" означает изменить масштаб представления данных отрезка: разделить все данные нацело на число, не меньшее размера отрезка. Поскольку интервалы имеют, как правило, разные размеры, предлагается использовать двоичный ряд: в зависимости от размера отрезка делить его нацело на наименьшее подходящее число (наименьшее не меньшее) из ряда степеней двойки: 1, 2, 4, 8, 16 и так далее.

В итоге получается, что нужно последовательно делить обе границы интервала на одно и то же число из ряда 1, 2, 4, 8, 16 и так далее, пока округленные значения результатов деления в конце концов не совпадут. Этот одинаковый для двух границ результат деления и будет значением специального реквизита "проекция", который можно проиндексировать и затем использовать для поиска.

Для поиска интервала по заданному значению момента времени потребуется представить его во всех возможных масштабах и выполнить проверку совпадения этих представлений со значением реквизита "проекция". Число всех возможных масштабов для диапазона 1.01.0001 - 31.12.3999 равно 36-ти. Совпадение не означает однозначного вхождения точки в интервал, а говорит только о возможности такого вхождения. Потребуется дополнительная проверка. Но эта проверка выполняется для очень небольшого количества записей, что и дает ускорение.

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

ВЫБРАТЬ * ИЗ РегистрСведений.Дано 
ГДЕ Проекция В (&МассивПроекций) И &МоментВремени МЕЖДУ НачалоИнтервала И КонецИнтервала

Предполагается, что поле "проекция" будет проиндексировано. 

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

Функция ПроекцияИнтервала(От, До) Экспорт
	Если Мин(От, До) = '00010101' ИЛИ Макс(От, До) = '39991231235959' Тогда
		Возврат 0
	КонецЕсли;
	Масштаб = pow(2, 99 - Цел(99 - Окр(log(Макс(До - От, От - До)) / log(2), 10)));
	Пока Окр((От - '00010101') / Масштаб) <> Окр((До - '00010101') / Масштаб) Цикл
		Масштаб = Масштаб * 2
	КонецЦикла;
	Возврат Окр((От - '00010101') / Масштаб)
КонецФункции

Функция МассивПроекций(Дата) Экспорт
	Ответ = Новый Массив;
	Проекция = Дата - '00010101';
	Пока  Проекция >= 0.25 Цикл
		Ответ.Вставить(0, Окр(Проекция));
		Проекция = Проекция / 2
	КонецЦикла;
	Возврат Ответ
КонецФункции

Первая функция вычисляет значение спецреквизита "проекция" по началу и концу интервала, а вторая создает массив проекций по выбранному моменту времени, который затем будет использоваться для поиска.

К тексту функций необходимы небольшие пояснения:

Кажущееся сложным выражение:

Масштаб = pow(2, 99 - Цел(99 - Окр(log(Макс(До - От, От - До)) / log(2), 10)));

всего лишь вычисляет нужный элемент ряда степеней двойки, не меньший размера интервала. То есть для числа 42, например, это выражение будет равно 64, а для 73 будет равно128. Вычисление приближения масштаба в одном выражении позволяет избавиться от многих итераций цикла при его последовательном подборе.

Сравнение

Окр((От - '00010101') / Масштаб) <> Окр((До - '00010101') / Масштаб)

 только на первый взгляд можно заменить выражением

Цел((От - '00010101') / Масштаб) <> Цел((До - '00010101') / Масштаб)

Дело в том, что в последнем случае интервал в две переходящих "новогодних" секунды 20151231235959 - 201601010000 (упрощенно), приходящиеся на момент переноса разряда при двоичной нумерации интервалов, будет требовать большого масштаба уменьшения и получать при таком подходе незаслуженно маленькое значение проекции. То есть произойдет "эскалация" уровня некоторых "несчастливых" интервалов. В результате они будут болтаться на верхних, не своих уровнях, отбираясь по проекции с большой, а по дополнительной проверке - с очень малой вероятностью.
Чтобы этого не происходило, потребуется при построении системы координат каждый раз сдвигать начало следующего, более нижнего уровня разметки границ интервалов на половину масштабного деления.
Это гарантирует равномерность плотности границ интервалов разного масштаба при проекции на общую ось времени. И снижение вероятности того, что интервал, переходящий через границу на нижнем уровне, тоже попадет на границу уровнем выше. Использование округления вместо расчета целого как раз и решает таким образом указанную проблему.

Та же самая мысль иллюстрируется сравнением кодовых линеек обычного двоичного позиционного кода и кода Грэя, представленных на фиг.1 и 2 соответственно. 

Кодовая линейка двоичного позиционного кода

Фиг.2

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

Используя линейку кода на фиг.2, можно еще раз объяснить принцип работы метода:
Интервал каждой записи прикладывается к кодовой линейке последовательно на нулевой (нижний), первый, второй и так далее уровни пока он не войдет целиком в область, окрашенную в один цвет. Адрес этой области определяется порядковым номером области на соответствующем уровне. Этот "адрес" записывается в колонку "проекция". Для поиска интервалов, содержащих заданный период, просматриваются только интервалы, входящие в области разных уровней, в которые также входит период.

Построение фиг.2 также наглядно иллюстрирует факт отсутствия пересечений диапазонов изменений значений проекций разных уровней. Очевидно, что это может произойти только в том случае, когда нижняя граница рабочего диапазона дат меньше верхней более чем вдвое. Например, при использовании рабочего диапазона 01.01.1007 - 01.01.2016. Такой диапазон  в реальных применениях не встречается. Впрочем, даже наличие пересечения не было бы фатальным, а  приводило всего лишь к небольшому снижению избирательности отбора по полю "проекция". 

Если есть сомнения в селективности индекса по полю "проекция", то для проверки можно сгенерировать таблицу случайных интервалов с колонками: начало интервала, конец интервала и рассчитать энтропию поля "проекция". Для этого возьмем, например, 1 000 000 интервалов, равномерно распределенных на промежутке времени длинной один год, средней длиной один день с экспоненциальным распределением длины. Просматривая полученные значение поля, можно увидеть большое разнообразие записанных в нем значений. Вычисления показывают, что энтропия поля префикс равна примерно 8,5.
Это можно было бы предсказать и теоретическими вычислениями.

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

А вот данные тестирования времени его выполнения в зависимости от количества записей: 


Результаты сравнительного тестирования методов
Видно, что время выполнения запроса от количества записей практически не зависит, хотя в теории логарифмическая зависимость определенно имеется. Она связана с выполнением поиска на Log(n) уровнях.
Для сравнения на том же графике приведено время выполнения обычного запроса, которое имеет видимую на графике зависимость от количества записей.

Тестирование проводилось при следующих параметрах: Для файлового варианта: 500 тысяч интервалов в год (случайно-равномерно по году), длина каждого интервала случайная (экспоненциальный закон), со средним 86400 секунд (сутки). Замеры за один, два, три и четыре года. Выбранный момент времени помещался в середине диапазона. Для MS SQL 1,6 миллиона заявок в год, диапазон от одного года до 11 лет, средний размер и положение интервала такие же как в варианте для файловой базы.

Для удобства проверки полученных результатов к статье прилагается каркасная конфигурация, содержащая обработки заполнения базы тестовыми данными и отчеты для сравнительного тестирования базового метода "0" и предлагаемого метода "1".

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

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

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

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

Задача о статусах заявок

В обсуждении статьи "Регистры сведений 1С. Как это устроено" в комментарии (40) была очень подробно сформулирована простая задача, подчеркивающая врожденный недостаток периодических регистров сведений. Он заключается в том, что при хранении в периодическом регистре сведений статусов заявок, затраты времени на выборку заявок с конкретным статусом неизбежно растут вместе с ростом глубины истории статусов заявок.

То есть речь идет о деградации производительности вот такого запроса:

ВЫБРАТЬ * ИЗ РегистрСведений.СтатусыЗаявок.СрезПоследних(&Т0, ) 
ГДЕ Статус В (&Новый, &ВРаботе)

к регистру сведений вот такой структуры:

Например, если заявки поступают каждые десять секунд, то через три года их станет десять миллионов и время выполнения этого запроса возрастет (учтены конкретные условия задачи) до 16,4 секунд. Анализ показывает, что данная проблема имеет общую природу с той, которая решается методом, приведенным в данной статье.

Поэтому предлагается добавить к структуре регистра два реквизита: "проекция" типа Число (15, 0) и "дата смены статуса" типа "Дата".

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

ВЫБРАТЬ *
ИЗ РегистрСведений.СтатусыЗаявок
ГДЕ Проекция В(&МассивПроекций) И Период <= &Т0 И ДатаСменыСтатуса > &Т0

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

В результате время выборки заявок с нужным статусом уменьшилось до 0,57 секунды и практически перестало зависеть от числа заявок в базе!

Вот новый план выполнения запроса:

Каркасную конфигурацию "СтатусыЗаявок" с запросами "Задача1" и "Задача2" можно также скачать из приложений к статье.

P.S.: Хочу поблагодарить Александра Спешилова (speshuric) за интересную задачу, благодаря которой было найдено описанное решение, а  Сергея Носкова (Sergey.Noskov) за статью о регистрах сведений, пробудившую интерес к данной теме.

.

Скачать файлы

Наименование Файл Версия Размер
Каркасная конфигурация "Статусы заявок"

.cf 26,74Kb
23
.cf 26,74Kb 23 Скачать
Каркасная конфигурация "Индексация интервалов"

.cf 21,88Kb
17
.cf 21,88Kb 17 Скачать

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

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Makushimo 157 28.09.16 11:31 Сейчас в теме
абалдеть !
Как всегда прочитал с удовольствием и обязательно буду применять в работе.
2. Alias 165 28.09.16 12:21 Сейчас в теме
Очень красиво, спасибо большое. И вдобавок ещё и полезно. :)
3. igormiro 711 28.09.16 14:22 Сейчас в теме
Очередная статья мастера. По заголовку статьи знаешь, чья статься. Спасибо.
AlX0id; Kinestetik; wowik; Evil Beaver; webester; soulsteps; Liris; Noxie41; +8 Ответить
4. Sergey.Noskov 1193 28.09.16 14:23 Сейчас в теме
Очень интересно и наглядно.
Вопрос, Не пытались архитектуру регистра заточить под использование кластерного индекса? Судя по последнему плану запроса основную часть ресурсов потребляет операция "Поиск ключа", судя по всему это проверка части условия "..ДатаСменыСтатуса > &Т0.." + получение ресурса "Статус", сделав ДатаСменыСтатуса в составе измерений, уже можно получить профит, а если кластерным будет ключ [Проекция, Период, ДатаСменыСтатуса...], то должны получить максимальную скорость.
5. ildarovich 7268 28.09.16 15:16 Сейчас в теме
(4) Sergey.Noskov, такая мысль была.
Не стал этого делать, поскольку попробовал этот вариант на основной задаче: поиске интервалов. Первый план ему как раз и соответствует. Ощутимого прироста это не дало, поэтому на задаче о статусах пробовать уже не стал.
12. Sergey.Noskov 1193 29.09.16 16:58 Сейчас в теме
(5) а в диаграмме значения "Без индексирования" и "С индексированием" это сравнение каких запросов? Можно план запроса для "Без индексирования" увидеть?
13. ildarovich 7268 30.09.16 09:55 Сейчас в теме
(12) Sergey.Noskov, "с индексированием" это запрос с отбором по проекции:
ВЫБРАТЬ * ИЗ РегистрСведений.Дано 
ГДЕ Проекция В (&МассивПроекций) И &МоментВремени МЕЖДУ НачалоИнтервала И КонецИнтервала


Без индексирования - исходный запрос без такого отбора:
ВЫБРАТЬ * ИЗ Дано 
ГДЕ &МоментВремени МЕЖДУ НачалоИнтервала И КонецИнтервала

Вот его план (в двух видах в приложенных файлах):
Не увидел там ничего интересного, поэтому не стал приводить в статье.
Прикрепленные файлы:
ПланЗапросаБезИндексирования.txt
6. vspl 28.09.16 15:20 Сейчас в теме
Не хочу придираться к сути самой статьи, там все, наверное, правильно,
но для чистоты эксперимента в "Задаче о статусах заявок" нужно все-таки сравнивать быстродействие вот с этим запросом:

ВЫБРАТЬ * ИЗ РегистрСведений.СтатусыЗаявок.СрезПоследних(&Т0, Статус В (&Новый, &ВРаботе))

При условии, конечно, что Статус - индексированный

В этом случае результаты будут ИМХО не такие радужные
7. ildarovich 7268 28.09.16 15:25 Сейчас в теме
(6) vspl, это не эквивалентные запросы.
LordKim; ImHunter; Silenser; +3 Ответить
9. speshuric 1215 28.09.16 16:14 Сейчас в теме
(6) При небольшом количестве статусов (я думаю, до 50, могу проверить) СрезПоследних без явного отбора по заявкам всегда будет уходить в скан. Про это и была исходная задача. Задача описанная в этой статье - это вторая часть той задачи и она не эквивалентна срезу да и не решается только через срез.
ildarovich на самом деле молодец, сразу увидел главную граблю задачи по интервалам.
8. kare 21 28.09.16 15:26 Сейчас в теме
10. bulpi 185 28.09.16 21:21 Сейчас в теме
Задача со статусами , ИМХО, проще решается путем ввода условия
РегистрСведений.СтатусыЗаявок.СрезПоследних(&Т0, Период>=&ДатаПотериИнтереса)
, где ДатаПотериИнтереса =Т0- ИнтервалИнтересаВСекундах

, где ИнтервалИнтересаВСекундах - интервал, дальше которого пофиг на все незакрытые статусы. Такой интервал в реальных задачах всегда есть. Пусть даже большой. Например, год или два.
11. speshuric 1215 28.09.16 22:37 Сейчас в теме
(10) bulpi, Если этот интервал больше 10% от общего времени жизни - будут сканы. Точнее так: в 8.2 будет сканирование большого диапазона кластеризованного индекса, в 8.3 скорее всего будет полный скан (судя по освещённым в Sergey.Noskov изменениям).
14. user614720_vinzax 30.09.16 10:00 Сейчас в теме
Правда есть один забавный момент - есть такая константа "НеИспользоватьРазделениеПоОбластямДанных", так вот чтобы был доступен пункт с дополнительными отчетами и обработками она должна быть установлена в "Истина". Устанавливаться она должна, по идее, автоматически, но, видимо, разработчики БСП где-то что-то упустили и по умолчанию установлено значение "Ложь".
Можно зайти через "все функции", найти эту константу и установив значение "Истина" получить доступ к настройке внешних отчетов и обработок.
15. Serg O. 191 15.06.17 11:12 Сейчас в теме
крутатень! Ещё одно доказательство, что Правильная архитектура - очень важна!

мат. подход нужен, когда уже не помогает подход с матом
user656955_chel1C; +1 Ответить
17. kasper076 77 07.07.17 07:58 Сейчас в теме
Решил "реиндексировать" РС "СостоянияСогласованияЗаявок" УПП. При заполнении реквизита "Проекция" периодически возникала ошибка "Неправильное значение аргумента встроенной функции (Log)". Анализ показал, что в случае когда соседние записи в РС идут с одной и той же датой в поле период, то код
log(Макс(До - От, От - До)
выдает ошибку, т.к. log(0) не существует. Как решить эту проблему? Я понимаю, что записи в пределах секунды разнесены, но как учесть это в алгоритме расчета проекции не понимаю.
18. Release 07.07.17 08:01 Сейчас в теме
(17)Почему бы для До, От не использовать МоментВремени()?
19. kasper076 77 07.07.17 08:24 Сейчас в теме
(18) между моментами времени нельзя вычислить разность.
20. ildarovich 7268 07.07.17 09:47 Сейчас в теме
(17) Проще всего заменить выражение
Масштаб = pow(2, 99 - Цел(99 - Окр(log(Макс(До - От, От - До)) / log(2), 10)));
выражением
Масштаб = 1;
Тогда в следующем цикле будет выполняться больше итераций, а результат будет тем же. Ну, а если все же хочется убрать "лишние" итерации, то нужно проверить условие "От = До". Если оно выполняется, то масштаб принять равным единице:
Масштаб = ?(От = До, 1, pow(2, 99 - Цел(99 - Окр(log(Макс(До - От, От - До)) / log(2), 10))));
Кажется, так.
21. kasper076 77 07.07.17 10:06 Сейчас в теме
(20) Спасибо. Сейчас попробую.
Еще такой момент. Возможно обработка "Реиндексация" писалась на скорую руку и предполагалось, что конечный пользователь сам ее оптимизирует. Спасибо и за это. А возможно что-то упускаю и нужно было сделать именно так, как сделано.
Вот что есть сейчас:
	НаборЗаписей = РегистрыСведений.СтатусыЗаявок.СоздатьНаборЗаписей();
	НаборЗаписей.Прочитать();
	Таблица = НаборЗаписей.Выгрузить();
	Таблица.Сортировать("Заявка, Период");

При наличии в ТЗ ~2,5 млн строк Таблица.Сортировать("Заявка, Период") выполняется оч долго. Сделал так:
	Запрос = Новый Запрос(
	"ВЫБРАТЬ *
	|ИЗ
	|	РегистрСведений.СостоянияСогласованияЗаявок КАК СостоянияСогласованияЗаявок
	|
	|УПОРЯДОЧИТЬ ПО
	|	Заявка,
	|	Период
	|АВТОУПОРЯДОЧИВАНИЕ");
	
	Таблица = Запрос.Выполнить().Выгрузить();
Показать
22. ildarovich 7268 07.07.17 11:13 Сейчас в теме
(21) Если вы про обработку "Реиндексация" из примеров к статье, то все так и было.
Если реиндексацию необходимо делать не один раз, а часто, то интервалы лучше находить на основе алгоритма из статьи: Быстрое определение интервалов в запросе. Если постараться, то и проекцию можно сразу в запросе посчитать.
Оставьте свое сообщение

См. также

Безопасная работа с транзакциями во встроенном языке Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Разбираемся с опасностями использования транзакций во встроенном языке 1С. Познаем ошибку "В данной транзакции уже происходили ошибки". Учимся защищаться от них.

1 стартмани

25.03.2019    41622    tormozit    58    

Семеро одного не ждут? Асинхронное исследование асинхронности

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

Все уже, наверное, знают о появлении в новых версиях платформы асинхронных функций и конструкций Асинх/Ждать. Многие, возможно, уже их используют. Но что будет, если создать свои асинхронные функции, запустить и не дожидаться окончания их выполнения? Неужели можно запустить несколько процессов параллельно?

1 стартмани

08.06.2021    3362    Alxby    41    

Динамическая расшифровка СКД (на примере отчета)

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Предлагаю Вашему неподкупному вниманию вариант более-менее унифицированной реализации динамически формирующейся расшифровки СКД на примере простейшего отчета для конфигурации УТ 11.

1 стартмани

08.12.2020    874    mr_sav    2    

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

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

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

1 стартмани

07.12.2020    3522    user1502278    17    

Как выполнить отчет на СКД через COM и получить данные отчета? Промо

Практика программирования v8 УПП1 Россия Абонемент ($m)

Для чего это нужно. Например, нужно в одной базе получить какой-либо показатель из другой базы. Этот показатель вычисляется в каком-либо сложном отчете, который написан на СКД. Можно, конечно, "скопипастить" текст запроса из другой базы, немного подправить его и выполнять в том же COM подключении. Но с этим теряется гибкость: если отчет изменился, то нужно помнить о том, что где-то есть его "немного модифицированная" копия. В статье будет рассмотрен пример получения данных из базы ЗУП.

2 стартмани

08.05.2018    28097    wowik    3    

Cбор и анализ ошибок при помощи Sentry, или как упростить жизнь себе и пользователям

Практика программирования Интеграция v8 Абонемент ($m)

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

1 стартмани

09.10.2020    5562    hexhoc    12    

Программная корректировка при выводе отчета СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Большинство отчетов на СКД, требующих программной корректировки, реализуются с помощью программной настройки СКД или обработки табличного документа уже после вывода отчета. Но во многих случаях более оптимально будет выполнять программную корректировку в процессе вывода отчета. Для этого существуют программные объекты, о которых я расскажу в данной статье.

1 стартмани

08.10.2020    7611    dabu-dabu    13    

Загрузка, скачивание, удаление файлов с помощью НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера()

Практика программирования v8 1cv8.cf Абонемент ($m)

В платформе 8.3.15 появились новые методы НачатьПомещениеФайлаНаСервер() и НачатьПолучениеФайлаССервера(). В данной статье рассмотрено готовое решение проверенное и прекрасно работающее на тонком и веб-клиенте.

1 стартмани

25.07.2020    8573    Flashill    13    

Как нарисовать граф на 1С Промо

Практика программирования v8 Абонемент ($m)

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

1 стартмани

09.08.2013    72301    ildarovich    117    

Параллельные вычисления расчета факториала числа N

Практика программирования v8 1cv8.cf Абонемент ($m)

Распараллеливание алгоритма с помощью фоновых заданий (асинхронные вычисления)

1 стартмани

29.06.2020    3524    Rustig    18    

Универсальная печатная форма Приказа/Договора с возможностью настройки макета в пользовательском режиме

Практика программирования Универсальные печатные формы v8 1cv8.cf Абонемент ($m)

В данной статье я опишу реализацию универсальной (в кавычках) печати Приказа (Договора или чего пожелаете) с возможностью настройки выводимого текста с параметрами из пользовательского режима

1 стартмани

24.06.2020    1994    BuriyLesha    0    

Методика обновления формы объекта данных при изменении объекта

Практика программирования v8 v8::УФ 1cv8.cf Абонемент ($m)

В формах объектов данных часто встречаются элементы, косвенно связанные с объектом. Логику обновления этих элементов при изменении объекта обычно вызывают из обработчиков ПриСозданнииНаСервере и ПриОткрытии, забывая про наличие других способов изменения объекта. В статье предложена методика для обычных и управляемых форм, учитывающая все способы.

1 стартмани

09.03.2020    15278    tormozit    14    

Минимализмы 3 Промо

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

Очередная серия "минимализмов" [http://infostart.ru/public/306536/, https://infostart.ru/public/460935/]. Также, как и в предыдущих статьях, здесь приведена подборка коротких оригинальных авторских решений некоторых задач. Ранее эти решения были разбросаны по моим комментариям к чужим публикациям.

19.02.2018    48876    ildarovich    47    

Отправка уведомлений с помощью командной строки, Оповещения с сервера на клиент с помощью командной строки

Практика программирования v8 1cv8.cf Россия Абонемент ($m)

Отправка уведомлений с помощью команды командной строки msg. Оповестить пользователей из серверного модуля или регламентного задания, с помощью командной строки msg.

1 стартмани

05.03.2020    7125    user5300    3    

Вывод сообщений в HTML поле средствами 1С

Практика программирования v8 v8::УФ Абонемент ($m)

Пример использования вывода большого количества сообщений в поле HTML. С возможностью открывать ссылочные объекты и создавать новые объекты передавая параметры прямо из HTML поля. Протестировано на релизах 8.3.12 и 8.3.15+

2 стартмани

31.01.2020    7120    burni4    16    

Краткое руководство по внесению изменений в конфигурацию

Практика программирования v8 1cv8.cf Абонемент ($m)

Кратко описаны основополагающие моменты при старте групповой разработки конфигурации несколькими программистами. Полезно для проектной документации как требование к разработчикам или сопровождающей компании.

1 стартмани

13.01.2020    20700    sapervodichka    41    

Бесплатная проверка контрагентов в ФНС (общий модуль с алгоритмом). На примере выводим статус в список справочника контрагентов Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

Если вам интересно проверить контрагенте в ФНС, вам поможет данная публикация. Весь алгоритм работы строится на основе данных, полученных с сервиса http://npchk.nalog.ru совершенно бесплатно.

1 стартмани

01.02.2018    36951    rpgshnik    49    

Универсальные функции: разложение произвольной строки адреса в структуру

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

Процедуры и функции раскладывают произвольную строку адрес в структуру по ключевым словам.

1 стартмани

30.12.2019    5109    vik070777    10    

"Живые" картинки со Snap.SVG

Практика программирования WEB Работа с интерфейсом v8 Абонемент ($m)

В статье рассмотрен пример использования http-сервисов для визуализации данных

1 стартмани

24.10.2019    14616    blackhole321    7    

RLS - дубли условий в запросах к СУБД

Практика программирования Роли и права v8 v8::Права 1cv8.cf Абонемент ($m)

"Подводные камни", возникающие при бездумном копировании ролей с ограничениями RLS, как это отражается на производительности, разбор примера и инструмент для анализа.

1 стартмани

07.10.2019    9422    geron4    4    

БСП: Дополнительная обработка (Регламенты), примеры от простого к сложному Промо

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

Очень много попадается странных решений, которые можно решить через БСП:Дополнительные отчеты и обработки. Я бы вообще БСП из-за этой подсистемы переименовал в «Большое Спасибо Программистам». Поработаем с подсистемой в части написания регламентных заданий.

1 стартмани

10.05.2018    50132    dsdred    44    

Полное копирование одной формы в другую

Практика программирования Универсальные обработки Работа с интерфейсом v8 1cv8.cf Абонемент ($m)

Однажды я столкнулся с необходимостью открыть форму ЛЮБОГО документа с определенными изменениями, не зависящими от структуры объекта (например, заблокировать все кнопки). В интернете решения я не нашел. Обычно на форумах на запросы подобного рода отвечают чем-то вроде "покажи первоначальную задачу, а не спрашивай как реализовать то, что ты придумал". Тем не менее, мне стало интересно, как это можно сделать.

1 стартмани

03.10.2019    7008    nekit_rdx    24    

Многопоточная обработка данных на примере перепроведения документов

Обработка документов Практика программирования v8 ERP2 УТ11 КА2 Абонемент ($m)

Дальнейшее развитие темы фоновой обработки данных - проведение документов в потоках. Настройка параметров и запуск основного процесса (менеджера потоков). Разбивка документов для проведения на не связанные друг с другом наборы и запуск дополнительных фоновых заданий для отдельных потоков. Отслеживание выполнения каждого потока в родительском сеансе.

1 стартмани

17.09.2019    11276    ids79    46    

Отображение истории выполнения по всем задачам комплексного процесса в документообороте

Документооборот и делопроизводство Практика программирования v8 ДО УУ Абонемент ($m)

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

1 стартмани

15.09.2019    8049    pavelpribytkin96    8    

Некоторая работа с данными через COM Промо

Практика программирования v8 Абонемент ($m)

В статье приведены примеры работы с Платформой 8.X через COM (точнее, через объект COMConnector). Примеры кода были использованы при реализации прикладных задач в процессе трудовой деятельности.

2 стартмани

05.12.2012    59159    wowik    32    

Описание формата внутреннего представления данных 1С в контексте обмена данными

Практика программирования Внешние источники данных v8 v8::УФ 1cv8.cf Абонемент ($m)

Фирма 1С не рекомендует использовать внутреннее представление данных для любых целей, которые отличны от обмена с 1С:Предприятием 7.7. Но сама возможность заглянуть на "внутреннюю кухню" платформы с помощью функций ЗначениеВСтрокуВнутр(), ЗначениеВФайл(), ЗначениеИзСтрокиВнутр() и ЗначениеИзФайла(), дала возможность сообществу программистов 1С разработать новые приемы разработки и анализа. Так, именно на использовании внутреннего представления был построен алгоритм "быстрого массива", который позволяет практически мгновенно создать массив в памяти на основании строки с разделителями. С помощью разбора внутреннего представления можно "на лету" программным кодом выполнить анализ обычной формы и даже сделать редактор графической схемы. Во внутреннем формате сохраняют свои данные между сеансами различные популярные внешние обработки. А еще это возможность сделать быстрый обмен с внешними системами.

1 стартмани

06.09.2019    20986    Dementor    31    

Удобный просмотр результата запроса с большим количеством временных таблиц

Практика программирования v8 Абонемент ($m)

Если Вам часто приходится просматривать в отладчике сложные пакетные запросы с большим количеством временных таблиц, то эта статья для Вас.

1 стартмани

27.08.2019    12179    ids79    22    

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

Практика программирования v8 1cv8.cf Абонемент ($m)

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

2 стартмани

24.08.2019    14777    BenGunn    22    

Работа со схемой запроса Промо

Инструментарий разработчика Практика программирования v8 v8::Запросы Абонемент ($m)

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

1 стартмани

24.04.2018    48815    kalyaka    39    

Иерархия без "В ИЕРАРХИИ"

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

Говорится о том, как эффективно представлять иерархию в СУБД, как получать и использовать эти представления при решении задач в запросной технике. Уточняются и дополняются запросы из статьи "Уровни, глубина, прародители, циклы и аналоги запросом" [https://infostart.ru/public/160707/].

22.08.2019    14137    ildarovich    24    

Изменяющееся контекстное меню в 1С 8.3

Практика программирования Работа с интерфейсом Разработка v8 v8::УФ Абонемент ($m)

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

1 стартмани

06.08.2019    20091    signum2009    16    

Процедура ПриКомпоновкеРезультата

Практика программирования v8 1cv8.cf Абонемент ($m)

Коллекция кода

1 стартмани

26.07.2019    51571    vasilev2015    64    

Многопоточность. Универсальный «Менеджер потоков» (фреймворк) с отслеживанием зависимости объектов Промо

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

Восстановление партий, расчет зарплаты, пакетное формирование документов или отчетов - теперь все это стало доступнее. * Есть желание повысить скорость работы медленных алгоритмов! Но... * Нет времени думать о реализации многопоточности? * о запуске и остановке потоков? * о поддержании потоков в рабочем состоянии? * о передаче данных в потоки и как получить ответ из потока? * об организации последовательности? Тогда ЭТО - то что надо!!!

26.05.2017    50715    DarkAn    86    

10 способов получить модуль числа (а может, и больше)

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

Пишем функцию вычисления модуля числа. Сколько способов существует? Давайте посчитаем!

1 стартмани

11.07.2019    12190    sam441    30    

Ловец дедлоков СУБД

Производительность и оптимизация (HighLoad) Практика программирования Разработка v8 Россия Абонемент ($m)

Анализ простейшего дедлока СУБД в рабочей базе с использованием ЦУП (центра управления производительностью) и profiler MS SQL (Microsoft SQL Server). Эта статья будет полезна людям, изучающим вопросы оптимизации работы 1С, или тем, у кого возникают дедлоки в рабочей базе. UPD 09.07.2019 добавлено воспроизведение блокировки в случае установки управляемой блокировки перед чтением набора записей регистра сведений. UPD 10.07.2019 добавлена тестовая база с примером.

1 стартмани

08.07.2019    12111    azazana    80    

Мониторинг производительности и искусственный интеллект

Производительность и оптимизация (HighLoad) Практика программирования Разработка v8 Абонемент ($m)

Расскажем и покажем практически, как использовать искусственный интеллект на страже мониторинга производительности. У вас появится возможность создать собственного помощника Ларису, которая возьмет на себя вопросы по контролю и диагностике состояния обслуживаемой системы.

1 стартмани

01.07.2019    10032    ivanov660    28    

Новый запрос и новая таблица значений как функции Промо

Практика программирования v8 Абонемент ($m)

Предлагается две простые функции, использование которых уменьшает объем кода в конфигурациях на платформе «1С:Предприятие 8». Эти функции можно добавлять к своему общему модулю, что сделает процесс программирования более эффективным.

1 стартмани

27.11.2012    45976    ildarovich    48    

"Убер на складе": динамический расчет маршрутов с учетом реальных расстояний

Учет ТМЦ Практика программирования Учет ТМЦ v8 УУ Абонемент ($m)

Представляю методику и инструмент для динамического расчета маршрутов отбора на высоконагруженных складах для максимального повышения эффективности склада, ускорения проходимости и, как следствие, экономии денег. Это методика и обработка для интеграции в WMS решения. Тестировалось на 1С 8.3.14.1565.

3 стартмани

24.06.2019    18529    informa1555    17    

1С:Ассемблер. Немного летнего веселья!

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

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

1 стартмани

21.06.2019    32108    Evil Beaver    143    

Еще раз о рабочих днях. Быстрый способ расчета в запросах

Практика программирования Математика и алгоритмы Разработка v8 Абонемент ($m)

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

1 стартмани

20.06.2019    11546    Alxby    15    

Уровни, глубина, прародители, циклы и аналоги запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

В продолжение публикации «Транзитивное замыкание запросом» [http://infostart.ru/public/158512/] добавлены другие варианты использования того же приема. Приведены запросы для быстрого определения уровней всех элементов справочника, максимальной глубины справочника, прародителей произвольных элементов справочника, запрос для быстрого определения циклов (на примере справочника спецификаций «1С:Управление производственным предприятием») и определения множеств аналогов номенклатуры (также на примере конфигурации «1С:Управление производственным предприятием»).

1 стартмани

13.11.2012    117311    ildarovich    98    

Простые примеры сложных отчетов на СКД

Практика программирования v8 v8::СКД 1cv8.cf Абонемент ($m)

Подписи в отчете. Особенности соединения наборов: как соединить несоединяемое. Остатки на дату и обороты по месяцам в одном отчете. Курс валюты на каждую дату без группировок и соединений в запросе. Отчет с произвольными колонками и с произвольной последовательностью. "Неадекватный отчет".

1 стартмани

12.06.2019    34033    Hatson    32    

Графики работы из БСП

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

Не очень давно на канале 1С:БСП была опубликована заметка по использованию Графиков работы и Календарных графиков.

1 стартмани

23.05.2019    3796    fenixnow    0    

Создание внешней печатной формы в формате документа Word

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

В статье написано, как создать внешнюю печатную форму (для конфигураций с БСП) в формате Word.

1 стартмани

17.05.2019    20316    ВикторП    22    

Неоплаченные долги при распределении оплаты по правилу ФИФО одним запросом и намного быстрее, чем Вы думали Промо

Практика программирования Дебиторская и кредиторская задолженность Дебиторская и кредиторская задолженность v8 v8::СКД КА1 УТ10 УПП1 УУ Абонемент ($m)

Предлагается метод для быстрого нахождения неоплаченных долгов при распределении оплаты по правилу ФИФО, основанный на дихотомии. Описывается реализация метода в виде достаточно простого запроса, решающего за линейное время указанную задачу, считавшуюся ранее существенно более трудоемкой. Приводятся примеры использования запроса в отчетах на СКД для конфигураций УТ, КА, УПП.

1 стартмани

28.02.2014    70067    ildarovich    131    

Поле адреса в своем справочнике на примере 1С:Бухгалтерия 3

Практика программирования Разработка v8 v8::БУ БП3.0 Россия Абонемент ($m)

В публикации описано, как добавить поле адреса в свой справочник, чтобы вводить адрес через адресный классификатор.

1 стартмани

17.05.2019    7409    vasilievil    4    

Пример настройки шаблонов и реализации печати отчетов в документ MS Word используя функциональную часть "Библиотеки Стандартных Подсистем 1С" (БСП)

Практика программирования Разработка v8 Россия Абонемент ($m)

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

1 стартмани

23.04.2019    7895    olegpkc    11    

Ops средствами 1С:Предприятие

Практика программирования Разработка v8 1cv8.cf Абонемент ($m)

В статье описан программный пакет "Автоматизация ИТ-процессов" (АИТП), позволяющий автоматизировать задачи по администрированию, управлению и обслуживанию ИТ-инфраструктуры.

1 стартмани

23.04.2019    18194    blackhole321    28    

Транзитивное замыкание запросом Промо

Практика программирования v8 1cv8.cf Абонемент ($m)

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

1 стартмани

29.10.2012    90077    ildarovich    120    

1C + Python + Django Rest Framework + Vue.js. Опыт несложной full-stack разработки

Практика программирования Внешние источники данных Обмен через XML WEB Разработка v8 1cv8.cf Абонемент ($m)

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

1 стартмани

22.04.2019    38365    riposte    68    

Вывод вариантов СКД в таблицы на управляемой форме

Практика программирования Работа с интерфейсом v8 v8::УФ v8::СКД 1cv8.cf Абонемент ($m)

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

05.04.2019    12491    artkor    1    

[EnterpriseData] Антисвертка характеристик номенклатуры при выгрузке в Бухгалтерию

Практика программирования Перенос данных из 1C8 в 1C8 Разработка v8 v8::ПВХ КД УНФ БП3.0 Россия БУ Абонемент ($m)

Рассмотрена выгрузка каждой пары значений Номенклатура - Характерстика из УНФ 1.6 в отдельную номенклатуру в Бухгалтерию 3.0 путём доработки правил обмена в формате EnterpriseData.

1 стартмани

27.03.2019    5467    nforce    6