Откройте рабочую таблицу продаж и найдите любого клиента, который давно с вами. Скорее всего, он встретится не один раз: «ООО Ромашка», «Ромашка ООО» и «Ромашка (Иванов)». Рядом колонка «Email», в которой у половины строк пусто. И вот вопрос: пусто, потому что адрес неизвестен, или потому что менеджер решил, что он не нужен? Таблица на этот вопрос не отвечает. CRM ответит ещё хуже: она спокойно сохранит пустоту и в том и в другом случае, а потом будет честно показывать её на карточке клиента.

Поэтому подготовка к переходу — это не техническая процедура с кнопкой «Импортировать» в конце. Это серия решений о смысле данных. Их принимают люди, а не программа. Ниже разберём, какие именно решения нужны, в каком порядке их удобно принимать и как провести пробный импорт так, чтобы его последствия были понятны заранее. В примерах используется EspoCRM, потому что её документация по импорту и восстановлению доступна, но логика подготовки применима и к другим системам.

Сначала разложить таблицу по сущностям

Таблица в Excel почти всегда устроена как «один лист — всё сразу». Одна строка может одновременно описывать компанию, человека в ней, сделку и последний звонок. Для человека, который читает строку глазами, это удобно. Для CRM это смесь нескольких разных объектов, у которых разные жизненные циклы.

Возьмём условный фрагмент исходного листа (данные вымышлены):

Фрагмент исходной таблицы
КлиентКонтактТелефонEmailСделкаКомментарий
ООО РомашкаИванов П.8 (912) 345-67-89ivanov@romashka.exampleПоставка, 120 000просил счёт до пятницы
Ромашка ОООПётр Иванов+7 912 345 67 89Допоставка, 40 000старый адрес не использовать
Ромашка (Иванов)89123456789ivanov@romashka.exampleзвонить после 15:00

Глазами видно, что это одна компания и один человек. Но в этих трёх строках на самом деле лежат три разных вида данных:

  • организация — одна, с тремя вариантами названия;
  • контакт — один человек, записанный по-разному, с одним номером в трёх форматах;
  • сделки — две реальные («Поставка» и «Допоставка») и одна строка, где сделки нет вовсе;
  • заметки — три комментария разного характера: просьба по счёту, предупреждение про адрес, удобное время для звонка.

Эту раскладку стоит выполнить на бумаге или в отдельном листе до любых правок. Для каждой колонки исходной таблицы запишите, к какой сущности она относится и в какое поле CRM пойдёт. Такая карта полей — самый полезный документ всей миграции. Колонка «Клиент» уйдёт в название организации, «Контакт» — в имя и фамилию контакта (а не в одну строку), «Сделка» придётся разбить на название и сумму, потому что «Поставка, 120 000» в одном поле не годится для сумм.

Колонки, которым места в карте не нашлось, — повод для разговора, а не для механического переноса. Документация EspoCRM указывает, что при импорте несопоставленные столбцы игнорируются (EspoCRM: Import). Это удобно, но и опасно: если важная колонка осталась без пары, система не сообщит о потере, она её просто пропустит. Поэтому каждую колонку нужно либо сопоставить, либо сознательно отнести к «не переносим».

Что считать «тем же самым клиентом»

Дубли — главная причина, по которой первые недели в новой CRM превращаются в разочарование. Менеджер ищет клиента, находит три карточки и не знает, в какой из них актуальная история. Хуже всего, когда дубль появляется на этапе импорта: он уже в системе, на него уже ссылаются сделки.

Чтобы объединять записи, нужен устойчивый признак совпадения. Устойчивый — значит, такой, который не меняется от того, кто и как заполнял строку. Название компании к ним не относится: оно записывается как угодно. Относительно надёжны:

  • email — если приведён к нижнему регистру и очищен от пробелов;
  • телефон — после приведения к единому формату;
  • ИНН для юридических лиц, если вы его собираете.

