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