From f3e94ef49d8d1908eb7af8cb3ccdd5ebf180feab Mon Sep 17 00:00:00 2001 From: "vladimir.buzalka" Date: Fri, 17 Oct 2025 14:25:39 +0200 Subject: [PATCH] z230 --- 11 Vakcina na samostatných listech.py | 151 +++++++++++++++++++++++++ 12 Vakcina na samostatnych listech.py | 157 ++++++++++++++++++++++++++ 2 files changed, 308 insertions(+) create mode 100644 11 Vakcina na samostatných listech.py create mode 100644 12 Vakcina na samostatnych listech.py diff --git a/11 Vakcina na samostatných listech.py b/11 Vakcina na samostatných listech.py new file mode 100644 index 0000000..4ddd5a9 --- /dev/null +++ b/11 Vakcina na samostatných listech.py @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from pathlib import Path +import time +import fdb +import pandas as pd +from openpyxl import load_workbook +from openpyxl.worksheet.table import Table, TableStyleInfo +from openpyxl.styles import Font, PatternFill, Alignment +from openpyxl.utils import get_column_letter + +# ================== Výstupní cesta ================== +BASE_DIR = Path(r"..") # uprav dle potřeby +timestamp = time.strftime("%Y-%m-%d %H-%M-%S") +xlsx_name = f"Pacienti očkování {timestamp}.xlsx" +xlsx_path = BASE_DIR / xlsx_name + +# ================== Definice skupin vakcín ================== +SHEETS = { + "COVID-19": ["commirnaty", "spikevax", "nuvaxovid"], + "Chřipka": ["vaxigrip", "influvac", "fluarix", "afluria"], + "Klíšťová encefalitida": ["fsme", "encepur"], + "Tetanus": ["tetavax", "boostrix", "adacel"], + "HepA": ["avaxim", "havrix"], + "HepB": ["engerix"], + "HepA+B": ["twinrix"] +} + +# ================== Připojení k DB ================== +con = fdb.connect( + host='192.168.1.4', + database=r'z:\\MEDICUS 3\\data\\medicus.FDB', + user='sysdba', + password='masterkey', + charset='WIN1250' +) + +# ================== SQL dotaz ================== +sql = """ +SELECT + kar.rodcis AS "Rodné číslo", + kar.prijmeni AS "Příjmení", + kar.jmeno AS "Jméno", + ockzaz.datum AS "Datum očkování", + ockzaz.kodmz AS "Kód MZ", + ockzaz.poznamka AS "Šarže", + ockzaz.latka AS "Látka", + ockzaz.nazev AS "Název", + ockzaz.expire AS "Expirace", + ( + SELECT LIST(l.kod, ', ') + FROM lecd l + WHERE l.rodcis = kar.rodcis + AND l.datose = CAST(ockzaz.datum AS DATE) + ) AS "LECD kódy (ten den)", + ( + SELECT LIST(d.kod, ', ') + FROM dokladd d + WHERE d.rodcis = kar.rodcis + AND d.datose = CAST(ockzaz.datum AS DATE) + ) AS "Výkony (ten den)" +FROM registr +JOIN kar ON registr.idpac = kar.idpac +JOIN ockzaz ON registr.idpac = ockzaz.idpac +WHERE + registr.datum_zruseni IS NULL + AND kar.vyrazen <> 'A' + AND kar.rodcis IS NOT NULL + AND idicp <> 0 + AND EXTRACT(YEAR FROM ockzaz.datum) = 2025 +ORDER BY ockzaz.datum DESC +""" + +# ================== Načtení do DataFrame ================== +df = pd.read_sql(sql, con) +con.close() + +# ================== Datové typy ================== +for col in ["Kód MZ", "Šarže", "Rodné číslo", "Látka", "Název", "Příjmení", "Jméno", "LECD kódy","Výkony"]: + if col in df.columns: + df[col] = df[col].astype("string") + +for dcol in ["Datum očkování", "Expirace"]: + if dcol in df.columns: + df[dcol] = pd.to_datetime(df[dcol], errors="coerce") + +# ================== Uložení do Excelu – více listů ================== +with pd.ExcelWriter(xlsx_path, engine="openpyxl") as writer: + for sheet_name, vakciny in SHEETS.items(): + print(sheet_name,vakciny) + mask = df["Látka"].str.contains('|'.join(vakciny), case=False, na=False) + df_filtered = df[mask] + if not df_filtered.empty: + df_filtered.to_excel(writer, index=False, sheet_name=sheet_name) + # navíc celkový přehled všech očkování + df.to_excel(writer, index=False, sheet_name="Vše") + +# ================== Formátování ================== +wb = load_workbook(xlsx_path) + +def autosize_columns(ws): + for col_idx in range(1, ws.max_column + 1): + col_letter = get_column_letter(col_idx) + max_len = 0 + for cell in ws[col_letter]: + val = "" if cell.value is None else str(cell.value) + if len(val) > max_len: + max_len = len(val) + ws.column_dimensions[col_letter].width = min(max(12, max_len + 2), 60) + +def style_table(ws, table_name: str): + max_row = ws.max_row + max_col = ws.max_column + if max_col == 0: + return + + header_fill = PatternFill("solid", fgColor="D9E1F2") + for cell in ws[1]: + cell.font = Font(bold=True) + cell.fill = header_fill + cell.alignment = Alignment(vertical="center") + + ws.freeze_panes = "A2" + + if max_row < 2: + autosize_columns(ws) + return + + ref = f"A1:{get_column_letter(max_col)}{max_row}" + tbl = Table(displayName=table_name.replace(" ", "_"), ref=ref) + tbl.tableStyleInfo = TableStyleInfo( + name="TableStyleMedium9", showRowStripes=True, showColumnStripes=False + ) + ws.add_table(tbl) + autosize_columns(ws) + +def format_dates(ws, columns_names): + header = [c.value for c in ws[1]] + date_cols = [header.index(name) + 1 for name in columns_names if name in header] + for col_idx in date_cols: + for row in ws.iter_rows(min_row=2, min_col=col_idx, max_col=col_idx, max_row=ws.max_row): + row[0].number_format = "DD.MM.YYYY" + +for ws in wb.worksheets: + style_table(ws, ws.title) + format_dates(ws, ["Datum očkování", "Expirace"]) + +wb.save(xlsx_path) + +print(f"✅ Hotovo. Uloženo do: {xlsx_path.resolve()}") diff --git a/12 Vakcina na samostatnych listech.py b/12 Vakcina na samostatnych listech.py new file mode 100644 index 0000000..32f2ba5 --- /dev/null +++ b/12 Vakcina na samostatnych listech.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +from pathlib import Path +import time +import fdb +import pandas as pd +import re +from openpyxl import load_workbook +from openpyxl.worksheet.table import Table, TableStyleInfo +from openpyxl.styles import Font, PatternFill, Alignment +from openpyxl.utils import get_column_letter + +# ================== Výstupní cesta ================== +BASE_DIR = Path(r"..") # uprav dle potřeby +timestamp = time.strftime("%Y-%m-%d %H-%M-%S") +xlsx_name = f"Pacienti očkování {timestamp}.xlsx" +xlsx_path = BASE_DIR / xlsx_name + +# ================== Definice skupin vakcín ================== +SHEETS = { + "COVID-19": ["commirnaty", "spikevax", "nuvaxovid"], + "Chřipka": ["vaxigrip", "influvac", "fluarix", "afluria"], + "Klíšťová encefalitida": ["fsme", "encepur"], + "Tetanus": ["tetavax", "boostrix", "adacel"], + "HepA": ["avaxim", "havrix"], + "HepB": ["engerix"], + "HepA+B": ["twinrix"], +} + +# ================== Připojení k DB ================== +con = fdb.connect( + host='192.168.1.4', + database=r'z:\\MEDICUS 3\\data\\medicus.FDB', + user='sysdba', + password='masterkey', + charset='WIN1250' +) + +# ================== SQL dotaz ================== +sql = """ +SELECT + kar.rodcis AS "Rodné číslo", + kar.prijmeni AS "Příjmení", + kar.jmeno AS "Jméno", + ockzaz.datum AS "Datum očkování", + ockzaz.kodmz AS "Kód MZ", + ockzaz.poznamka AS "Šarže", + ockzaz.latka AS "Látka", + ockzaz.nazev AS "Název", + ockzaz.expire AS "Expirace", + ( + SELECT LIST(l.kod, ', ') + FROM lecd l + WHERE l.rodcis = kar.rodcis + AND l.datose = CAST(ockzaz.datum AS DATE) + ) AS "LECD kódy (ten den)", + ( + SELECT LIST(d.kod, ', ') + FROM dokladd d + WHERE d.rodcis = kar.rodcis + AND d.datose = CAST(ockzaz.datum AS DATE) + ) AS "Výkony (ten den)" +FROM registr +JOIN kar ON registr.idpac = kar.idpac +JOIN ockzaz ON registr.idpac = ockzaz.idpac +WHERE + registr.datum_zruseni IS NULL + AND kar.vyrazen <> 'A' + AND kar.rodcis IS NOT NULL + AND idicp <> 0 + AND EXTRACT(YEAR FROM ockzaz.datum) = 2025 +ORDER BY ockzaz.datum DESC +""" + +# ================== Načtení do DataFrame ================== +df = pd.read_sql(sql, con) +con.close() + +# ================== Datové typy ================== +for col in ["Kód MZ", "Šarže", "Rodné číslo", "Látka", "Název", "Příjmení", "Jméno", "LECD kódy", "Výkony"]: + if col in df.columns: + df[col] = df[col].astype("string") + +for dcol in ["Datum očkování", "Expirace"]: + if dcol in df.columns: + df[dcol] = pd.to_datetime(df[dcol], errors="coerce") + +# ================== Uložení do Excelu – více listů ================== +with pd.ExcelWriter(xlsx_path, engine="openpyxl") as writer: + for sheet_name, vakciny in SHEETS.items(): + pattern = "|".join(re.escape(v) for v in vakciny if v) + mask = df["Látka"].astype(str).str.contains(pattern, case=False, na=False) + df_filtered = df[mask] + if not df_filtered.empty: + df_filtered.to_excel(writer, index=False, sheet_name=sheet_name) + # navíc celkový přehled všech očkování + df.to_excel(writer, index=False, sheet_name="Vše") + +# ================== Formátování ================== +wb = load_workbook(xlsx_path) + +def autosize_columns(ws): + for col_idx in range(1, ws.max_column + 1): + col_letter = get_column_letter(col_idx) + max_len = 0 + for cell in ws[col_letter]: + val = "" if cell.value is None else str(cell.value) + if len(val) > max_len: + max_len = len(val) + ws.column_dimensions[col_letter].width = min(max(12, max_len + 2), 60) + +def safe_table_name(sheet_name): + """Return an Excel-safe, unique table name.""" + name = re.sub(r"[^0-9A-Za-z_]", "_", sheet_name) + return f"tbl_{name[:25]}" + +def style_table(ws): + max_row = ws.max_row + max_col = ws.max_column + if max_col == 0: + return + + header_fill = PatternFill("solid", fgColor="D9E1F2") + for cell in ws[1]: + cell.font = Font(bold=True) + cell.fill = header_fill + cell.alignment = Alignment(vertical="center") + + ws.freeze_panes = "A2" + + if max_row < 2: + autosize_columns(ws) + return + + ref = f"A1:{get_column_letter(max_col)}{max_row}" + tbl = Table(displayName=safe_table_name(ws.title), ref=ref) + tbl.tableStyleInfo = TableStyleInfo( + name="TableStyleMedium9", showRowStripes=True, showColumnStripes=False + ) + ws.add_table(tbl) + autosize_columns(ws) + +def format_dates(ws, columns_names): + header = [c.value for c in ws[1]] + date_cols = [header.index(name) + 1 for name in columns_names if name in header] + for col_idx in date_cols: + for row in ws.iter_rows(min_row=2, min_col=col_idx, max_col=col_idx, max_row=ws.max_row): + row[0].number_format = "DD.MM.YYYY" + +for ws in wb.worksheets: + style_table(ws) + format_dates(ws, ["Datum očkování", "Expirace"]) + +wb.save(xlsx_path) + +print(f"✅ Hotovo. Uloženo do: {xlsx_path.resolve()}")