В практике ведения учета часто возникают ситуации, когда одна первичная продажа (реализация) корректируется несколькими документами. Это может быть связано с частичными возвратами на разные склады или поэтапным уточнением стоимости товаров. Для целей контроля корректности учета и формирования отчетности по НДС нам может потребоваться список тех самых "первичных" реализаций, к которым привязано более одной корректировочной счет-фактуры (КСФ). Разберем, как решить эту задачу максимально эффективно и элегантно с помощью языка запросов 1С.
Прежде чем приступать к написанию кода, проанализируем типовую цепочку документов в системе. В большинстве конфигураций (таких как ERP, КА или УТ) связь между корректировкой и реализацией не всегда прямая. Рассмотрим стандартный путь:
Таким образом, наша задача сводится к тому, чтобы "пройтись" вверх по дереву ссылок от КСФ до РТУ и сгруппировать данные по найденному исходному документу.
Наиболее правильным подходом будет использование конструкции ВЫБОР для определения типа документа-основания и последующая фильтрация через секцию ИМЕЮЩИЕ. Разберем по шагам, как построить такой запрос.
Для начала выберем все ссылки на КСФ и определим для каждой из них "корневую" реализацию. Поскольку поле ДокументОснование имеет составной тип, нам нужно проверить, на какой глубине находится искомая РеализацияТоваровУслуг.
ВЫБРАТЬ
КСФ.Ссылка КАК Корректировка,
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(КСФ.ДокументОснование.ДокументОснование) = ТИП(Документ.РеализацияТоваровУслуг)
ТОГДА КСФ.ДокументОснование.ДокументОснование
КОГДА ТИПЗНАЧЕНИЯ(КСФ.ДокументОснование.ДокументОснование.ДокументОснование) = ТИП(Документ.РеализацияТоваровУслуг)
ТОГДА КСФ.ДокументОснование.ДокументОснование.ДокументОснование
ИНАЧЕ КСФ.ДокументОснование // Если цепочка короткая или иная
КОНЕЦ КАК Реализация
ПОМЕСТИТЬ ВТ_СвязиКСФ
ИЗ
Документ.КорректировочныйСчетФактура КАК КСФ
ГДЕ
КСФ.Проведен = ИСТИНА
;
Обратите внимание, что прямое обращение через "точку" к полям составного типа (КСФ.ДокументОснование.ДокументОснование) заставляет СУБД выполнять множество левых соединений со всеми таблицами, входящими в этот тип. Рассмотрим ниже, как оптимизировать этот момент.
После того как мы получили временную таблицу с парами "КСФ — Реализация", нам остается только сгруппировать данные по реализации и оставить те группы, где количество различных КСФ больше единицы. Для этого воспользуемся предложением ИМЕЮЩИЕ.
ВЫБРАТЬ
ВТ.Реализация КАК ДокументОснование,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ.Корректировка) КАК КоличествоКСФ
ИЗ
ВТ_СвязиКСФ КАК ВТ
ГДЕ
ВТ.Реализация ССЫЛКА Документ.РеализацияТоваровУслуг
СГРУППИРОВАТЬ ПО
ВТ.Реализация
ИМЕЮЩИЕ
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ВТ.Корректировка) > 1
Этот запрос вернет список только тех реализаций, по которым в системе зарегистрировано более одного корректировочного документа. Это и есть решение нашей задачи в базовом варианте.
Проанализируем ситуацию с точки зрения быстродействия. Если база данных содержит сотни тысяч документов, обращение через несколько точек к составным полям приведет к существенному замедлению. Чтобы помочь планировщику SQL, крайне рекомендуется использовать конструкцию ВЫРАЗИТЬ. Это позволит системе обращаться только к конкретной таблице документа.
Перепишем определение реализации более профессионально:
ВЫБРАТЬ
КСФ.Ссылка КАК Корректировка,
ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(КСФ.ДокументОснование) = ТИП(Документ.ВозвратТоваровОтПокупателя)
ТОГДА ВЫБОР
КОГДА ТИПЗНАЧЕНИЯ(ВЫРАЗИТЬ(КСФ.ДокументОснование КАК Документ.ВозвратТоваровОтПокупателя).ДокументОснование) = ТИП(Документ.РеализацияТоваровУслуг)
ТОГДА ВЫРАЗИТЬ(КСФ.ДокументОснование КАК Документ.ВозвратТоваровОтПокупателя).ДокументОснование
ИНАЧЕ ВЫРАЗИТЬ(ВЫРАЗИТЬ(КСФ.ДокументОснование КАК Документ.ВозвратТоваровОтПокупателя).ДокументОснование КАК Документ.Претензия).ДокументОснование
КОНЕЦ
ИНАЧЕ Неопределено
КОНЕЦ КАК Реализация
ИЗ
Документ.КорректировочныйСчетФактура КАК КСФ
Важный момент: В современных конфигурациях 1С (ERP 2.5, УТ 11.5) связи документов часто хранятся в специальном регистре сведений СведенияОДокументахОснованиях. Использование этого регистра может быть гораздо эффективнее, чем ручной перебор цепочек вложенности, так как он содержит "плоскую" структуру связей.
Если вам необходимо решать эту задачу программно (в коде модуля), а не в сложном отчете, можно рассмотреть использование Критериев отбора. В типовых конфигурациях обычно существует критерий СвязанныеДокументы.
Проанализируем алгоритм:
КритерииОтбора.СвязанныеДокументы.Найти(РеализацияСсылка) получаем массив подчиненных документов.ДокументСсылка.КорректировочныйСчетФактура.Однако помните, что метод с критериями отбора в цикле будет работать значительно медленнее, чем один хорошо оптимизированный запрос, поэтому для построения списков и отчетов всегда отдавайте предпочтение запросам с группировкой и условием ИМЕЮЩИЕ.
Мы выяснили, что для поиска множественных КСФ по одной реализации необходимо:
ВЫРАЗИТЬ для полей составного типа для ускорения работы.СГРУППИРОВАТЬ ПО и ИМЕЮЩИЕ КОЛИЧЕСТВО(...) > 1.Такой подход гарантирует получение точных данных даже при сложной структуре документооборота, когда возвраты осуществляются на разные склады через промежуточные акты претензий.