Загрузка данных
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}')