Как получить последние документы и даты движений с отбором по корсчету в 1С

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

В процессе разработки отчетов на платформе 1С:Предприятие часто возникает задача: определить дату последней хозяйственной операции по конкретному договору или контрагенту, но с обязательным условием — операция должна проходить в корреспонденции с определенным счетом. Например, нас интересует последняя поставка от поставщика (Дт 20, 26, 44 — Кт 60). Рассмотрим, как правильно построить такой запрос, какие подводные камни существуют при работе с виртуальными таблицами регистра бухгалтерии и как оптимизировать результат.

Анализ проблемы: почему типовые обороты могут давать лишние данные

Часто разработчики начинают с использования виртуальной таблицы РегистрБухгалтерии.Хозрасчетный.Обороты. Однако при установке фильтра по параметру КорСчет можно столкнуться с тем, что в выборку попадают лишние данные. Проанализируем ситуацию: если мы просто указываем счет в параметрах, система может подхватить любые обороты, где искомый счет выступает и как основной, и как корреспондирующий в разных записях, если не задана жесткая связь дебета и кредита.

Разберем типичную ошибку в запросе:


ВЫБРАТЬ ПЕРВЫЕ 1
    ХозрасчетныйОбороты.Субконто2 КАК Договор,
    МАКСИМУМ(ХозрасчетныйОбороты.Регистратор.Дата) КАК ПоследняяДата,
    ХозрасчетныйОбороты.Субконто1 КАК Контрагент
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, Регистратор, Счет В (&СписокСчетов), , , КорСчет = ЗНАЧЕНИЕ(ПланСчетов.Хозрасчетный.ОсновноеПроизводство), ) КАК ХозрасчетныйОбороты
СГРУППИРОВАТЬ ПО
    ХозрасчетныйОбороты.Субконто2,
    ХозрасчетныйОбороты.Субконто1

В данном примере использование ВЫБРАТЬ ПЕРВЫЕ 1 без правильной сортировки и группировки по всем полям может вернуть случайную запись. Кроме того, фильтрация по корсчету в общей таблице оборотов иногда работает "шире", чем ожидает программист, особенно если счета имеют сложную иерархию или используются в разных типах проводок.

Решение 1: Использование виртуальной таблицы ОборотыДтКт

Для максимально точного отбора по корреспонденции (например, строго Дт 20.01 — Кт 60.01) наиболее эффективно использовать специализированную таблицу Хозрасчетный.ОборотыДтКт. В отличие от обычной таблицы оборотов, она содержит явные измерения СчетДт и СчетКт. Это исключает появление в отчете договоров, по которым не было именно такой связки счетов.

Рассмотрим пример запроса для поиска последней даты:


ВЫБРАТЬ
    ХозрасчетныйОборотыДтКт.СубконтоКт1 КАК Контрагент,
    ХозрасчетныйОборотыДтКт.СубконтоКт2 КАК Договор,
    МАКСИМУМ(ХозрасчетныйОборотыДтКт.Период) КАК ПоследняяДата
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОборотыДтКт(&Начало, &Конец, День, СчетДт = &Счет20, , СчетКт = &Счет60, , ) КАК ХозрасчетныйОборотыДтКт
СГРУППИРОВАТЬ ПО
    ХозрасчетныйОборотыДтКт.СубконтоКт1,
    ХозрасчетныйОборотыДтКт.СубконтоКт2

Важный момент: передавайте условия по счетам именно в параметры виртуальной таблицы, а не в секцию ГДЕ. Это позволит платформе оптимизировать SQL-запрос на уровне сервера базы данных, не выбирая лишние записи из физических таблиц для последующей фильтрации.

Решение 2: Соединение максимальных дат с остатками (Комплексный подход)

Если задача стоит шире — не просто найти дату, но и вывести текущий остаток по этим договорам, — лучше всего использовать метод временных таблиц. Выясним причину: прямое соединение больших виртуальных таблиц "в лоб" может привести к декартову произведению строк или крайне медленной работе. Посмотрим на алгоритм, который объединяет поиск последней активности и получение сальдо.

  1. Сначала создадим временную таблицу ТаблицаДвижений, где соберем максимальные даты по нужным нам корреспонденциям.
  2. Затем соединим эту таблицу с таблицей ОстаткиИОбороты для получения конечных сумм.

Рассмотрим реализацию на языке запросов 1С:


ВЫБРАТЬ
    МАКСИМУМ(ХозрасчетныйОбороты.Регистратор.Дата) КАК ПоследняяДата,
    ХозрасчетныйОбороты.Субконто2 КАК Договор,
    ХозрасчетныйОбороты.КорСчет КАК КорСчет
ПОМЕСТИТЬ ТаблицаДвижений
ИЗ
    РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, Регистратор, Счет В ИЕРАРХИИ (&СписокСчетов), , , , ) КАК ХозрасчетныйОбороты
ГДЕ
    ХозрасчетныйОбороты.КорСчет = &НужныйКорСчет
СГРУППИРОВАТЬ ПО
    ХозрасчетныйОбороты.Субконто2,
    ХозрасчетныйОбороты.КорСчет
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ХозрасчетныйОстаткиИОбороты.Субконто1 КАК Контрагент,
    ХозрасчетныйОстаткиИОбороты.Субконто2 КАК Договор,
    ТаблицаДвижений.ПоследняяДата КАК ПоследняяДата,
    ХозрасчетныйОстаткиИОбороты.СуммаКонечныйОстаток КАК СуммаКонечныйОстаток,
    ТаблицаДвижений.КорСчет КАК КорСчет
ИЗ
    РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&НачалоПериода, &КонецПериода, , , Счет В ИЕРАРХИИ (&СписокСчетов), , ) КАК ХозрасчетныйОстаткиИОбороты
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ТаблицаДвижений КАК ТаблицаДвижений
        ПО ХозрасчетныйОстаткиИОбороты.Субконто2 = ТаблицаДвижений.Договор
УПОРЯДОЧИТЬ ПО
    ПоследняяДата УБЫВ

Проанализируем этот код. Использование ВНУТРЕННЕЕ СОЕДИНЕНИЕ гарантирует, что в итоговый отчет попадут только те объекты, по которым были движения в выбранном периоде. Если же вам нужно видеть все договора с остатками, даже если по ним не было оборотов с указанным корсчетом, замените соединение на ЛЕВОЕ СОЕДИНЕНИЕ.

Как получить конкретный документ (Регистратор)

Если требуется получить не только дату, но и саму ссылку на документ Регистратор, обычная группировка по полю Регистратор не поможет, так как она разобьет строки и МАКСИМУМ(Дата) потеряет смысл. В 1С нет виртуальной таблицы "СрезПоследних" для бухгалтерии, поэтому мы применяем следующую технику:

  1. Находим максимальный период (или Момент Времени) для каждой аналитики.
  2. Соединяем результат с физической таблицей регистра или виртуальной таблицей оборотов по полям Период и Субконто.

Это позволит вытащить именно ту ссылку на документ, которая соответствует этой "последней" дате.

Оптимизация и важные рекомендации

При работе с регистром бухгалтерии следует учитывать специфику индексов. Рассмотрим основные правила:

Таким образом, комбинируя временные таблицы и правильный выбор между Обороты и ОборотыДтКт, можно добиться точного и быстрого получения данных о последних хозяйственных операциях в системе.

← На главную