Почему в 1С растут дубли контрагентов и как это лечится
Дубли контрагентов в 1С почти никогда не появляются из-за «глюка обмена». У них есть конкретная причина, и она обычно одна и та же.
Почему вообще появляются дубли
Обмен ищет, есть ли уже такой контрагент. Вопрос в том, по какому признаку он ищет. Если по названию, то любое расхождение в строке создаёт новую запись: лишний пробел, кавычки другого вида, «ООО» в начале вместо конца, сокращение вместо полного наименования.
Дальше это множится само: менеджер видит два одинаковых контрагента, выбирает наугад, документы расходятся по разным карточкам, отчёты перестают сходиться.
Проверка занимает минуту: отсортируйте контрагентов по названию и посмотрите соседние строки. Если видите пары, отличающиеся пробелом или регистром, — сопоставление идёт по тексту.
Как понять, по какому полю идёт сопоставление
Смотреть надо не в описание обмена, а в данные. У записей, созданных обменом, проверьте, заполнен ли идентификатор из внешней системы — GUID, XML_ID или служебное поле. Если у половины записей он пустой, обмен их не по нему искал.
- Заполнен у всех записей — сопоставление по идентификатору, причина дублей в другом
- Заполнен частично — часть записей заведена руками или другим обменом
- Пустой почти везде — сопоставление идёт по названию, это и есть источник дублей
// Сопоставление по идентификатору вместо названия.
// Ключ — GUID из 1С: он не меняется при переименовании контрагента,
// а название меняется регулярно. Отсюда и берутся дубли.
function findCompany(string $guid): ?int
{
$res = CCrmCompany::GetListEx(
[],
['=UF_GUID_1C' => $guid, 'CHECK_PERMISSIONS' => 'N'],
false,
['nTopCount' => 1],
['ID'],
);
$row = $res->Fetch();
return $row ? (int) $row['ID'] : null;
}Что делать, если сопоставление по названию
Переводить на идентификатор. GUID в 1С не меняется при переименовании контрагента, а название меняется регулярно — этим они и отличаются.
- Проставить идентификатор существующим записям — по совпадению названий, вручную разобрав спорные
- Перевести обмен на поиск по идентификатору
- Свести уже накопленные дубли, объединив документы
- Добавить в обмен проверку: если запись найдена по названию, но идентификатор не совпал — не создавать новую, а писать в лог
Последний пункт важнее, чем кажется: он превращает молчаливое размножение записей в заметную ошибку, которую видно сразу, а не через полгода.
// Обновляем только то, что реально изменилось.
// Хэш всего набора полей дешевле, чем сравнение поля за полем,
// и переживает добавление новых полей без правки кода.
$hash = md5(json_encode($fields, JSON_UNESCAPED_UNICODE));
if ($existing !== null && $existing['UF_HASH_1C'] === $hash) {
return $existing['ID']; // ничего не поменялось — не трогаем запись
}
$fields['UF_HASH_1C'] = $hash;Чем это оборачивается на объёме
В одном из разборов мы вычистили 20 174 мусорные компании, оставшиеся от старого типового обмена. После перехода на сопоставление по GUID дубли по названию сократились до четырёх пар — их разобрали руками.
| Признак сопоставления | Что происходит при переименовании | Риск дублей |
|---|---|---|
| Название | Создаётся новая запись | Высокий |
| ИНН | Запись находится, но филиалы и ИП с одним ИНН слипаются | Средний |
| GUID из 1С | Запись находится, данные обновляются | Низкий |
Если дубли уже накопились
Разовая чистка без исправления причины даёт отсрочку на месяц-другой. Разбираем причину, чиним сопоставление и только потом сводим накопленное.