При ведении бухгалтерского учета часто возникает необходимость гибко управлять зачетом авансов. Стандартный механизм «первый пришел — первый закрылся» (ФИФО) не всегда удовлетворяет требованиям бизнеса. Например, если у покупателя имеется задолженность по судебным претензиям или исполнительным листам, то поступающий аванс в первую очередь должен гасить именно этот критический долг, и только потом — стандартную задолженность по отгрузкам.
В конфигурациях на платформе «1С:Предприятие 7.7» для таких целей часто используется вспомогательный справочник соответствия счетов. Однако записи в нем могут вноситься хаотично. Проанализируем, как настроить автоматический зачет авансов по приоритетам без жесткой привязки к конкретным счетам в коде, и разберемся, почему в форме списка справочника могут быть заблокированы кнопки интерактивной сортировки.
Для понимания логики бухгалтеров обратимся к плану счетов. Например, в ряде стран СНГ (в частности, по стандартам НСБУ Республики Узбекистан) используются следующие счета:
Задача состоит в том, чтобы при получении аванса на счет 63.10 программа автоматически проверяла наличие долгов на счетах 48.60 и 40.10, но закрывала их строго по приоритету: сначала претензии (высший приоритет), затем обычный долг.
Рассмотрим по шагам, как реализовать этот механизм элегантно и сделать его управляемым для пользователей.
---
Чтобы избежать «хардкода» (жесткого прописывания номеров счетов в программном коде), дадим бухгалтерам возможность самостоятельно определять приоритеты. Для этого добавим в справочник соответствия счетов новый реквизит:
СоответствиеСчетов (или аналогичный, используемый в вашей конфигурации).ПриоритетВ режиме «Предприятие» бухгалтеры смогут заполнить этот реквизит числовыми значениями: например, для связки счетов 63.10 - 48.60 установить приоритет 1, а для 63.10 - 40.10 — приоритет 2. Чем меньше число, тем выше приоритет зачета.
---
Прямая выборка элементов справочника через стандартный метод ВыбратьЭлементы() считывает данные в порядке их физического нахождения в базе данных или по коду, игнорируя наш приоритет. Чтобы обойти это ограничение платформы 1С 7.7, применим механизм выгрузки данных во временную Таблицу Значений (ТЗ) с последующей сортировкой.
Рассмотрим пример программного кода, который необходимо вставить в модуль проведения документа зачета авансов или в соответствующую процедуру обработки:
// 1. Создаем объект "Таблица Значений" для сортировки правил зачета
ТЗ_Правила = СоздатьОбъект("ТаблицаЗначений");
ТЗ_Правила.НоваяКолонка("СчетАванса", "Счет");
ТЗ_Правила.НоваяКолонка("СчетДолга", "Счет");
ТЗ_Правила.НоваяКолонка("Приоритет", "Число");
// 2. Выбираем настройки из справочника соответствия счетов
СпрСоответствие = СоздатьОбъект("Справочник.СоответствиеСчетов");
СпрСоответствие.ВыбратьЭлементы();
Пока СпрСоответствие.ПолучитьЭлемент() = 1 Цикл
// Пропускаем элементы, помеченные на удаление
Если СпрСоответствие.ПометкаУдаления() = 1 Тогда
Продолжить;
КонецЕсли;
// Заполняем строку таблицы значений
ТЗ_Правила.НоваяСтрока();
ТЗ_Правила.СчетАванса = СпрСоответствие.СчетАванса;
ТЗ_Правила.СчетДолга = СпрСоответствие.СчетДолга;
// Если приоритет не заполнен, присваиваем ему заведомо большое число
Если СпрСоответствие.Приоритет = 0 Тогда
ТЗ_Правила.Приоритет = 999;
Иначе
ТЗ_Правила.Приоритет = СпрСоответствие.Приоритет;
КонецЕсли;
КонецЦикла;
// 3. Сортируем таблицу по возрастанию приоритета
// Знак "+" указывает платформе на прямую сортировку (от меньшего к большему)
ТЗ_Правила.Сортировать("Приоритет+");
Теперь в нашей таблице значений ТЗ_Правила верхние строчки гарантированно будут содержать наиболее приоритетные счета (с приоритетом 1, 2 и т.д.). Далее мы можем запустить цикл распределения суммы аванса по этим счетам:
// Предположим, у нас есть общая сумма аванса, которую нужно распределить
ОстатокАванса = СуммаАвансаДляЗачета;
ТЗ_Правила.ВыбратьСтроки();
Пока (ТЗ_Правила.ПолучитьСтроку() = 1) И (ОстатокАванса > 0) Цикл
ТекущийСчетДолга = ТЗ_Правила.СчетДолга;
ТекущийСчетАванса = ТЗ_Правила.СчетАванса;
// Получаем фактический остаток задолженности контрагента по текущему счету
// Используем объект БухгалтерскиеИтоги (предварительно рассчитанный)
СуммаДолга = БухИтоги.СКД(ТекущийСчетДолга, "С",,, ВыбКонтрагент, ВыбДоговор);
Если СуммаДолга > 0 Тогда
// Определяем сумму, которую можем закрыть в рамках данного шага приоритета
СуммаСписания = Мин(ОстатокАванса, СуммаДолга);
// Формируем проводку зачета аванса
Операция.НоваяПроводка();
Операция.Дебет.Счет = ТекущийСчетАванса;
Операция.Дебет.Субконто(1, ВыбКонтрагент);
Операция.Дебет.Субконто(2, ВыбДоговор);
Операция.Кредит.Счет = ТекущийСчетДолга;
Операция.Кредит.Субконто(1, ВыбКонтрагент);
Операция.Кредит.Субконто(2, ВыбДоговор);
Операция.Сумма = СуммаСписания;
// Уменьшаем остаток нераспределенного аванса
ОстатокАванса = ОстатокАванса - СуммаСписания;
КонецЕсли;
КонецЦикла;
Использование этого алгоритма позволяет системе динамически подстраиваться под любые изменения законодательства или внутренней политики компании. Бухгалтеру достаточно изменить цифру в справочнике, и программа тут же перестроит логику проведения документов.
---
Часто при тестировании решения пользователи жалуются, что они не могут визуально отсортировать справочник по новой колонке Приоритет — кнопки сортировки (синие стрелочки вверх и вниз на панели инструментов) остаются серыми и неактивными. Выясним основные причины такого поведения платформы 1С 7.7.
В отличие от более современных версий 1С, платформа 7.7 не умеет «на лету» сортировать списки по произвольным полям. Сортировка возможна только по тем реквизитам, для которых в Конфигураторе явно созданы поисковые индексы.
Решение:
Приоритет нашего справочника.После выполнения этих действий кнопка сортировки по колонке «Приоритет» в режиме «Предприятие» станет активной.
Платформа 1С 7.7 накладывает жесткое ограничение на типы данных реквизитов, по которым возможна сортировка. Сортировать интерактивно можно только реквизиты простых типов: Число, Строка или Дата.
Если в вашем справочнике есть реквизиты с типом Счет или Справочник.Субконто, вы не сможете включить для них свойство «Сортировка» в Конфигураторе — эта опция будет заблокирована. Если вам критически важно визуально сортировать список по счетам, создайте дублирующий текстовый реквизит (например, СчетКодТекст), программно записывайте туда текстовое представление счета (например, "48.60") при сохранении элемента и включайте индексацию именно для этого текстового поля.
УстановитьОтбор)Если при открытии формы списка справочника в коде модуля формы вызывается метод УстановитьОтбор(), платформа 1С 7.7 автоматически отключает возможность интерактивной сортировки по всем колонкам, кроме той, по которой в данный момент установлен отбор.
Решение: Проанализируйте предопределенную процедуру ПриОткрытии() в модуле формы списка. Если там присутствует код вида УстановитьОтбор("ИмяРеквизита", ...), то для восстановления возможности сортировки пользователям придется сначала программно или интерентивно отключать текущий отбор.