Описывая ситуацию на примере Управление торговлей, редакция 11 (11.4.6.166).
Началось все с того, что в какой то момент данные отчета Ведомость расчетов с клиентами перестали совпадать с данными сверок взаиморасчетов. Попытку идти привычным путем - искать, какой же документ вызвал расхождение, ожидало фиаско. Если посмотреть на код формирования отчета, то можно увидеть, что данные он получает из регистра "РасчетыСКлиентамиПоСрокам". А регистратор у этого регистра всего один - документ "Регистратор расчетов", у которого всего несколько реквизитов: ОбъектРасчетов, АналитикаУчетаПоПартнерам, Валюта и ТипРасчетов. ТипРасчетов в моем случае - это "Расчеты с клиентом". АналитикаУчетаПоПартнерам включает в себя комбинацию "Организация"+"Партнер". Объект расчетов - в моем случае - Заказ клиента. Что происходит при проведении любого документа, из группы документов, сформированных по этому критерию ? А происходит полный пересчет всех данных по этой группе, и полученный результат записывается в регистр "Расчеты с киентами по срокам" при помощи регистратора "Регистратор расчетов". Вследствии чего данные в этом регистре всегда актуальны, независимо от последовательности проведения документов этой группы. Причем, при простом перепроведении документов учета - будь то реализация или документ оплаты, пересчета происходить не будет - для оптимизации сделано так, что пересчет производится только при выявлении каких либо изменений в документе учета. Следовательно, при переборе путей исправления расхождения отчета и акта сверки - простое перепроведение документов помочь не может. Да и неплохо бы понять, сколько вообще в базе таких ошибок. Сваял для этого отчет по выявлению таковых ошибок. Отчет прилагается в архиве, запрос СКД привожу здесь:
Выявление расхождений между регистрами "РасчетыСКлиентами" и "РасчетыСКлиентамиПоСрокам"
ВЫБРАТЬ
вв0.АналитикаУчетаПоПартнерам КАК АналитикаУчетаПоПартнерам,
вв0.ЗаказКлиента КАК ЗаказКлиента,
вв0.Валюта КАК Валюта,
вв0.АналитикаУчетаПоПартнерам.Партнер КАК Партнер,
СУММА(вв0.СуммаПриход) КАК СуммаПриход,
СУММА(вв0.ДолгПриход) КАК ДолгПриход,
СУММА(вв0.ПредоплатаПриход) КАК ПредоплатаПриход,
СУММА(вв0.СуммаРасход) КАК СуммаРасход,
СУММА(вв0.ДолгРасход) КАК ДолгРасход,
СУММА(вв0.ПредоплатаРасход) КАК ПредоплатаРасход,
СУММА(вв0.СуммаПриход - вв0.СуммаРасход - (вв0.ДолгПриход+вв0.ПредоплатаРасход - вв0.ДолгРасход-вв0.ПредоплатаПриход)) КАК Разность
ИЗ
(ВЫБРАТЬ
РасчетыСКлиентамиОбороты.АналитикаУчетаПоПартнерам КАК АналитикаУчетаПоПартнерам,
РасчетыСКлиентамиОбороты.ЗаказКлиента КАК ЗаказКлиента,
РасчетыСКлиентамиОбороты.Валюта КАК Валюта,
РасчетыСКлиентамиОбороты.СуммаПриход КАК СуммаПриход,
РасчетыСКлиентамиОбороты.СуммаРасход КАК СуммаРасход,
0 КАК ПредоплатаПриход,
0 КАК ПредоплатаРасход,
0 КАК ДолгПриход,
0 КАК ДолгРасход
ИЗ
РегистрНакопления.РасчетыСКлиентами.Обороты(&НачалоПериода,&КонецПериода , , ) КАК РасчетыСКлиентамиОбороты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
РасчетыСКлиентамиПоСрокамОбороты.АналитикаУчетаПоПартнерам,
РасчетыСКлиентамиПоСрокамОбороты.ОбъектРасчетов,
РасчетыСКлиентамиПоСрокамОбороты.Валюта,
0,
0,
РасчетыСКлиентамиПоСрокамОбороты.ПредоплатаПриход,
РасчетыСКлиентамиПоСрокамОбороты.ПредоплатаРасход,
РасчетыСКлиентамиПоСрокамОбороты.ДолгПриход,
РасчетыСКлиентамиПоСрокамОбороты.ДолгРасход
ИЗ
РегистрНакопления.РасчетыСКлиентамиПоСрокам.Обороты(&НачалоПериода,&КонецПериода , , ) КАК РасчетыСКлиентамиПоСрокамОбороты) КАК вв0
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.АналитикаУчетаПоПартнерам КАК РегАналитика
ПО (РегАналитика.КлючАналитики = вв0.АналитикаУчетаПоПартнерам)
{ГДЕ
вв0.АналитикаУчетаПоПартнерам.Партнер.*}
СГРУППИРОВАТЬ ПО
вв0.АналитикаУчетаПоПартнерам,
вв0.ЗаказКлиента,
вв0.Валюта,
вв0.АналитикаУчетаПоПартнерам.Партнер
ИМЕЮЩИЕ
не СУММА(вв0.СуммаПриход - вв0.СуммаРасход - (вв0.ДолгПриход+вв0.ПредоплатаРасход - вв0.ДолгРасход-вв0.ПредоплатаПриход))=0
Отчет показал, что некоторое количество ошибок в базе накопилось. Сразу оговорюсь, что вины типовой конфигурации в моем случае не было, причиной послужила некорректная доработка, а именно, документ, который записывал движения непосредственно в регистр "РасчетыСКлиентамиПоСрокам", что недопустимо. Ниже я приведу шаблон модуля документа, которому необходимо следовать при разработке.
Что ж, список ошибок получен. Нужно их исправлять. Самый простой способ - это переключить в настройках способ ведения взаиморасчетов - вначале на офлайн, потом вернуть обратно онлайн.
Но тут я не советовал бы торопиться это делать - довольно длительная операция - как в ту, так и в обратную сторону. Поэтому я стал исправлять точечно. Тут есть муторный путь - отменять проведение какого либо документа из группы по объекту расчетов (Заказу клиента) и проводить его. Ошибка при этом пропадает. Решил несколько оптимизировать - написал такой код для исправления выбранного заказа клиента:
"Перепроведение" регистратора расчетов
ОсновныеПараметры = ОперативныеВзаиморасчетыСервер.СтруктураПараметровЗаполненияВзаиморасчетов();
//ОсновныеПараметры:
//Структура = Новый Структура;
//Структура.Вставить("ОбъектРасчетов");
//Структура.Вставить("АналитикаУчетаПоПартнерам");
//Структура.Вставить("ВалютаРасчетов");
//Структура.Вставить("ЭтоРасчетыСКлиентами");
//Структура.Вставить("Порядок","");
//Структура.Вставить("ТолькоПланы", Ложь);
//Структура.Вставить("Регистратор", Неопределено);
//Структура.Вставить("ДополнительныеСвойстваПроведения", Неопределено);
// выясним необходимые данные для заполнения ОсновныеПараметры. Будем считать, что в РасчетыСКлиентами все в норме
// и для заданного ЗаказКлиента набор АналитикаУчетаПоПартнерам,Валюта,ЗаказКлиента однозначен
запрос=новый запрос;
запрос.Текст=
"ВЫБРАТЬ
| РасчетыСКлиентами.АналитикаУчетаПоПартнерам КАК АналитикаУчетаПоПартнерам,
| РасчетыСКлиентами.ЗаказКлиента КАК ОбъектРасчетов,
| РасчетыСКлиентами.Валюта КАК ВалютаРасчетов
|ИЗ
| РегистрНакопления.РасчетыСКлиентами КАК РасчетыСКлиентами
|где ЗаказКлиента=&ЗаказКлиента
|сгруппировать по АналитикаУчетаПоПартнерам,ЗаказКлиента,Валюта
|";
запрос.УстановитьПараметр("ЗаказКлиента",ЗаказКлиента);
выборка=запрос.Выполнить().Выбрать();
если не выборка.Следующий() тогда
сообщить("По регистру РасчетыСКлиентами не найдено данных по выбранному заказу клиента");
возврат;
КонецЕсли;
заполнитьзначениясвойств(ОсновныеПараметры,выборка);
ОсновныеПараметры.ЭтоРасчетыСКлиентами=истина;
ОперативныеВзаиморасчетыСервер.ЗаполнитьОперативныеВзаиморасчеты(ОсновныеПараметры);
Код работает - ошибки исправляет. Чтож, финита! остается все лишь совместить первый отчет со списком ошибок и запустить этот кусок кода в цикле, и база исправлена.
Каким же образом действовать, если требуется добавить в конфигурацию документ, который будет делать движения по регистру "РасчетыСКлиентами" и работать корректно при использовании новой архитектуры взаиморасчетов ? Пишу шаблон модуля такого документа (это опять таки - для УТ 11.4.6.166. Для других релизов возможны отличия)
Шаблон модуля документа для работы с регистром РасчетыСКлиентами
Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
ДополнительныеСвойства.Вставить("ЭтоНовый", ЭтоНовый());
ДополнительныеСвойства.Вставить("РежимЗаписи", РежимЗаписи);
КонецПроцедуры
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
ПроведениеСерверУТ.ИнициализироватьДополнительныеСвойстваДляПроведения(Ссылка, ДополнительныеСвойства, РежимПроведения);
Движения.РасчетыСКлиентами.Записывать=Истина;
// ........
// здесь формируется набор записей регистра накопления РасчетыСКлиентами
ПроведениеСерверУТ.ЗаписатьНаборыЗаписей(ЭтотОбъект);
КонецПроцедуры
Все написанное не претендует на полное описание данного функционала, которое можно посмотреть в мануале. Да и здесь, на сайте, я видел довольно грамотную статью - я так точно писать не умею. Пишу скорее о том, как столкнулся с ним, и как действовал.
Что в архиве:
ВыявлениеРасхожденийМеждуРегистрами.erf
ПерепроведениеРегистратораРасчетов.epf
В принципе, практически весь код файлов из архива приведен в статье. В качестве бонуса прилагаю отчет по взаиморасчетам, который строится по регистру "РасчетыСКлиентами" - просто РасчетыСКлиентами.ОстаткиИОбороты; группировки Партнер / Заказ клиента / Регистратор