Но и у них есть слабые места. Общий email «info@» принадлежит всей компании, а не человеку. Один телефон может быть у двух коллег в небольшом офисе. Поэтому правило совпадения стоит писать как набор условий, а не одно поле. Например: «контакт считается тем же, если совпадает нормализованный телефон или email, и при этом название организации после упрощения похоже». Это авторское правило, а не истина CRM: вы вправе выбрать строже или мягче, но обязаны выбрать заранее и записать.

Нормализация телефонов на примере

Три записи из нашего фрагмента — «8 (912) 345-67-89», «+7 912 345 67 89» и «89123456789» — это один номер. Простое правило: оставить только цифры, заменить ведущую 8 на 7, добавить плюс. Результат у всех трёх одинаков.

8 (912) 345-67-89  →  +79123456789
+7 912 345 67 89  →  +79123456789
89123456789        →  +79123456789

Обратите внимание: правило работает для российских мобильных номеров. Городские номера с добавочными, международные номера и записи вроде «912-345-67-89, доб. 12» требуют отдельных решений. Добавочный лучше вынести в отдельный столбец или в заметку, иначе цифры сольются с номером.

Для обработки удобно взять скрипт, но стоит помнить, как он читает файл. Модуль csv в Python поддерживает разные диалекты — варианты разделителей и правил экранирования, а читающий reader обычно возвращает строки без автоматического преобразования типов (Python: csv). Для нас это полезное свойство: телефон остаётся строкой, и ведущие нули или плюс не превращаются в число, как это случается при открытии файла в табличном редакторе. А DictReader сопоставляет поля именам столбцов, поэтому код читается как «взять поле Телефон», а не «взять колонку номер четыре». Но разделитель нужно проверить: файл, сохранённый русской версией Excel, нередко использует точку с запятой, а не запятую.

Пустое поле — это не одно значение, а три

Вернёмся к пустой колонке из начала. В реальной таблице пустота обычно означает одно из трёх:

  1. не знаем — данные могут существовать, но их не собрали;
  2. не применимо — например, у физического лица нет ИНН организации;
  3. не нужно — менеджер решил, что поле неважно для этого клиента.

CRM различает их только тогда, когда вы ей это позволите. Часть различий выражается самой структурой: «не применимо» решается тем, что поле просто не показывается для данного типа клиента. «Не знаем» и «не нужно» стоит развести явно, например отдельным справочным значением или флагом. Иначе отчёт «клиенты без email» будет смешивать тех, кого нужно обзвонить для уточнения, и тех, кому письма не нужны принципиально.

Практичный приём: до импорта собрать вместе всех, кто заполнял таблицу, и за полчаса договориться о значениях для трёх-четырёх самых проблемных колонок. Не обо всех, иначе встреча затянется. Достаточно тех, по которым вы собираетесь строить фильтры и рассылки. Для статусов тоже нужен словарь: если в таблице встречаются «в работе», «в раб.», «работаем» и «ведём», импорт перенесёт их как четыре разных значения. Словарь соответствия сводит их к одному.

Пример словаря значений (условный)
Как записано в таблицеЗначение в CRM
в работе, в раб., работаем, ведёмВ работе
отказ, не интересно, ушёлЗакрыто без сделки
пустоРешает ответственный: уточнить или оставить без статуса

Комментарии: что превращается в поля, а что остаётся текстом

Колонка «Комментарий» — самый богатый и самый неудобный источник. В наших трёх строках лежат три принципиально разных сообщения. «Просил счёт до пятницы» — это задача со сроком, и спустя месяц она устарела. «Старый адрес не использовать» — это правило, которое должно сопровождать карточку клиента постоянно. «Звонить после 15:00» — предпочтение контакта, которое можно вынести в отдельное поле или оставить в заметке.

Разбирать тысячи комментариев вручную нереально, и не нужно. Разумный подход состоит из двух проходов. Сначала по ключевым словам выделить комментарии, которые явно содержат структурируемые данные: даты, суммы, слова «не звонить», «только email». Их разобрать вручную. Остальное перенести целиком в заметку к карточке, сохранив исходный текст дословно и дату, если она известна. Тогда информация не потеряна, а поиск по заметкам всё равно её найдёт.

