Как реализовать поиск дублей счетов-фактур в 1С с помощью СКД?

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

При работе в учетных системах 1С часто возникает ситуация, когда один и тот же входящий документ (например, счет-фактура) регистрируется в базе несколько раз. Это приводит к завышению НДС к вычету и проблемам при сдаче отчетности. Обычный поиск по номеру не всегда эффективен, так как номера могут совпадать у разных поставщиков. Разберем подробно, как создать отчет на Системе компоновки данных (СКД), который будет находить дубли по сложному условию из семи полей.

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

Прежде чем приступать к написанию запроса, проанализируем ситуацию. В 1С тип Дата всегда содержит время (часы, минуты, секунды). Если мы просто сгруппируем документы по полю Дата, система может посчитать два документа, созданных в один день, разными, если они записаны в 10:00 и в 15:00. Для поиска дублей нам нужно сравнивать только «календарную» дату. Кроме того, нам необходимо учитывать дополнительные признаки, такие как исправления и корректировки, так как счета-фактуры с одинаковыми номерами могут быть вполне легитимными, если один из них является исправлением другого.

Рассмотрим 7 ключевых полей для поиска дублей, которые мы будем использовать в ключе уникальности:

  1. Поставщик (реквизит Контрагент)
  2. Дата (приведенная к началу дня)
  3. Номер (входящий номер документа)
  4. Исправление (булево поле, указывающее, является ли документ исправлением)
  5. ДатаИсправления (если есть)
  6. НомерИсправления (если есть)
  7. Корректировочный (булево поле, указывающее на вид документа)

Шаг 1. Создание структуры запроса с использованием временных таблиц

Для эффективного поиска дублей мы применим классическую схему из трех этапов. Посмотрим, как это реализовать в тексте запроса СКД.

Этап 1: Группировка и подсчет количества. Сначала мы выберем все документы, приведем их даты к началу дня и сгруппируем по всем семи полям. Функция СУММА(1) позволит нам понять, сколько раз встречается такая комбинация.


ВЫБРАТЬ
    СчетФактура.Контрагент КАК Контрагент,
    НАЧАЛОПЕРИОДА(СчетФактура.Дата, ДЕНЬ) КАК ДатаКраткая,
    СчетФактура.Номер КАК Номер,
    СчетФактура.Исправление КАК Исправление,
    НАЧАЛОПЕРИОДА(СчетФактура.ДатаИсправления, ДЕНЬ) КАК ДатаИсправленияКраткая,
    СчетФактура.НомерИсправления КАК НомерИсправления,
    СчетФактура.Корректировочный КАК Корректировочный,
    СУММА(1) КАК КоличествоДублей
ПОМЕСТИТЬ ВТ_Статистика
ИЗ
    Документ.СчетФактураПолученный КАК СчетФактура
ГДЕ
    СчетФактура.Проведен = ИСТИНА
    И СчетФактура.ПометкаУдаления = ЛОЖЬ
СГРУППИРОВАТЬ ПО
    СчетФактура.Контрагент,
    НАЧАЛОПЕРИОДА(СчетФактура.Дата, ДЕНЬ),
    СчетФактура.Номер,
    СчетФактура.Исправление,
    НАЧАЛОПЕРИОДА(СчетФактура.ДатаИсправления, ДЕНЬ),
    СчетФактура.НомерИсправления,
    СчетФактура.Корректировочный;

Этап 2: Отбор ключей дублей. Теперь из полученной временной таблицы ВТ_Статистика нам нужно выбрать только те записи, где КоличествоДублей больше единицы. Это и будут наши «проблемные» комбинации полей.


ВЫБРАТЬ
    ВТ_Статистика.Контрагент,
    ВТ_Статистика.ДатаКраткая,
    ВТ_Статистика.Номер,
    ВТ_Статистика.Исправление,
    ВТ_Статистика.ДатаИсправленияКраткая,
    ВТ_Статистика.НомерИсправления,
    ВТ_Статистика.Корректировочный
ПОМЕСТИТЬ ВТ_ТолькоДубли
ИЗ
    ВТ_Статистика КАК ВТ_Статистика
ГДЕ
    ВТ_Статистика.КоличествоДублей > 1;

Этап 3: Вывод детальных записей. На последнем этапе мы соединяем таблицу ВТ_ТолькоДубли обратно с основной таблицей документов Документ.СчетФактураПолученный. Это позволит нам вывести в отчет не просто «ключи», а конкретные ссылки на документы, чтобы пользователь мог их открыть и проверить.


ВЫБРАТЬ
    СчетФактура.Ссылка КАК Ссылка,
    СчетФактура.Контрагент КАК Контрагент,
    СчетФактура.Номер КАК Номер,
    СчетФактура.Дата КАК Дата,
    СчетФактура.Исправление КАК Исправление,
    СчетФактура.ДатаИсправления КАК ДатаИсправления,
    СчетФактура.НомерИсправления КАК НомерИсправления,
    СчетФактура.Корректировочный КАК Корректировочный
