From 947c494d8f34edf6bee1906053e61162bc935cea Mon Sep 17 00:00:00 2001 From: manoraga Date: Tue, 4 Aug 2026 18:29:25 +0300 Subject: [PATCH] =?UTF-8?q?=D0=BE=D1=87=D0=B8=D1=81=D1=82=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PROJECT_SNAPSHOT.md | 82 ------------------------ PROJECT_SNAPSHOT_old.md | 133 --------------------------------------- data/knowledge_base.json | 10 --- update_kb.py | 45 ------------- zup_detective.py | 63 ------------------- zup_scanner.py | 60 ------------------ 6 files changed, 393 deletions(-) delete mode 100644 PROJECT_SNAPSHOT.md delete mode 100644 PROJECT_SNAPSHOT_old.md delete mode 100644 data/knowledge_base.json delete mode 100644 update_kb.py delete mode 100644 zup_detective.py delete mode 100644 zup_scanner.py diff --git a/PROJECT_SNAPSHOT.md b/PROJECT_SNAPSHOT.md deleted file mode 100644 index 4f642a4..0000000 --- a/PROJECT_SNAPSHOT.md +++ /dev/null @@ -1,82 +0,0 @@ -# 📦 ПАСПОРТ СНАПШОТА ПРОЕКТА: `scud_orion_ai_v2` - -> **Архитектура:** Автоматизированный конвейер кадрового контроллинга и детекции аномалий -> **Интеграционный стек:** `СКУД «Орион Pro»` ⟷ `1С:ЗУП` ⟷ `AI-Аудитор` -> **Статус:** 🟢 **Готовая боевая сборка** с прямой SQL-интеграцией, обработкой 1С-реестров и обучением на лету. - ---- - -## 📁 Итоговая структура каталогов - -```plaintext -scud_orion_ai_v2/ -├── .gitignore # Настройки исключений отслеживания Git -├── exceptions.json # Реестр постоянных исключений (ОВК, подрядчики, особые роли) -├── knowledge_base.json # Динамическая база знаний (накопленные правила ИИ из режима Human-in-the-Loop) -├── config.py # Глобальная конфигурация путей, моделей Ollama и функций нормализации -├── main.py # Главный оркестратор (Этапы 0–5, логика слияния, детекция аномалий) -│ -├── data/ # 📂 Папка входных сырых данных -│ ├── scud/ # [Автовыгрузка СКУД] Файлы Сотрудники_ДД.ММ.ГГГГ.xlsx из MS SQL -│ ├── 1c/ # [Кадровые реестры] Файлы из 1С:ЗУП: -│ │ # • Штатные сотрудники - ОУП.xlsx -│ │ # • Отсутствия сотрудников - выгрузка.xlsx -│ └── static_reason_workers.csv# [Справочник] Реестр постоянных причин (Удаленка и т.д.) -│ -├── output/ # 📂 Результаты работы (Excel-сводки и ИИ-отчеты в Markdown) -│ ├── Сводка_контроллинга_ДД.ММ.ГГГГ.md -│ ├── ДД месяца ГГГГ сводка.xlsx -│ └── ДД месяца ГГГГ отчет.xlsx -│ -└── modules/ # 📂 Функциональные ядро-модули - ├── scud_export.py # Модуль прямого подключения к MS SQL Server (Орион Pro) - ├── data_loader.py # Загрузка и первичная предобработка СКУД/1С файлов - ├── data_validator.py # Валидатор свежести и корректности входных таблиц - ├── ai_verifier.py # Интеграция с Ollama (Qwen2.5) для нечеткого поиска ФИО и опечаток - ├── text_reporter.py # Формирователь экспертного аналитического отчета ИИ - ├── excel_exporter.py # Генератор итоговых стилизованных Excel-отчетов - ├── feedback_loop.py # Модуль интерактивного обучения и дообучения ИИ (Human-in-the-Loop) - └── knowledge_base.py # Менеджер чтения/записи базы знаний knowledge_base.json -``` - ---- - -## 🛠️ Главные технические наработки и решённые задачи - -### 1. Автоматический забор данных СКУД из БД MS SQL Server (`scud_export.py`) -* **Прямой коннект:** Запрос к БД СКУД `Orion-14.01.21-1` через `pyodbc`. -* **Высокая скорость (0.2 сек):** Использование оконной функции `ROW_NUMBER() OVER (PARTITION BY HozOrgan ORDER BY TimeVal DESC)` для мгновенного сбора событий за 24 часа. -* **Корректный учет текущего присутствия (`СЕГОДНЯ`):** - * Если день ещё не окончен и последнее событие — **Вход**, в колонке выводится `Нет выхода`. - * Ограничено искажение времени для тех, кто ещё находится в здании или уходил на обед. -* **Поддержка отладки (`-d` / `--debug`):** Вывод детальной статистики в консоль (сколько в здании, сколько ушло, сколько отсутствовало). - -### 2. Нормализация и ИИ-сборка данных (`config.py` + `data_loader.py` + `ai_verifier.py`) -* **Удаление технического мусора:** Автоматическая очистка служебных пометок 1С в скобках (`(осн.)`, `(совм.)`, `(сводная)`), предотвращающая расхождение ФИО. -* **Умное слияние с 1С:** Поиск опечаток и несопоставленных записей в реестре отсутствий через нейросеть `Qwen2.5:14b`. - -### 3. Комплексный детектор аномалий (`main.py`) -Автоматическое пересечение всех 4 источников (*СКУД* + *1С* + *Статический реестр* + *Исключения*) с перехватом конфликтов: -* 🔴 **Критическая аномалия:** Физический проход по СКУД при наличии оформленного документа в 1С (*Отпуск* / *Больничный* / *Командировка*). -* 🟠 **Удалёнщик в офисе:** Сотрудник числится на постоянной удалёнке, но пришёл через турникет. -* 🟡 **Конфликт справочников:** Нестыковка данных 1С:ЗУП и реестра статических причин. - -### 4. Обучение на лету / Human-in-the-Loop (`feedback_loop.py` + `knowledge_base.json`) -* **Запоминание правил:** Если пользователь разрешает спорную ситуацию *(например: «Незнанова иногда в офисе — не считать аномалией»)*, правило фиксируется в `knowledge_base.json`. -* **Авто-фильтрация:** Детектор аномалий проверяет Базу Знаний до формирования вопросов, избавляя пользователя от повторных уведомлений по решённым случаям. - -### 5. Лаконичная аналитическая отчетность (`text_reporter.py`) -* Формирование строгой сводки в формате Markdown. -* Выведение отдельным блоком нумерованного списка истинно неизвестных случаев. -* Отсутствие дублирования ФИО в разделе кадровых рекомендаций. - ---- - -## 🚀 Команды для запуска снапшота - -| Режим запуска | Команда в терминале | -| :--- | :--- | -| **Стандартный запуск** *(Экспорт СКУД из SQL + ИИ Анализ)* | `python main.py` | -| **Режим отладки** *(С детальными логами)* | `python main.py -d` | -| **Без повторного обращения к SQL** *(На сохраненных файлах)* | `python main.py --skip-export` | -| **Отладка только модуля выгрузки СКУД** | `python modules/scud_export.py -d` | diff --git a/PROJECT_SNAPSHOT_old.md b/PROJECT_SNAPSHOT_old.md deleted file mode 100644 index ecf079e..0000000 --- a/PROJECT_SNAPSHOT_old.md +++ /dev/null @@ -1,133 +0,0 @@ -# Архитектура и документация проекта СКУД v2 - -## 1. Фактическая структура проекта - -```text -scud_root_v2/ -│ -├── config.py # Конфигурация, глобальные пути (DATA_DIR, OUTPUT_DIR), даты (DATE_TODAY, DATE_YESTERDAY) -├── exceptions.json # Фильтры исключений (ОВК, клинеры, конкретные ФИО) -├── PROJECT_SNAPSHOT.md # 📄 Архитектурный снимок состояния проекта -├── main.py # Главный скрипт запуска и оркестрации всего конвейера -│ -├── data/ # 📂 Входные файлы (Выгрузки СКУД и 1С) -│ ├── knowledge_base.json # Накопленная база знаний и динамические правила компании -│ ├── Штатные сотрудники - ОУП.xlsx # Выгрузка штата из 1С -│ ├── Отсутствия сотрудников - выгрузка.xlsx # Выгрузка докум. отсутствий из 1С -│ ├── Сотрудники_24.07.2026.xlsx # Выгрузка СКУД за ВЧЕРА (для детального отчета) -│ └── Сотрудники_27.07.2026.xlsx # Выгрузка СКУД за СЕГОДНЯ (для оперативной сводки) -│ -├── modules/ # 📂 Исполняемые модули системы -│ ├── __init__.py -│ ├── data_validator.py # 🛡️ Детерминированный контроль актуальности и свежести входных файлов СКУД/1С -│ ├── data_loader.py # Загрузка и объединение Excel-выгрузок СКУД и 1С -│ ├── ai_verifier.py # Интеграция с Ollama (qwen2.5:14b) для исправления опечаток в ФИО из СКУД -│ ├── excel_exporter.py # 📊 Единый модуль генерации Excel-файлов (Сводка + Детальный отчет за вчера) -│ ├── text_reporter.py # 📝 ИИ-аудитор (формирование текстовой сводки с проверкой совмещений) -│ ├── knowledge_base.py # Чтение/запись динамических правил компании -│ └── feedback_loop.py # Модуль обратной связи для обучения базы знаний -│ -└── output/ # 📂 Результаты работы (генерируются автоматически): - ├── 26 июля 2026 отчет.xlsx - ├── 27 июля 2026 сводка.xlsx - └── Сводка_контроллинга_27.07.2026.md -``` - ---- - -## 2. Подробное описание модулей и их логики - -### ⚙️ `config.py` -**Константы:** -- `OLLAMA_URL = "http://localhost:11434/api/chat"` -- `OLLAMA_MODEL = "qwen2.5:14b"` -- `DATE_TODAY`, `DATE_YESTERDAY` — расчет рабочих дат. - -**Основные функции:** -- `normalize_fio()` — приводит ФИО к нижнему регистру, удаляет скобки `(...)`, меняет латинские визуальные дубликаты букв на кириллицу, заменяет `ё` на `е`. -- `clean_scud_fio_light()` — облегченная очистка ФИО из СКУД от системных символов и артефактов. -- `load_exceptions()` — загружает фильтры и исключения из `exceptions.json`. - ---- - -### 🛡️ `modules/data_validator.py` -Модуль детерминированного контроля актуальности данных (**Data Quality & Freshness Control**). - -- Проверяет наличие файлов за сегодня и вчера в папке `data/`. -- Проверяет дату и время изменения файлов (`mtime`), предотвращая запуск системы на устаревших выгрузках прошлого дня. -- В случае отсутствия или устаревания данных блокирует запуск основного конвейера и предупреждает оператора. - ---- - -### 🛡️ `exceptions.json` -Содержит конфигурационные списки исключений, отфильтровываемые при сборе аналитики: -- **Департаменты:** отдел ОВК и др. -- **Должности:** Уборщик, Клинер, Дворник и т.д. -- **Персональные исключения:** конкретные ФИО сотрудников или подрядчиков. - ---- - -### 📥 `modules/data_loader.py` -- Выполняет загрузку данных из папки `data/`. -- Определяет факт присутствия на рабочем месте (`Пришел = True`, если зафиксирован проход в СКУД). -- Применяет правила фильтрации `is_excluded()` на основе данных из `exceptions.json`. - ---- - -### 🤖 `modules/ai_verifier.py` -- Отправляет список нераспознанных ФИО из СКУД и эталонный список из 1С в модель Ollama (`qwen2.5:14b`). -- Автоматически выявляет опечатки, несоответствия в написании и возвращает JSON сопоставлений. - ---- - -### 📊 `modules/excel_exporter.py` -Универсальный модуль формирования отчетов в формате Excel. Автоматически формирует имена файлов с названием месяца прописью (например, `27 июля 2026 сводка.xlsx` и `26 июля 2026 отчет.xlsx`). - -#### 1. Оперативная сводка за сегодня (`generate_summary_excel`): -- **Древовидная группировка:** Категория *«неизвестно»* раскрыта по умолчанию, остальные категории свернуты под плюсики `[+]` / `[-]`. -- **Настройка структуры:** Принудительно включено отображение боковой панели со значками группировки через `showOutlineSymbols = True`. -- **Палитра:** - - Шапка: `#D9E1F2` *(Светло-голубой)* - - По списку: `#F2F2F2` *(Светло-серый)* - - Неизвестно: `#FCE4D6` *(Персиковый)* - - Категории 1С: Циклическая пастельная палитра (`#FFF2CC`, `#E1D5E7`, `#E1F5FE`, `#FFF0F5`, `#E8F8F5`, `#FCF3CF`) - - Итого на работе: `#E2EFDA` *(Светло-зеленый)* - -#### 2. Детальный отчет за вчера (`generate_detailed_excel`): -- **Динамическая ширина колонок:** Ширина столбцов рассчитывается по длине самого широкого значения ячеек. -- **Столбец G (Причина отсутствия):** Ширина фиксирована на `25.0` (180 px), включен автоперенос текста (`wrap_text = True`) с адаптивным расширением высоты строк под длинные тексты. -- **Цветовая маркировка:** - - `#FFF2CC` *(Желтый)* — есть официальная причина в 1С. - - `#FCE4D6` *(Светло-красный)* — приход отсутствует, документ в 1С не найден. - ---- - -### 📝 `modules/text_reporter.py` -- Формирует с помощью Ollama текстовую Markdown-сводку для руководства. -- **Форматирование нумерованного списка неизвестных:** Строгий формат `N. ФИО — [Аббревиатура], Должность`. -- **Контроль математики:** Количество человек в поле *«Неизвестно»* строго совпадает с количеством элементов в сгенерированном нумерованном списке. -- **Подсветка аномалий:** Выявление совмещений и сотрудников с несколькими табельными номерами/картами СКУД (например, Кондрашова Е.В.). - ---- - -### 🚀 `main.py` -Главный исполнительный модуль системы. Координирует конвейер обработки: - -1. `check_file_freshness()` — **Этап 0:** жесткая проверка свежести файлов. -2. `load_all_data()` — загрузка реестров 1С и СКУД. -3. `ai_verify()` — сопоставление опечаток в ФИО через ИИ. -4. `merge()` — связывание, фильтрация и категоризация данных. -5. **Генерация отчетов** — создание `[дата] сводка.xlsx` и `[дата] отчет.xlsx`. -6. **Вывод ИИ-сводки** — формирование и сохранение текстового итогового отчета в `output/`. - ---- - -## 3. Текущие и будущие задачи - -### 🗄️ Разворачивание локальной базы данных -- Переход от плоских файлов Excel к локальной СУБД (SQLite / PostgreSQL). -- Хранение истории проходов и статусов сотрудников с временными метками для быстрого формирования аналитики за любой выбранный период. - -### 🔄 Переход на прямое подключение к СКУД через T-SQL -- Настройка прямого подключения Python к базе данных СКУД через `pyodbc` / `sqlalchemy`. -- Отказ от ручной выгрузки Excel-файлов СКУД оператором. \ No newline at end of file diff --git a/data/knowledge_base.json b/data/knowledge_base.json deleted file mode 100644 index b284975..0000000 --- a/data/knowledge_base.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "rules": [ - "Кондрашова Елена Владимировна имеет 2 пропуска в СКУД. Если один 'Отсутствовал', а второй с временем входа — считать ПРИШЕДШЕЙ.", - "ГЛОБАЛЬНОЕ ПРАВИЛО 1: Документы отсутствий из 1С:ЗУП (отпуск, больничный, командировка) имеют 100% высший приоритет над статическим реестром удалёнщиков.", - "ГЛОБАЛЬНОЕ ПРАВИЛО 2: Удалённые сотрудники имеют право беспрепятственно работать в офисе по СКУД в любое время (это не является аномалией)." - ], - "fio_corrections": { - "кондрашава елена владимировна": "Кондрашова Елена Владимировна" - } -} \ No newline at end of file diff --git a/update_kb.py b/update_kb.py deleted file mode 100644 index e66ff4c..0000000 --- a/update_kb.py +++ /dev/null @@ -1,45 +0,0 @@ -import sqlite3 -import os -from config import DATA_DIR - -DB_PATH = os.path.join(DATA_DIR, "scud_orion_ai.db") - -system_ai_prompt = ( - "СИСТЕМНЫЙ ПРОМПТ ИИ (MATCHING & VERIFICATION):\n" - "Ты — экспертный ИИ-аудитор СКУД и кадрового учета 1С. Твоя задача — проводить интеллектуальный анализ аномалий " - "и сопоставление (Fuzzy Matching) нераспознанных ФИО из СКУД с эталонным Штатным расписанием 1С.\n\n" - "1. ЗАЩИТА ОТ ПОЛНЫХ ТЁЗОК (FULL NAME COLLISION):\n" - " - Если в эталонном штате 1С присутствуют два или более сотрудников с ОДИНАКОВЫМИ ФИО (полные тёзки), " - "ты ОБЯЗАН учитывать контекст: Подразделение и Должность.\n" - " - Ни в коем случае не объединяй записи разных людей! Если контекст не позволяет однозначно определить, кто именно из тёзок совершил проход, ПОМЕТЬ СЛУЧАЙ КАК НЕОДНОЗНАЧНЫЙ и НЕ делай автоматическую подмену.\n\n" - "2. ПРАВИЛА СОПОСТАВЛЕНИЯ (MATCHING RULES):\n" - " - Допускаются исправления мелких опечаток, перестановки порядка (Имя Фамилия -> Фамилия Имя), замена букв Е/Ё, И/Й.\n" - " - Учитывай сокращения инициалов (например, 'Иванов И.В.' -> 'Иванов Иван Васильевич').\n" - " - Если уверенность в совпадении меньше 85% — НЕ сопоставляй, оставляй запись как нераспознанную.\n\n" - "3. ФОРМАТ ВЫХОДНЫХ ДАННЫХ:\n" - " Верни строго JSON-объект без вводных слов и Markdown-разметки: {\"mappings\": [...], \"unmatched\": [...]}" -) - -rules = [ - (system_ai_prompt, "System_AI"), - ("ГЛОБАЛЬНОЕ ПРАВИЛО 1: Любое физическое присутствие сотрудника по СКУД при наличии в 1С документа отсутствия (отпуск, больничный, уход за ребенком и др.), КРОМЕ командировок и служебных поездок — ЯВЛЯЕТСЯ СТРОГОЙ ИСТИННОЙ АНОМАЛИЕЙ.", "Human"), - ("ГЛОБАЛЬНОЕ ПРАВИЛО 2: Документы отсутствий из 1С:ЗУП имеют 100% высший приоритет над статическим реестром удалёнщиков.", "Human"), - ("ГЛОБАЛЬНОЕ ПРАВИЛО 3: Удалённые сотрудники имеют право беспрепятственно работать в офисе по СКУД в любое время (это не является аномалией).", "Human") -] - -conn = sqlite3.connect(DB_PATH) -cursor = conn.cursor() - -# Очищаем таблицу перед записью, чтобы избежать дублей и UNIQUE constraint error -cursor.execute("DELETE FROM ai_knowledge_base;") - -for rule_text, added_by in rules: - cursor.execute( - "INSERT INTO ai_knowledge_base (rule_text, added_by) VALUES (?, ?)", - (rule_text, added_by) - ) - -conn.commit() -conn.close() - -print("✅ База знаний успешно перезаписана с включением системного промпта ИИ!") \ No newline at end of file diff --git a/zup_detective.py b/zup_detective.py deleted file mode 100644 index 3f9dd25..0000000 --- a/zup_detective.py +++ /dev/null @@ -1,63 +0,0 @@ -import pyodbc -from config import ZUP_SQL_CONFIG - -print("="*60) -print("🕵️‍♂️ ZUP DETECTIVE: ПОИСК СТАТУСА 'УВОЛЕН'") -print("="*60) - -conn_str = ( - f"DRIVER={ZUP_SQL_CONFIG['driver']};" - f"SERVER={ZUP_SQL_CONFIG['server']};" - f"DATABASE={ZUP_SQL_CONFIG['database']};" - f"UID={ZUP_SQL_CONFIG['user']};" - f"PWD={ZUP_SQL_CONFIG['password']};" - f"TrustServerCertificate=yes;" -) - -with pyodbc.connect(conn_str) as conn: - cursor = conn.cursor() - - # 1. Получаем ID наших подопытных - cursor.execute("SELECT TOP 1 _IDRRef FROM dbo._Reference299 WHERE _Description LIKE '%Шумский Алексей Анатольевич%'") - id_work = cursor.fetchone()[0] - - cursor.execute("SELECT TOP 1 _IDRRef FROM dbo._Reference299 WHERE _Description LIKE '%Щелканов Дмитрий Викторович%'") - id_fired = cursor.fetchone()[0] - - # 2. Сканируем два самых больших кадровых регистра, которые нашел наш сканер - for table in ['_InfoRg16684', '_InfoRg32796']: - print(f"\n🔍 АНАЛИЗ РЕГИСТРА: {table}") - - # Ищем все колонки-ссылки - cursor.execute(f"SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('{table}') AND system_type_id = 173 AND max_length = 16") - cols_bin = [r[0] for r in cursor.fetchall()] - - found = False - for col in cols_bin: - cursor.execute(f"SELECT COUNT(*) FROM dbo.{table} WITH (NOLOCK) WHERE {col} = ?", (id_work,)) - if cursor.fetchone()[0] > 0: - print(f"✅ Найдена колонка связи с Сотрудником: {col}") - - # Забираем полные строки обоих людей - cursor.execute(f"SELECT * FROM dbo.{table} WITH (NOLOCK) WHERE {col} = ?", (id_work,)) - data_work = cursor.fetchone() - all_cols = [c[0] for c in cursor.description] - - cursor.execute(f"SELECT * FROM dbo.{table} WITH (NOLOCK) WHERE {col} = ?", (id_fired,)) - data_fired = cursor.fetchone() - - if data_work and data_fired: - print("\n⚖️ ОТЛИЧИЯ В ДАННЫХ (Работает vs Уволен):") - for i, c in enumerate(all_cols): - # Выводим только те поля, где есть отличия - if data_work[i] != data_fired[i]: - print(f"Поле [{c}]:") - print(f" 🟢 Шумский: {data_work[i]}") - print(f" 🔴 Щелканов: {data_fired[i]}\n") - found = True - break - - if found: - break - -print("✅ Расследование завершено!") \ No newline at end of file diff --git a/zup_scanner.py b/zup_scanner.py deleted file mode 100644 index d3ae8dd..0000000 --- a/zup_scanner.py +++ /dev/null @@ -1,60 +0,0 @@ -import pyodbc -from config import ZUP_SQL_CONFIG - -print("="*60) -print("🔍 ЗАПУСК СКАНЕРА СТРУКТУРЫ 1С:ЗУП 3.1") -print("="*60) - -conn_str = ( - f"DRIVER={ZUP_SQL_CONFIG['driver']};" - f"SERVER={ZUP_SQL_CONFIG['server']};" - f"DATABASE={ZUP_SQL_CONFIG['database']};" - f"UID={ZUP_SQL_CONFIG['user']};" - f"PWD={ZUP_SQL_CONFIG['password']};" - f"TrustServerCertificate=yes;" - f"Encrypt=no;" -) - -with pyodbc.connect(conn_str) as conn: - cursor = conn.cursor() - - print("⏳ Анализ справочников...") - cursor.execute("SELECT name FROM sys.tables WHERE name LIKE '_Reference%'") - for row in cursor.fetchall(): - t = row[0] - try: - cursor.execute(f"SELECT TOP 5 CAST(_Description AS NVARCHAR(255)) FROM {t} WITH (NOLOCK) WHERE _Description <> ''") - vals = [r[0].strip() for r in cursor.fetchall() if r[0]] - if not vals: continue - text = " ".join(vals).lower() - - # Ищем сотрудников (исключая физлиц _Reference299) - if t != '_Reference299' and any(w in text for w in ["александров", "иванов", "смирнов", "петрова", "сергеев"]): - print(f"👤 СОТРУДНИКИ ({t}): {vals[:3]}") - # Ищем должности - elif any(w in text for w in ["инженер", "специалист", "директор", "уборщик"]): - print(f"💼 ДОЛЖНОСТИ ({t}): {vals[:3]}") - # Ищем подразделения - elif any(w in text for w in ["отдел", "управление", "служба"]): - print(f"🏢 ПОДРАЗДЕЛЕНИЯ ({t}): {vals[:3]}") - except: - pass - - print("\n⏳ Анализ регистров кадровой истории...") - cursor.execute("SELECT name FROM sys.tables WHERE name LIKE '_InfoRg%'") - for row in cursor.fetchall(): - t = row[0] - try: - # Ищем широкие регистры (Текущие кадровые данные имеют много колонок) - cursor.execute(f"SELECT COUNT(*) FROM sys.columns WHERE object_id = OBJECT_ID('{t}')") - col_count = cursor.fetchone()[0] - - cursor.execute(f"SELECT COUNT(*) FROM {t} WITH (NOLOCK)") - row_count = cursor.fetchone()[0] - - if col_count > 15 and row_count > 500: - print(f"📋 ШИРОКИЙ РЕГИСТР КАДРОВ ({t}) -> Колонок: {col_count}, Строк: {row_count}") - except: - pass - -print("\n✅ Сканирование завершено!") \ No newline at end of file