Настройка объединения дубликатов в CRM Битрикс24
Найти дубли — половина работы. Вторая половина — объединить их так, чтобы не потерять историю звонков, сделки, задачи и кастомные поля. Именно здесь большинство компаний сталкиваются с реальными проблемами: после слияния исчезают активности, неверно выбирается «главная» карточка, связанные сделки перевешиваются не туда.
Механизм объединения в Битрикс24 работает через класс CCrmEntityMerger — он последовательно переносит связанные объекты, затем удаляет поглощённые записи. Важно понимать порядок операций, чтобы не получить битые связи.
Ручное объединение через интерфейс
Базовый сценарий: CRM → Контакты → Найти дубликаты → выбрать группу → Объединить. Система показывает карточки бок о бок и предлагает выбрать, какое значение каждого поля оставить в итоговой записи.
Подводные камни ручного режима:
- При объединении компаний связанные контакты автоматически переносятся к «главной» — проверьте, что выбрали правильную.
- Файлы из поглощаемых карточек переносятся, но их исходный путь в
b_disk_objectменяется — если есть внешние ссылки на файлы, они сломаются. - Пользовательские поля типа «список» объединяются только если включена опция «множественный выбор»; одиночные значения берутся из главной записи, остальные теряются.
Настройка правил слияния
В разделе CRM → Настройки → Дубликаты → Правила объединения задаётся логика выбора значений при конфликте полей:
| Правило | Поведение |
|---|---|
| Главная запись | Берётся значение из выбранной «главной» карточки |
| Более заполненная | Берётся непустое значение; при конфликте — из главной |
| Объединение | Применимо для множественных полей (телефоны, email) |
| Последняя по дате | Берётся значение из записи с более поздней датой изменения |
Для большинства задач оптимально: ключевые идентификаторы (ИНН, телефон, email) — «объединение»; статусные поля (ответственный, стадия) — «главная запись»; текстовые примечания — «более заполненная».
Программное объединение через API
При массовой чистке базы ручной режим не подходит. REST-метод для слияния контактов:
// Объединение: запись 1001 поглощает 1002 и 1003
$response = CRest::call('crm.contact.merge', [
'id' => 1001,
'victims' => [1002, 1003],
'fields' => [
'PHONE' => 'merge', // объединить телефоны
'EMAIL' => 'merge', // объединить email
'ASSIGNED_BY_ID' => 'primary', // ответственный из главной
],
]);
Для компаний — аналогично crm.company.merge. Метод синхронный, при объединении >5 поглощаемых записей может таймаутить — разбивайте на пары.
Внутри Битрикса на уровне PHP (коробочная версия):
$merger = new CCrmEntityMerger(CCrmOwnerType::Contact);
$merger->Merge(
1001, // ID главной записи
[1002, 1003], // жертвы
$fields, // правила полей
$errorMessage
);
Перенос связанных объектов
Это критическая часть, которую легко упустить. При слиянии автоматически переносятся:
- Сделки (поле
CONTACT_IDобновляется) - Активности: звонки, письма, встречи из таблицы
b_crm_activity - Задачи через связь
b_tasks_member - Временная шкала (
b_crm_timeline)
Не переносятся автоматически:
- Связи через пользовательские блоки смарт-процессов (SPAs) — нужен отдельный скрипт обновления
- Внешние связи из сторонних интеграций (данные в кастомных таблицах)
- Чаты в Открытых линиях — история привязана к линии, не к контакту
Для смарт-процессов обновление связей нужно делать вручную через crm.item.update с новым contactId.
Откат объединения
Встроенного отката нет. После слияния поглощённые записи помечаются удалёнными (флаг DELETED=Y в b_crm_contact), но физически остаются в БД несколько дней до очистки корзины.
Временное окно для восстановления: CRM → Настройки → Корзина — поглощённые карточки попадают туда и доступны для восстановления в течение 30 дней (настраивается). После восстановления связи с главной записью не восстанавливаются автоматически — их придётся переназначить вручную.
Перед запуском массового слияния всегда делайте резервную копию таблиц b_crm_contact, b_crm_company, b_crm_deal и таблиц активностей.