ИЗ
    ВТ_ТолькоДубли КАК ВТ_Дубли
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.СчетФактураПолученный КАК СчетФактура
    ПО ВТ_Дубли.Контрагент = СчетФактура.Контрагент
    И ВТ_Дубли.Номер = СчетФактура.Номер
    И ВТ_Дубли.ДатаКраткая = НАЧАЛОПЕРИОДА(СчетФактура.Дата, ДЕНЬ)
    И ВТ_Дубли.Исправление = СчетФактура.Исправление
    И ВТ_Дубли.ДатаИсправленияКраткая = НАЧАЛОПЕРИОДА(СчетФактура.ДатаИсправления, ДЕНЬ)
    И ВТ_Дубли.НомерИсправления = СчетФактура.НомерИсправления
    И ВТ_Дубли.Корректировочный = СчетФактура.Корректировочный
УПОРЯДОЧИТЬ ПО
    Контрагент,
    Номер,
    Дата;

Шаг 2. Оптимизация запроса с помощью условия ИМЕЮЩИЕ

Проанализируем ситуацию: можно ли сделать запрос лаконичнее? Да, используя конструкцию ИМЕЮЩИЕ (аналог HAVING в SQL). Это позволит нам объединить первые два этапа в один. Рассмотрим этот вариант, так как он более производителен при больших объемах данных.


ВЫБРАТЬ
    СчетФактура.Контрагент,
    НАЧАЛОПЕРИОДА(СчетФактура.Дата, ДЕНЬ) КАК ДатаДень,
    СчетФактура.Номер,
    СчетФактура.Исправление,
    СчетФактура.НомерИсправления,
    НАЧАЛОПЕРИОДА(СчетФактура.ДатаИсправления, ДЕНЬ) КАК ДатаИсправленияДень,
    СчетФактура.Корректировочный
ПОМЕСТИТЬ ВТ_КлючиДублей
ИЗ
    Документ.СчетФактураПолученный КАК СчетФактура
СГРУППИРОВАТЬ ПО
    СчетФактура.Контрагент,
    НАЧАЛОПЕРИОДА(СчетФактура.Дата, ДЕНЬ),
    СчетФактура.Номер,
    СчетФактура.Исправление,
    СчетФактура.НомерИсправления,
    НАЧАЛОПЕРИОДА(СчетФактура.ДатаИсправления, ДЕНЬ),
    СчетФактура.Корректировочный
ИМЕЮЩИЕ
    СУММА(1) > 1;

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

Шаг 3. Реализация поиска дублей средствами настроек СКД

Выясним, можно ли решить задачу, не переписывая сложный запрос, а используя возможности самого компоновщика данных. Это полезно, если вы хотите оставить запрос максимально простым. Рассмотрим алгоритм настройки:

  1. Набор данных: В запросе просто выбираем все необходимые поля документов без группировок.
  2. Ресурсы: Переходим на закладку «Ресурсы» и добавляем поле Ссылка. В выражении пишем Количество(Ссылка). Рассчитывать ресурс нужно по всем группировочным полям (Контрагент, Номер и т.д.).
  3. Настройки: На закладке «Настройки» создаем группировку, в которую включаем все наши 7 полей поиска.
  4. Отбор в группировке: Это самый важный момент. Нам нужно установить отбор не на весь отчет, а именно на эту группировку. Переходим в настройки этой группировки, закладка «Отбор» и добавляем условие: Количество(Ссылка) Больше 1.

Такой метод позволяет динамически менять поля поиска пользователем прямо в режиме «1С:Предприятие» без изменения конфигурации.

Важные нюансы работы со счетами-фактурами

Разберем специфические моменты, которые часто упускают при разработке подобных отчетов. Во-первых, при поиске входящих счетов-фактур (полученных) логичнее использовать реквизиты НомерВходящегоДокумента и ДатаВходящегоДокумента, если они предусмотрены в вашей конфигурации. Внутренний номер 1С может присваиваться автоматически и не совпадать с номером поставщика.

Во-вторых, обработка пустых дат исправлений. Если документ не является исправлением, поле ДатаИсправления будет содержать пустую дату (01.01.0001). В запросе 1С НАЧАЛОПЕРИОДА от пустой даты отработает корректно, но при сравнении это нужно учитывать, чтобы не «склеить» обычные документы с документами, где дата исправления просто не заполнена по ошибке.

В-третьих, производительность. Если в вашей базе данных сотни тысяч документов, обязательно добавьте индексирование во временную таблицу. В конце первого запроса (перед точкой с запятой) напишем: ИНДЕКСИРОВАТЬ ПО Контрагент, Номер. Это значительно ускорит операцию ВНУТРЕННЕЕ СОЕДИНЕНИЕ на третьем этапе.

Проанализировав ситуацию, мы видим, что задача поиска дублей — это не только написание кода, но и правильная подготовка данных (очистка от времени, учет специфики исправлений). Использование предложенных методов позволит вам создать надежный инструмент для контроля чистоты базы данных.

← На главную