Улучшение механизма поиска и удаления дублей#795
Open
WonderMr wants to merge 3 commits intocpr1c:developfrom
Open
Улучшение механизма поиска и удаления дублей#795WonderMr wants to merge 3 commits intocpr1c:developfrom
WonderMr wants to merge 3 commits intocpr1c:developfrom
Conversation
Исправление транзакционной логики замены ссылок: - Убран внутренний Попытка/Исключение в первом проходе записи, который приводил к ошибке "В данной транзакции уже происходили ошибки" и блокировал запись всех объектов батча - Убран первый проход записи (проверочный блок) как избыточный — проверка циклических ссылок уже выполняется в ЗаписатьОбъектПриЗаменеСсылок Дедупликация ключей регистров сведений: - Добавлена процедура УдалитьДубликатыКлючейРегистраСведений — после замены ссылок в движениях удаляет записи с дублирующимися ключевыми полями (Период + все Измерения), предотвращая ошибку "Запись с такими ключевыми полями существует" Журнал удаления дублей на форме: - Добавлено поле лога на страницу удаления (ЖурналУдаления) — многострочное, на всю ширину, только чтение, с автопрокруткой вниз - Прогресс пишется в Журнал Регистрации (событие "Поиск и удаление ссылок.Прогресс") с режимом Независимая — записи не теряются при откате транзакций - Клиент читает ЖР при каждом опросе прогресса, отображает полный лог с коррекцией на клиентское время (смещение клиент-сервер) - По каждому дублю пишется итоговая запись (✓ успех / ✗ ошибка) - По каждому месту использования пишется запись с именем дубля и объекта - Счётчик "обработано X из Y" в заголовке считает итоговые записи из ЖР - Лог сохраняется на странице успешного удаления с итогом в конце - Скрыт старый SpreadsheetDocument и отдельная надпись результата Отмена фонового задания: - Кнопка "Прервать" теперь реально отменяет фоновое задание через УИ_ДлительныеОперации.ОтменитьВыполнениеЗадания, а не просто закрывает форму - Идентификатор задания сохраняется в реквизите формы Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Дополнение к c40603f — устранение критического бага с ОСВ после удаления дублей в Бухгалтерии Казахстана и доведение SQL-генератора до рабочего состояния для PostgreSQL и MS SQL Server. Корневая причина бага с ОСВ: - В пути "Объект" функция ИзмененныеОбъектыПриЗаменеВОбъекте обрабатывала движения регистров бухгалтерии через Выгрузить → модификация → Загрузить → Записать(). Для регистра с составными субконто (3 уровня Дт+Кт) Выгрузить включает виртуальные поля ВидСубконтоДт*/Кт*, а Записать() выполняет DELETE+INSERT. Платформа некорректно восстанавливает виртуальные типы при INSERT, что перераспределяет субконто на другой объект того же типа - Аналогичная защита УЖЕ БЫЛА в пути "КлючЗаписи" (ПроизвестиЗаменуВНаборе, стр. 3855), но отсутствовала в пути "Объект" - Симптом: по счёту 1310 одна номенклатура показывала Дт=359380 Кт=566742 сальдо=-207362, общий итог при этом сходился — записи остались, но Субконто Дт1 перераспределилось Защита регистров бухгалтерии в пути "Объект" (УИ_ОбщегоНазначения/Module.bsl, ИзмененныеОбъектыПриЗаменеВОбъекте): - Сигнатура расширена параметром Результат (для накопления ЗаменыТребующиеSQL) - Построение ПарыЗамен перенесено до цикла чтения движений - Для каждого ОписаниеДвижения проверяется тип регистра: если регистр бухгалтерии — помечаем флагом ПропуститьИзЗаРБ, накапливаем пары через НакопитьЗаменуДляSQL, пишем информационную запись в Журнал Регистрации. Набор записей не читается и не модифицируется - Во всех трёх последующих циклах по ОписаниеДвижений добавлен skip-фильтр по флагу ПропуститьИзЗаРБ. Замена выполняется SQL-скриптом после операции SQL-генератор замены ссылок (СгенерироватьSQLСкриптЗамены): - Автоопределение СУБД через парсинг СтрокаСоединенияИнформационнойБазы() по подстроке DBMS=POSTGRESQL / DBMS=MSSQLSERVER. Если определилось — выводится только нужная секция, иначе обе, но MS SQL предваряется префиксом "-- ", чтобы запуск всего файла в PG-клиенте не падал на синтаксисе BEGIN TRY - Корректный порядок байт UUID при формировании decode/0x литералов (СсылкаВHex). 1С хранит ссылки в bytea PG / varbinary(16) MS SQL с полным реверсом сегментов UUID v1: stored = clock_seq(2) + node(6) + timestamp_hi+ver(2) + timestamp_mid(2) + timestamp_low(4), что в hex даёт перестановку chars[17..32] + chars[13..16] + chars[9..12] + chars[1..8]. Подтверждено сравнением реального содержимого _RecorderRRef в БД с XMLString ссылки документа. Без свопа UPDATE даёт 0 affected rows - Пропуск итоговых и служебных таблиц регистров бухгалтерии и накопления (Назначение содержит "ИТОГ" или "НАСТРОЙК": _AccRgAT*, _AccRgCT*, _AccRgOpt*, _AccumRgT*, _AccumRgOpt*). UPDATE по ним вызывает конфликты UNIQUE constraint (когда у Дубля и Оригинала совпадают остальные ключевые поля) и не имеет смысла — итоги пересчитываются автоматически - Каждый UPDATE обёрнут в DO-блок с EXCEPTION (PG) и BEGIN TRY / BEGIN CATCH (MS SQL). При несовместимости типов (например _KindDt*/_KindCt* фактически NUMERIC, а не bytea) или конфликте уникальности скрипт логирует пропуск через RAISE NOTICE / PRINT и продолжает выполнение, не откатывая транзакцию - В шапку SQL добавлено напоминание о необходимости запустить Пересчёт итогов в 1С после применения скрипта Вывод SQL-скрипта в форму лога вместо модального попапа (Forms/ПоискДублей/Module.bsl): - ЗаполнитьРезультатыУдаленияДублей: добавлен out-параметр ТекстSQLСкрипта, удалён вызов Сообщить() — SQL собирается в параметр и дописывается в ЖурналУдаления вызывающим кодом, не показывается всплывающим окном - Логика ЗавершеноБезОшибок теперь игнорирует ошибки с типом ТребуетсяSQL_Итог и ТребуетсяSQL: операция считается успешной, если других (реальных) ошибок не возникло. До этого фикса форма после защиты РБ всегда уходила на ШагНеудачныеЗамены даже для штатно отработавших замен - Обработчик завершения фонового задания дописывает SQL в конец ЖурналУдаления с разделителями "=== SQL-СКРИПТ ДЛЯ ДОВЫПОЛНЕНИЯ ЗАМЕН ===" Поле лога на шаге неудачных замен (Forms/ПоискДублей/Form.form): - На шаг ШагНеудачныеЗамены добавлено поле ЖурналУдаленияНеудача (InputField, multiLine, readOnly), биндится к реквизиту ЖурналУдаления — тому же что и ЖурналУдаленияУспех на шаге успеха - До этого при реальных ошибках лог и SQL-скрипт были скрыты от пользователя: виден был только список необработанных дублей Инструкция по применению: 1. "Поиск и удаление дублей" → выбрать пары → "Удалить" 2. Скопировать SQL-скрипт из ЖурналУдаления (PG/MS SQL секция выводится автоматически в зависимости от текущей СУБД) 3. Выполнить SQL в клиенте СУБД (DataGrip, psql, SSMS) 4. В 1С запустить Пересчёт итогов (Все функции → Стандартные → Управление итогами или РегистрыБухгалтерии.<Имя>.ПересчитатьИтоги() в коде) 5. Запустить "Удаление помеченных объектов" для физического удаления дублей Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Защита регистров бухгалтерии при замене ссылок и доводка SQL-генератора
There was a problem hiding this comment.
Pull request overview
Pull request дорабатывает обработку «Поиск и удаление дублей» в подсистеме «Инструменты разработчика»: исправляет проблемные места при замене ссылок (в т.ч. регистры бухгалтерии), добавляет подробный пользовательский лог и поддержку отмены, а также формирует SQL-скрипт для «довыполнения» замен на уровне СУБД.
Changes:
- Добавлен пользовательский журнал удаления на форме (чтение прогресса из Журнала регистрации), автопрокрутка и вывод SQL-скрипта в лог.
- Реализована защита регистров бухгалтерии при замене ссылок в пути «Объект» через пропуск движений и накопление замен для последующего SQL.
- Добавлены: генератор SQL для PostgreSQL/MS SQL и удаление дублей ключей регистров сведений после замены.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/Инструменты/src/CommonModules/УИ_ОбщегоНазначения/Module.bsl |
Защита регистров бухгалтерии в обработке движений, накопление замен “требуется SQL”, генерация SQL-скрипта, дедупликация ключей РС. |
src/Инструменты/src/DataProcessors/УИ_ПоискИУдалениеДублей/Forms/ПоискДублей/Module.bsl |
Отмена фонового задания, чтение/отображение лога из ЖР, финализация результата удаления и дописывание SQL в лог. |
src/Инструменты/src/DataProcessors/УИ_ПоискИУдалениеДублей/Forms/ПоискДублей/Form.form |
Поля многострочного read-only лога на шагах удаления/успеха/неудачи, привязка к реквизиту формы. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Member
|
@WonderMr сможешь поправить замечания сонара? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Улучшение поиска и удаления дублей + защита регистров бухгалтерии
Краткое описание
Доработка механизма поиска и удаления дублей в подсистеме «Инструменты разработчика»:
устранены критичные баги (некорректная логика транзакций, потеря субконто в регистрах бухгалтерии, ошибка дублирующихся ключей в регистрах сведений), добавлены пользовательский журнал удаления и отмена длительной операции, реализована автогенерация SQL-скрипта для PostgreSQL/MS SQL, чтобы добить замены, которые нельзя сделать через 1С (регистры бухгалтерии).
Изменения разделены на два коммита: первый - функциональные доработки и UX, второй - защита регистров бухгалтерии и SQL-генератор.
Коммит 1 -
3fcb1273Улучшение механизма поиска и удаления дублейТранзакционная логика замены ссылок
Попытка/Исключениев первом проходе записи, который приводил к ошибке«В данной транзакции уже происходили ошибки»и блокировал запись всех объектов батча.ЗаписатьОбъектПриЗаменеСсылок.Дедупликация ключей регистров сведений
УдалитьДубликатыКлючейРегистраСведений. После замены ссылок в движениях процедура удаляет записи с дублирующимися ключевыми полями (Период+ всеИзмерения), предотвращая ошибку«Запись с такими ключевыми полями существует».Журнал удаления дублей на форме
ЖурналУдаления) - многострочное, на всю ширину, только чтение, с автопрокруткой вниз.«Поиск и удаление ссылок.Прогресс») с режимомНезависимая- записи не теряются при откате транзакций.«обработано X из Y»в заголовке формы считает итоговые записи из ЖР.SpreadsheetDocumentи отдельная надпись результата.Отмена фонового задания
«Прервать»теперь реально отменяет фоновое задание черезУИ_ДлительныеОперации.ОтменитьВыполнениеЗадания, а не просто закрывает форму.Коммит 2 -
438b4aaaЗащита регистров бухгалтерии при замене ссылок и доводка SQL-генератораЭтот коммит исправляет критический баг с ОСВ после удаления дублей в Бухгалтерии и доводит SQL-генератор до рабочего состояния для PostgreSQL и MS SQL Server.
Корневая причина бага с ОСВ
«Объект»функцияИзмененныеОбъектыПриЗаменеВОбъектеобрабатывала движения регистров бухгалтерии черезВыгрузить → модификация → Загрузить → Записать(). Для регистра с составными субконто (3 уровня Дт+Кт)Выгрузитьвключает виртуальные поляВидСубконтоДт*/Кт*, аЗаписать()выполняетDELETE+INSERT. Платформа некорректно восстанавливает виртуальные типы приINSERT, что перераспределяет субконто на другой объект того же типа.«КлючЗаписи»(ПроизвестиЗаменуВНаборе, стр. 3855), но отсутствовала в пути«Объект».Защита регистров бухгалтерии в пути «Объект»
Файл:
УИ_ОбщегоНазначения/Module.bsl, функцияИзмененныеОбъектыПриЗаменеВОбъекте.Результат(для накопленияЗаменыТребующиеSQL).ПарыЗаменперенесено до цикла чтения движений.ОписаниеДвиженияпроверяется тип регистра: если регистр бухгалтерии - помечается флагомПропуститьИзЗаРБ, накапливаются пары черезНакопитьЗаменуДляSQL, пишется информационная запись в Журнал Регистрации. Набор записей не читается и не модифицируется.ОписаниеДвиженийдобавлен skip-фильтр по флагуПропуститьИзЗаРБ. Замена выполняется SQL-скриптом после операции.SQL-генератор замены ссылок (
СгенерироватьSQLСкриптЗамены)СтрокаСоединенияИнформационнойБазы()по подстрокеDBMS=POSTGRESQL/DBMS=MSSQLSERVER. Если определилось - выводится только нужная секция; иначе обе, но MS SQL предваряется префиксом--- приоритет для PostgreSQL.decode/0xлитералов (СсылкаВHex). 1С хранит ссылки вbytea(PG) /varbinary(16)(MS SQL) с полным реверсом сегментов UUID v1:stored = clock_seq(2) + node(6) + timestamp_hi+ver(2) + timestamp_mid(2) + timestamp_low(4), что в hex даёт перестановкуchars[17..32] + chars[13..16] + chars[9..12] + chars[1..8].«ИТОГ»или«НАСТРОЙК»:_AccRgAT*,_AccRgCT*,_AccRgOpt*,_AccumRgT*,_AccumRgOpt*).UPDATEпо ним вызывает конфликтыUNIQUE constraint(когда у Дубля и Оригинала совпадают остальные ключевые поля) и не имеет смысла - итоги пересчитываются автоматически.UPDATEобёрнут вDO-блок сEXCEPTION(PG) иBEGIN TRY/BEGIN CATCH(MS SQL). При несовместимости типов (например,_KindDt*/_KindCt*фактическиNUMERIC, а неbytea) или конфликте уникальности скрипт логирует пропуск черезRAISE NOTICE/PRINTи продолжает выполнение, не откатывая транзакцию.Вывод SQL-скрипта в форму лога
Файл:
Forms/ПоискДублей/Module.bsl.ЗаполнитьРезультатыУдаленияДублей: добавлен out-параметрТекстSQLСкрипта- SQL собирается в параметр и дописывается вЖурналУдалениявызывающим кодом.ЗавершеноБезОшибоктеперь игнорирует ошибки с типомТребуетсяSQL_ИтогиТребуетсяSQL: операция считается успешной, если других (реальных) ошибок не возникло. До этого фикса форма после защиты РБ всегда уходила наШагНеудачныеЗаменыдаже для штатно отработавших замен.ЖурналУдаленияс разделителями=== SQL-СКРИПТ ДЛЯ ДОВЫПОЛНЕНИЯ ЗАМЕН ===.Поле лога на шаге неудачных замен
Файл:
Forms/ПоискДублей/Form.form.ШагНеудачныеЗаменыдобавлено полеЖурналУдаленияНеудача(InputField, multiLine, readOnly), биндится к реквизитуЖурналУдаления- тому же, что иЖурналУдаленияУспехна шаге успеха.Изменённые файлы
src/Инструменты/src/CommonModules/УИ_ОбщегоНазначения/Module.bsl- защита РБ в пути «Объект», SQL-генератор, дедупликация ключей РС.src/Инструменты/src/DataProcessors/УИ_ПоискИУдалениеДублей/Forms/ПоискДублей/Module.bsl- журнал удаления, отмена ФЗ, обработка результата с SQL-скриптом.src/Инструменты/src/DataProcessors/УИ_ПоискИУдалениеДублей/Forms/ПоискДублей/Form.form- поля журнала на страницах успеха и неудачи, перенос блока «Все места использования».Инструкция по применению
ЖурналУдаления(PG / MS SQL секция выводится автоматически в зависимости от текущей СУБД).DataGrip,psql,SSMS).Все функции → Стандартные → Управление итогамиилиРегистрыБухгалтерии.<Имя>.ПересчитатьИтоги()).План тестирования
Период+Измерения) - проверить, чтоУдалитьДубликатыКлючейРегистраСведенийотрабатывает без ошибки«Запись с такими ключевыми полями существует».psql/DataGrip. Проверить отсутствие синтаксических ошибок и попаданиеRAISE NOTICEв лог при несовместимости типов.«Прервать»- фоновое задание реально останавливается, форма не виснет.