Попалась база КА 2.4 с движениями по регистрам, у которых регистратор был непроведен или помечен на удаление.
Написал небольшую обработку по удалению таких записей из регистров.
Написал небольшую обработку по удалению таких записей из регистров.
Задача: Перебрать все регистры накопления, выявить непроведенные регистраторы и удалить движения.
В цикле собираю мега-запрос ко всем регистрам накопления, группирую по регистратору и имени регистра.
Создаю набор записей, устанавливаю отбор по регистратору и записываю набор.
Тестировал на платформе 1С:Предприятие 8.3 (8.3.14.1565)
Обработка универсальная, будет работать на любой конфигурации. Открывается через "Файл" — "Открыть".
Ваша обработка ошибочно удалит движения документов, у которых отключено проведение (Проведение = Запретить в конфигураторе).
На достаточно большой базе будет либо неоправданно долго работать, либо упадет из-за недостатка памяти вот из-за этой строки:
Не Регистр.Регистратор.Проведен
Ну еще и «Выбрать различные» вместо «Выбрать» нужно и «Объединить» вместо «Объединить все»…
(3) Протестировал. Если добавить «Выбрать различные», то 1с предприятие падает с ошибкой.
The query processor ran out of internal resources and could not produce a query plan.
This is a rare event and only expected for extremely complex queries or queries that reference a very large number of tables or partitions.
Please simplify the query. If you believe you have received this message in error, contact Customer Support Services for more information.
А в «Объединить» не вижу смысла, т.к. результаты запросов будут разные по двум измерениям «имя регистра» и регистратор.
Не проще написать: РегистрыНакопления[<ИмяРегистра>].СоздатьНаборЗаписей(); ?
я не спец, но может как-то сразу ограничить подмножестова?
— выбираем все виды документов, которые по настройкам конфигурации могут быть проведены;
— по полученным видам собираем все непроведенные доки;
— для всех непроведенных доков ищем записи проведения в регистрах…
так правильнее будет или нет?
(6) Можно было и таким путем пойти. Но у меня была цель универсальность. Если со временем добавят новые документы и новые регистры. Мой метод будет работать.
1. У Вас запрос собирается текстом. Почитайте про конкатенацию строк
https://its.1c.ru/db/v8std#content:782:hdoc
2. НЕ Регистр.Регистратор.Проведен. Тут сразу две ошибки в запросе. Первая — обращение через точку к составному типу(чаще всего регистр двигают несколько документов), и вторая — отрицание, что делает невозможным поиск по индексу.
3. ТИПЗНАЧЕНИЯ(Регистр.Регистратор) — вычисления по полю так же исключает поиск в индексе.В этой же строке <>
4. Итоговая группировка при КМК абсолютна лишняя, гораздо выгоднее сразу выбирать различные.
5. Упорядочивание по периоду так же лишняя, если учесть, что интерактивного анализа не подразумевается. Сортировка очень тяжелая операция.
6. В случае исключительной ситуации выполнение упадет, при этом придется так на каждую ошибку запускать заново. при этом целостность движений может пострадать, хоть эти движения и считаются лишними.
7. Команда выполнить не совсем к месту.
Как итог, самые большие проблемы в запросе. Если запустить Вашу обработку на системах с таблицами более миллиона записей, с несколькими регистраторами, то DBA Вам по пальцам настучит.
(4)
Ошибка заключается в том, что SQL отказался с Вами играть и попросил переделать запрос
(7) С новыми да, пока они не разрастутся.
(8)Спасибо за подробный разбор.
1. Исправил.
4. Так сразу падает 1с. Выше писал(4)
5. Убрал. Решал другую задачу.
7. Убрал
(11) п.2 и 3 особо критичны.
п.4 будет работать после исправления п.2 и п.3
(12) Каким образом можно убрать конструкцию Регистр.Регистратор.Проведен, если мне нужны все непроведенные документы?
(13)ограничением типа документа и объединение со всеми типами.
Не забывайте, что mssql имеет ограничение на 256 таблиц.
В конструкции регистратор. Проведён будет неяное соединение с каждой таблицей составного типа для каждой записи
Давно такого говнокода не попадалось)
Мое решение для «консоли запросов» на скрине к этому сообщению (для КА 2.4).