Приветствуем вас, уважаемые коллеги! Работа в системе «1С:Предприятие 7.7», особенно в популярной конфигурации «Торговля и Склад 9.2» (ТиС), до сих пор актуальна для множества предприятий благодаря ее высокой скорости работы и надежности. Однако устаревшая архитектура платформы иногда преподносит неприятные сюрпризы пользователям и начинающим программистам. Одним из таких сюрпризов является классическая проблема: при формировании отчета «Ведомость по контрагентам» по конкретному клиенту внезапно «вылезает» документ реализации (или любой другой первичный документ), оформленный на совершенно другого контрагента. При этом, если мы откроем общий журнал документов или реестр, там все выглядит абсолютно корректно — контрагент указан правильно.
Давайте подробно разберем, почему возникает это расхождение, как устроена архитектура регистров в 1С 7.7, и пошагово решим эту проблему раз и навсегда.
Для того чтобы понять корень проблемы, проанализируем, как именно платформа «1С:Предприятие 7.7» хранит и обрабатывает данные о взаиморасчетах. В отличие от современных конфигураций на платформе 1С 8.x, где учет ведется в разрезе нескольких независимых измерений (таких как Организация, Контрагент, Договор), в «Торговле и Складе 7.7» архитектура регистров накопления более лаконична.
Учет взаиморасчетов с покупателями и поставщиками ведется в специализированных регистрах накопления, главным из которых является регистр Покупатели (или Взаиморасчеты). Давайте обратим внимание на структуру измерений этого регистра. В нем отсутствует отдельное измерение «Контрагент»! Основным аналитическим разрезом, определяющим, за кем числится долг, выступает измерение Договор.
Справочник Договоры в системе является подчиненным справочнику Контрагенты. Это означает, что у каждого элемента справочника Договоры есть обязательный реквизит Владелец, ссылающийся на конкретного контрагента.
Когда вы формируете отчет «Ведомость по контрагентам», система не берет данные напрямую из реквизита «Контрагент» в документах. Она делает запрос к регистру накопления, выбирает движения по договорам и группирует их по контрагентам, обращаясь к владельцу договора через стандартную точку связи: Договор.Владелец.
Теперь представим ситуацию: в документе «Реализация» в поле «Контрагент» выбран Контрагент А, а в реквизите «Договор» ошибочно указан договор, принадлежащий Контрагенту Б. При проведении документа платформа запишет в регистр движения именно по этому ошибочному договору. Как результат:
Выясним причину, как такая некорректная связка («чужой» договор у контрагента) вообще могла оказаться в информационной базе. Штатный интерактивный интерфейс типовой конфигурации «Торговля и Склад» при ручном вводе жестко контролирует соответствие договора выбранному контрагенту. Но существуют обходные пути:
SetAttrs.ert для массового изменения реквизитов. Если была произведена групповая замена контрагента в проведенных документах, но при этом забыли заменить подчиненный реквизит «Договор», возникает рассинхронизация.Давайте разберем по шагам, как локализовать и подтвердить эту ошибку в вашей базе данных:
Для устранения ошибки нам необходимо восстановить корректную связь между контрагентом и договором в самом документе, а затем пересчитать движения регистров.
Покупатели с правильной аналитикой.Операции -> Проведение документов, выберите вкладку Последовательности, укажите последовательность взаиморасчетов и запустите восстановление с даты самого раннего исправленного документа.Если база данных большая, искать такие документы вручную в отчетах крайне трудоемко. Мы можем написать простую внешнюю обработку, которая автоматически проверит всю базу данных за выбранный период и выведет список документов, в которых нарушена связь «Контрагент - Договор».
Рассмотрим пример кода на встроенном языке 1С 7.7, который можно использовать в модуле внешней обработки:
// Создаем объект для обхода документов определенного вида, например, Реализации
Док = СоздатьОбъект("Документ.Реализация");
Док.ВыбратьДокументы(ДатаНачала, ДатаКонца);
Пока Док.ПолучитьДокумент() = 1 Цикл
// Проверяем, проведен ли документ, так как непроведенные документы не делают движений в регистрах
Если Док.Проведен() = 1 Тогда
// Сравниваем владельца договора с контрагентом, указанным в документе
Если Док.Договор.Владелец <> Док.Контрагент Тогда
Сообщить("В документе " + Док + " нарушена целостность данных!");
Сообщить(" Контрагент в документе: " + Док.Контрагент.Наименование);
Сообщить(" Владелец договора: " + Док.Договор.Владелец.Наименование);
КонецЕсли;
КонецЕсли;
КонецЦикла;
Запустив этот несложный скрипт, вы мгновенно получите полный список «кривых» документов и сможете точечно исправить каждый из них, сэкономив массу времени.
В случае, когда некорректных документов обнаружены сотни, исправлять их вручную не имеет смысла. Мы можем модифицировать наш код, чтобы он автоматически исправлял договор на основной договор контрагента и перепроводил документ:
Док = СоздатьОбъект("Документ.Реализация");
Док.ВыбратьДокументы(ДатаНачала, ДатаКонца);
Пока Док.ПолучитьДокумент() = 1 Цикл
Если Док.Проведен() = 1 Тогда
Если Док.Договор.Владелец <> Док.Контрагент Тогда
// Находим основной договор контрагента
СпрДоговоры = СоздатьОбъект("Справочник.Договоры");
СпрДоговоры.ИспользоватьВладельца(Док.Contragent);
// Предположим, у нас есть основной договор или мы берем первый попавшийся договор контрагента
СпрДоговоры.ВыбратьЭлементы();
Если СпрДоговоры.ПолучитьЭлемент() = 1 Тогда
// Открываем документ для редактирования в транзакции
Док.Договор = СпрДоговоры.ТекущийЭлемент();
Попытка
Док.Записать();
Док.Провести();
Сообщить("Документ " + Док.ТекущийДокумент() + " успешно исправлен и перепроведен.");
Исключение
Сообщить("Ошибка проведения документа " + Док.ТекущийДокумент() + ": " + ОписаниеОшибки());
КонецПопытки;
Иначе
Сообщить("У контрагента " + Док.Контрагент.Наименование + " не найдено ни одного договора! Пропустили.");
EndIf;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Таким образом, мы выяснили архитектурную причину расхождения данных в отчетах 1С 7.7 и научились диагностировать и исправлять подобные ошибки. Регулярно проводите технический аудит базы данных, следите за корректностью работы внешних обработок интеграции и своевременно восстанавливайте точку актуальности для поддержания порядка во взаиморасчетах!