Одно правило стоит запомнить: устаревшие срочные задачи («до пятницы») не нужно воскрешать как открытые задачи в новой системе. Иначе в первый же день у сотрудников окажется сотня просроченных дел, и доверие к системе будет подорвано ещё до первого рабочего звонка.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации Россия, США, Франция и Великобритания. Оплата картой РФ и по СБП.

АРЕНДОВАТЬ СЕРВЕР

Спорные дубли решает человек

Правила совпадения неизбежно делятся на три группы. Для первой совпадение очевидно: одинаковые нормализованные телефон и email, похожее название. Эти записи можно объединять автоматически, при условии что вы сохранили журнал, что с чем слито. Вторая группа — явные различия: ни телефона, ни email, ни организации не совпадает. Здесь вмешательство не требуется.

Третья группа — спорные случаи, и ради неё стоит завести отдельный лист «на разбор». Типичные примеры:

  • одинаковый телефон, но разные фамилии: это может быть коллега, а может быть опечатка;
  • одинаковая организация, но разные города: филиал или другая компания с похожим названием;
  • общий email отдела у нескольких разных людей;
  • тёзки в одной компании.

На такой лист нужно выделить время и назначить того, кто знает клиентов в лицо: чаще всего это руководитель продаж или менеджер, ведущий аккаунт. Программа не знает, что «Иванов П.» и «Пётр Иванов» — один человек, а «Иванов П.» из филиала — другой. Решение человека записывается рядом со строкой: «объединить», «оставить раздельно», «уточнить у клиента». Только после этого лист возвращается в общую обработку.

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

Пробный импорт: небольшая связанная группа

Когда карта полей готова, словари согласованы, а дубли разобраны, возникает соблазн загрузить всё. Лучше сопротивляться. Для первого импорта возьмите небольшую группу, но обязательно связанную: несколько организаций вместе с их контактами и сделками. Связность важна, потому что главные риски миграции живут именно в связях: контакт привязан не к той организации, сделка потеряла контакт, сумма попала не в то поле. Десять случайных строк этого не покажут, а пять компаний с полными цепочками покажут.

Подготовьте для каждой сущности отдельный CSV: организации, контакты, сделки. Порядок загрузки определяется зависимостями: сначала то, на что будут ссылаться. Документация EspoCRM описывает, что импорт принимает CSV и позволяет сопоставить столбцы файла с полями сущности (EspoCRM: Import). Для нашего фрагмента после нормализации файл контактов мог бы выглядеть так:

firstName;lastName;phone;email;account
Пётр;Иванов;+79123456789;ivanov@romashka.example;ООО Ромашка

Три исходные строки стали одной записью контакта: одно имя, одна фамилия, один телефон в единой форме, один email (заполненный из той строки, где он был) и одно каноническое название организации. В файле сделок останутся две строки — «Поставка» на 120 000 и «Допоставка» на 40 000, обе со ссылкой на ту же организацию. Третья исходная строка без сделки в файл сделок не попадёт совсем. Комментарии уйдут в заметки, а просьба «до пятницы» не станет задачей.

При импорте обратите внимание на два режима. Если вы только создаёте записи, система добавит новые. Если нужно обновить уже существующие, потребуется указать поля поиска, по которым CRM найдёт соответствующие записи (EspoCRM: Import). Здесь пригодится ваше правило совпадения: оно превращается в выбор поля для поиска. Если вы рассчитываете искать по телефону, он должен быть приведён к одному формату и в файле, и в самой CRM. Иначе поиск не найдёт то, что вы считали одним и тем же, и вместо обновления получится новая запись, то есть тот самый дубль.

Как читать результат пробы

После импорта не ограничивайтесь счётчиком «создано: 15». Откройте несколько карточек и пройдите по связям вручную. Проверьте по списку:

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

