Перейти к основному содержимому

ИНН, КПП, ОГРН и ОКТМО в выгрузках

Зачем и для кого

Инструкция для аналитиков и разработчиков, которым нужно стабильно сшивать открытые таблицы по организациям и территориям: закупки, субсидии, участники бюджетного процесса, отчётность. Определения терминов — в глоссарии (ИНН, КПП, ОГРН, ОКТМО); здесь — длины, нормализация ключей и типовые ошибки при JOIN.

Входные данные

Инструменты

  • Python 3 с pandas или чистой строковой обработкой; SQL или Excel — те же правила нормализации.
  • Браузер — ручная проверка карточки на egrul.nalog.ru или в ЕГРЮЛ при спорных случаях.

Шаги

  1. Приведите ИНН к строке из цифр без пробелов; не приводите к числу в Excel/CSV — иначе потеряете ведущие нули у коротких значений в старых файлах.
  2. Определите длину: 10 знаков — как правило юридическое лицо; 12ИП или иной учёт физлица как налогоплательщика (ИНН). Не джойньте 12-значный ИНН к таблице только юрлиц «как есть» без модели учёта.
  3. КПП9 цифр у организаций; храните как строку. Если в одном источнике есть КПП, а в другом нет, не расширяйте ключ до ИНН+КПП без явного допущения (КПП).
  4. ОГРН13 цифр для юрлица, 15 для ИП (ОГРН); используйте как дополнительный или альтернативный ключ к справочникам ЕГРЮЛ, если ИНН в одном наборе отсутствует или сомнителен.
  5. ОКТМО — нормализуйте до кода без пробелов; иерархия и смысл разрядов — в глоссарии; для бюджетных склеек проверьте, код территории заказчика это или территория бюджета в колонке.
  6. Проверьте дубликаты в справочнике на выбранный ключ до merge — иначе размножите строки факта.

Воспроизводимый пример

Нормализация ИНН, КПП и ОГРН и сборка составного ключа (без проверки контрольных цифр ФНС — при необходимости подключайте официальные алгоритмы отдельно):

import re


def digits_only(s: str | None) -> str | None:
if s is None:
return None
d = re.sub(r"\D", "", str(s).strip())
return d if d else None


def normalize_inn(inn: str | None) -> str | None:
d = digits_only(inn)
if d is None:
return None
if len(d) not in (10, 12):
return d # вернуть как есть для ручной проверки
return d


def normalize_kpp(kpp: str | None) -> str | None:
d = digits_only(kpp)
if d is None or len(d) != 9:
return None
return d


def normalize_ogrn(ogrn: str | None) -> str | None:
d = digits_only(ogrn)
if d is None or len(d) not in (13, 15):
return None
return d


def inn_kpp_key(inn: str | None, kpp: str | None) -> str | None:
ni, nk = normalize_inn(inn), normalize_kpp(kpp)
if ni is None:
return None
if nk is None:
return ni
return f"{ni}_{nk}"


# Пример
assert normalize_inn(" 7707083893 ") == "7707083893"
assert normalize_kpp("770701001") == "770701001"
assert inn_kpp_key("7707083893", "770701001") == "7707083893_770701001"

Проверка результата

  • Доля строк с нестандартной длиной ИНН после очистки должна быть объяснима (иностранные регистрации, тестовые поля, опечатки) — иначе проверьте кодировку исходного файла.
  • При джойне только по ИНН на организацию с несколькими КПП контролируйте, не смешиваются ли филиалы в одну строку (КПП).
  • Сопоставление с ОГРН из ЕГРЮЛ: один ОГРН соответствует одной записи о юрлице; расхождение ИНН и ОГРН в одной строке данных — сигнал к ручной сверке.

Ограничения и типовые ошибки

  • Числовой тип в pandas/Excel для ИНН/ОГРН — обрезание ведущих нулей и потеря точности для длинных цепочек; держите как string/object.
  • КПП у ИП в том же смысле, что у организаций, не используется — не требуйте КПП в ключе ко всем контрагентам без фильтра по типу (КПП).
  • ОКТМО vs КПП — оба могут «намекать» на географию, но это разные классификаторы; не подменяйте одно другим при агрегации по территории.
  • ОГРН ≠ реестровый номер контракта в ЕИС — не путайте регистрацию юрлица с идентификатором закупки (расшифровка идентификаторов ЕИС).

Связанные страницы