Многие пользователи и разработчики при работе в программе «1С:Бухгалтерия предприятия 3.0» (БП 3.0) сталкиваются с неприятной ситуацией: оплата по счету фактически поступила, в базе зарегистрированы все платежные поручения или кассовые ордера, но в списке документов «Счета покупателям» статус по-прежнему отображается как «Не оплачен». Статус обновляется только в том случае, если открыть документ вручную и заново его перепровести. При этом стандартное групповое перепроведение документов за период не приносит никакого результата.
В этой статье мы подробно разберем внутреннюю архитектуру учета статусов оплаты в 1С, выясним технические причины возникновения этой проблемы и рассмотрим практические способы ее решения как для обычных пользователей, так и для программистов.
Для начала проанализируем, как именно платформа хранит информацию об оплатах. В старых версиях конфигураций статус оплаты мог храниться непосредственно в реквизите самого документа «Счет на оплату покупателю». Однако в современных редакциях БП 3.0 разработчики фирмы «1С» полностью отказались от этой схемы в пользу более гибкой, но сложной двухзвенной архитектуры.
Сегодня за контроль и отображение оплаты отвечают два абсолютно разных регистра:
ОплатаСчетов. Это классический остаточный (или приходно-расходный) регистр. Движения по нему делают исключительно документы-регистраторы: «Поступление на расчетный счет», «Приходный кассовый ордер», «Операция Бух», а также сам «Счет на оплату» при выставлении. В этом регистре хранятся точные числовые данные о суммах взаиморасчетов в разрезе договоров, контрагентов и счетов.СтатусыДокументов. Это независимый (не подчиненный регистратору) регистр сведений. Именно из него система считывает текущее текстовое или визуальное состояние документа («Оплачен», «Не оплачен», «Частично оплачен») при открытии формы списка или формы самого счета. В форме документа при инициализации на сервере (процедура ПриСозданииНаСервере) значение статуса считывается именно из этой таблицы БД.Как они взаимодействуют в штатном режиме:
Когда вы проводите платежный документ (например, поступление на расчетный счет), система делает две вещи:
ОплатаСчетов, уменьшая сумму долга по счету.СтатусыДокументов, присваивая ему актуальный статус.Выясним причину, почему при массовом перепроведении документов статусы часто остаются «зависшими» в неактуальном состоянии.
Поскольку регистр сведений СтатусыДокументов является независимым, записи в нем не привязаны жестко к транзакции проведения конкретного платежного документа на уровне платформы. При выполнении стандартного группового перепроведения (особенно через специализированные обработки или при загрузке данных через механизмы синхронизации) система часто использует оптимизированные режимы записи данных:
ОбменДанными.Загрузка = Истина, который отключает выполнение прикладных обработчиков событий и подписок.В результате получается рассинхронизация: регистр накопления ОплатаСчетов успешно обновляет свои остатки, а записи в независимом регистре СтатусыДокументов остаются старыми. Так как документ счета физически не перепроводился, его статус в регистре сведений не актуализировался.
Рассмотрим несколько эффективных способов решения проблемы рассинхронизации данных.
Самый простой интерактивный метод, не требующий программирования:
Ctrl + A для выделения всех или удерживая Shift/Ctrl для выборочного выделения).СтатусыДокументов для всех выбранных объектов.Если документов слишком много или требуется автоматизировать процесс после выполнения обменов, можно написать внешнюю обработку. Проанализируем пример кода, который считывает реальные остатки по регистру накопления и принудительно актуализирует записи в независимом регистре сведений:
Процедура АктуализироватьСтатусыСчетовНаСервере() Экспорт
// Выбираем все счета, у которых есть расхождения между оплатой и статусом
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| СчетНаОплату.Ссылка КАК Ссылка,
| ЕСТЬNULL(ОплатаОстатки.СуммаОстаток, 0) КАК ОстатокОплаты,
| ЕСТЬNULL(Статусы.Статус, ЗНАЧЕНИЕ(Перечисление.СтатусыОплатыСчетов.НеОплачен)) КАК ТекущийСтатус
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК СчетНаОплату
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОплатаСчетов.Остатки КАК ОплатаОстатки
| ПО ОплатаОстатки.СчетОплаты = СчетНаОплату.Ссылка
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СтатусыДокументов КАК Статусы
| ПО Статусы.Документ = СчетНаОплату.Ссылка
|ГДЕ
| СчетНаОплату.Проведен = ИСТИНА";
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Определяем, какой статус должен быть фактически
Если Выборка.ОстатокОплаты <= 0 Тогда
ПравильныйСтатус = ПредопределенноеЗначение("Перечисление.СтатусыОплатыСчетов.Оплачен");
ИначеЕсли Выборка.ОстатокОплаты < Выборка.Ссылка.СуммаДокумента Тогда
ПравильныйСтатус = ...; // Логика для частично оплаченного
Иначе
ПравильныйСтатус = ПредопределенноеЗначение("Перечисление.СтатусыОплатыСчетов.НеОплачен");
КонецЕсли;
// Если статус в регистре сведений не совпадает с расчетным - перезаписываем его
Если Выборка.ТекущийСтатус <> ПравильныйСтатус Тогда
Набор = РегистрыСведений.СтатусыДокументов.СоздатьНаборЗаписей();
Набор.Отбор.Документ.Установить(Выборка.Ссылка);
НоваяЗапись = Набор.Добавить();
НоваяЗапись.Документ = Выборка.Ссылка;
НоваяЗапись.Статус = ПравильныйСтатус;
Набор.Записать(Истина);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Еще один частый вопрос: почему в одной информационной базе статус «Не оплачен» подсвечивается ярким красным цветом, а в другой (например, после переноса или загрузки данных) — нейтральным серым?
Разберем этот механизм:
Где программа берет дату планируемой оплаты:
СрокиОплатыПокупателями (где задается дефолтное количество дней на оплату счетов).Если после переноса данных все статусы стали серыми, вам необходимо проверить заполнение реквизита ОплатаДо в документах или настроить сроки оплаты в параметрах новой информационной базы.
Для детального анализа ситуации пользователю часто требуется заглянуть напрямую в регистры сведений и накопления. Но как быть, если база находится в облаке (например, в сервисе «1С:Предприятие через интернет» / 1С:Фреш), где меню «Все функции» («Функции для технического специалиста») заблокировано?
Рассмотрим два способа обхода этого ограничения:
Если интерфейс облака урезан правами доступа, но у вас есть базовые административные полномочия, вы можете открыть любой регистр напрямую по его внутреннему адресу (URL):
Shift + F11 (или откройте меню «Сервис и настройки» — «Перейти по ссылке»).e1cib/list/РегистрСведений.СтатусыДокументовe1cib/list/РегистрНакопления.ОплатаСчетовИспользуя этот лайфхак, вы сможете мгновенно анализировать реальное состояние записей в базах данных облачного сервиса и вовремя диагностировать расхождения в учете.