Загрузка данных


import re
import openpyxl

# ================= НАСТРОЙКИ =================
# 1. Имена твоих файлов (положи их в одну папку со скриптом)
FILE_MAIN = 'main.xlsx'  # Твоя основная таблица с преподами
FILE_NAGRUZKA = 'Svodnaya_uchebnaya_nagruzka_12_09_2026_-_krasnym_izmenenia.xlsx'
FILE_PODRAZDEL = 'Подразделения.xlsx'  # Проверь точное название файла подразделений
FILE_OUTPUT = 'main_ready.xlsx'  # Куда сохранить готовый результат

# 2. Номера столбцов в ОСНОВНОЙ таблице (счет идет слева направо: A=1, B=2, C=3, D=4...)
# Поменяй эти 3 цифры под свою основную таблицу!
COL_SUBJECT = 1  # В каком столбце написано Название предмета (Дисциплина)
COL_FIO = 2  # В каком столбце написано ФИО преподавателя
COL_KAFEDRA = 3  # В каком столбце написана Кафедра (где сейчас "ЦПД" или пусто)
START_ROW = 2  # С какой строки начинаются данные (если 1-я строка шапка, то 2; если шапки нет — 1)
# =============================================


def clean_str(val):
    """Очищает текст от кавычек, переносов строк и двойных пробелов для точного поиска"""
    if val is None:
        return ''
    s = str(val).replace('"', '').replace("'", '').replace('«', '').replace('»', '')
    s = re.sub(r'\s+', ' ', s)  # Заменяем переносы строк и табы на обычный пробел
    return s.strip().lower()


print('1. Читаем файл Подразделений (собираем шифры)...')
wb_podr = openpyxl.load_workbook(FILE_PODRAZDEL, data_only=True)
kaf_to_shifr = {}

# Проходим по всем листам файла подразделений
for sheet in wb_podr.worksheets:
    for row in sheet.iter_rows(values_only=True):
        # На фото: B (индекс 1) — Шифр, C (индекс 2) — Факультеты/Кафедры
        if len(row) >= 3 and row[1] is not None and row[2] is not None:
            shifr = str(row[1]).strip()
            kaf_full = clean_str(row[2])
            if kaf_full and kaf_full != 'факультеты/кафедры' and shifr.lower() != 'шифр':
                kaf_to_shifr[kaf_full] = shifr

print(f'   Найдено шифров кафедр: {len(kaf_to_shifr)}')

print('2. Читаем Сводную нагрузку (связываем предметы и кафедры)...')
wb_nagr = openpyxl.load_workbook(FILE_NAGRUZKA, data_only=True)
subj_to_kaf = {}

for sheet in wb_nagr.worksheets:
    for row in sheet.iter_rows(values_only=True):
        # На фото: B (индекс 1) — Кафедра, C (индекс 2) — Дисциплина
        if len(row) >= 3 and row[1] is not None and row[2] is not None:
            kaf_name = clean_str(row[1])
            subj_name = clean_str(row[2])
            if subj_name and subj_name != 'дисциплина' and kaf_name != 'кафедра':
                subj_to_kaf[subj_name] = kaf_name

print(f'   Найдено дисциплин в нагрузке: {len(subj_to_kaf)}')

print('3. Обрабатываем основную таблицу...')
wb_main = openpyxl.load_workbook(FILE_MAIN)
ws_main = wb_main.active

updated_kaf_count = 0
updated_fio_count = 0
not_found_subjects = set()
not_found_kafedras = set()

for row_idx in range(START_ROW, ws_main.max_row + 1):
    cell_subj = ws_main.cell(row=row_idx, column=COL_SUBJECT)
    cell_fio = ws_main.cell(row=row_idx, column=COL_FIO)
    cell_kaf = ws_main.cell(row=row_idx, column=COL_KAFEDRA)

    fio_val = str(cell_fio.value).strip() if cell_fio.value is not None else ''
    kaf_val = str(cell_kaf.value).strip() if cell_kaf.value is not None else ''
    subj_val = clean_str(cell_subj.value)

    # Пропускаем совсем пустые строки
    if not fio_val and not subj_val:
        continue

    # Если кафедра пустая — ищем её по предмету
    if not kaf_val and subj_val:
        kaf_full_name = subj_to_kaf.get(subj_val)

        if kaf_full_name:
            # Ищем точное совпадение в подразделениях
            shifr = kaf_to_shifr.get(kaf_full_name)

            # Если точного нет (например, из-за "имени М.Ф. Ненашева"), ищем по частичному вхождению
            if not shifr:
                for k_podr, s_podr in kaf_to_shifr.items():
                    if kaf_full_name in k_podr or k_podr in kaf_full_name:
                        shifr = s_podr
                        break

            if shifr:
                kaf_val = shifr
                cell_kaf.value = shifr  # Записываем аббревиатуру в ячейку кафедры
                updated_kaf_count += 1
            else:
                not_found_kafedras.add(kaf_full_name)
        else:
            not_found_subjects.add(str(cell_subj.value).strip())

    # Приписываем к ФИО кафедру в скобках без пробела: ФИО(ЦПД)
    if fio_val and kaf_val:
        # Проверяем, не приписана ли уже эта кафедра в конце ФИО
        suffix = f'({kaf_val})'
        if not fio_val.endswith(suffix):
            # Если на конце уже были какие-то старые скобки, убираем или оставляем чистое ФИО
            cell_fio.value = f'{fio_val}{suffix}'
            updated_fio_count += 1

wb_main.save(FILE_OUTPUT)
print(f'\nГотово! Результат сохранен в файл: {FILE_OUTPUT}')
print(f'— Вписано недостающих кафедр: {updated_kaf_count}')
print(f'— Обновлено ФИО со скобками: {updated_fio_count}')

if not_found_subjects:
    print(f'\n[!] Не найдены в сводной нагрузке предметы ({len(not_found_subjects)} шт.):')
    for s in list(not_found_subjects)[:10]:
        print(f'   - {s}')

if not_found_kafedras:
    print(f'\n[!] Найдены в нагрузке, но нет шифра в Подразделениях ({len(not_found_kafedras)} шт.):')
    for k in not_found_kafedras:
        print(f'   - {k}')