Особенно полезно показать результат сотрудникам, которые работают с этими клиентами. Человек, который вёл «Ромашку» три года, за минуту увидит, что связь не та, и подскажет, чего не хватает. Для программы такое различие невидимо.

Возврат: что отменяется, а что нет

Теперь самое важное различие, о которое спотыкаются чаще всего. В EspoCRM у выполненного импорта есть действие Revert. Оно удаляет записи, которые импорт создал. Но, как сказано в документации, оно не отменяет изменения, внесённые в уже существовавшие записи при обновлении (EspoCRM: Import).

Из этого следуют два практических вывода.

Первый. Если пробный импорт только создавал новые записи в пустой или тестовой области, Revert вполне подходит: он уберёт созданное, и можно исправить файл и повторить. Поэтому первую пробу разумно делать именно в режиме создания.

Второй. Если импорт обновлял существующие карточки, например дописывал телефоны или перезаписывал статусы, то старые значения Revert не вернёт. Перезаписанное поле останется перезаписанным. Единственная настоящая защита здесь — резервная копия, сделанная до импорта. В документации EspoCRM сказано, что полная копия включает файлы системы и дамп базы данных, а восстановление затрагивает файлы, права, базу и проверку расписания cron, причём инструкции отличаются для контейнерной и обычной установки (EspoCRM: Backup and restore). Это значит, что откат из копии — полноценная операция, а не щелчок. Её нужно хотя бы раз отрепетировать на отдельной площадке, прежде чем рассчитывать на неё в рабочий день.

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

Если вы хотите отрепетировать и импорт, и восстановление, не трогая рабочую систему, подойдёт отдельный VPS как тестовая площадка. У MAATRIX это виртуальные серверы на NVMe с процессорами AMD EPYC и root-доступом; для небольшой пробной CRM хватит и начального тарифа Ba (1 vCPU, 2 ГБ RAM, 40 ГБ NVMe), а при росте можно рассмотреть Uab или выше. Точные ресурсы нужно сверять с реальной нагрузкой: заявленные параметры не равны обещанию ёмкости. Серверы доступны в локациях UK, US, RU и FR, а оплата возможна картой РФ или через СБП (аренда VPS MAATRIX). Если дело дойдёт до перемещения самих файлов и хранилищ, полезен смежный материал о переносе данных на новый диск без простоя.

Порядок действий в одном взгляде

Если свести всё сказанное к последовательности, получится такая цепочка решений:

  1. Разложить колонки по сущностям и составить карту полей; пометить колонки, которые не переносятся.
  2. Выбрать признаки совпадения и записать правило объединения.
  3. Нормализовать телефоны, адреса, статусы; согласовать словарь значений и смысл пустоты.
  4. Разобрать комментарии на структурируемое и заметки.
  5. Передать спорные дубли человеку, который знает клиентов.
  6. Подготовить отдельные CSV по сущностям и проверить разделитель и кодировку.
  7. Импортировать небольшую связанную группу в режиме создания и проверить связи по карточкам.
  8. Перед любым обновлением существующих записей сделать резервную копию и выгрузку затронутых данных.

Пять компаний, которых все узнают

Заканчивать подготовку стоит не импортом всей базы, а маленьким результатом, который можно показать. Представьте группу из пяти клиентов. У каждого одна организация, один-два контакта с единообразными телефонами, сделки с понятными суммами и статусами, а комментарии аккуратно лежат в заметках. «Ромашка» из начала статьи теперь одна: одна карточка, один Пётр Иванов, две сделки в истории.

Покажите эту группу менеджерам. Если они открывают карточку и сразу узнают своего клиента — по составу контактов, по сделкам, по тому, что про него известно, — значит, правила данных работают. Если кто-то морщится и говорит «а где у него второй директор?», у вас есть конкретная правка в карту полей, а не абстрактное недовольство. После этого остальную базу можно загружать порциями, каждый раз с теми же проверками. Чистая маленькая группа, в которой люди узнают свои связи, — лучшее доказательство того, что перенос идёт правильно.