notebook vb
This commit is contained in:
@@ -26,7 +26,32 @@ cur.execute(f"""
|
||||
""")
|
||||
raw_rows = cur.fetchall()
|
||||
|
||||
TOP_TYPY = ['Rec', 'VykA', 'Files', 'MEDLAB', 'Lab', 'Ock', 'Nes', 'Lec', 'SpecVys', 'PlaPac']
|
||||
TOP_TYPY = ['VykA', 'Rec', 'Files', 'MEDLAB', 'Lab', 'Ock', 'Nes', 'Lec', 'SpecVys', 'PlaPac']
|
||||
|
||||
def rtf_na_text(rtf):
|
||||
"""Jednoduchý převod RTF na čistý text."""
|
||||
# Odstraň info blok (bookmarky apod.)
|
||||
text = re.sub(r'\{\\info.*?\}', '', rtf, flags=re.DOTALL)
|
||||
# Odstraň ostatní skupiny v {} rekurzivně (fonty, barvy apod.)
|
||||
for _ in range(6):
|
||||
text = re.sub(r'\{[^{}]*\}', '', text)
|
||||
# Nový řádek za \par \line
|
||||
text = re.sub(r'\\par\b\s*', '\n', text)
|
||||
text = re.sub(r'\\line\b\s*', '\n', text)
|
||||
# Dekóduj RTF hex escape sekvence (\'xx) jako cp1250 → správná čeština
|
||||
def decode_hex(m):
|
||||
try:
|
||||
return bytes.fromhex(m.group(1)).decode('cp1250')
|
||||
except Exception:
|
||||
return ''
|
||||
text = re.sub(r"\\'([0-9a-fA-F]{2})", decode_hex, text)
|
||||
# Odstraň ostatní RTF příkazy
|
||||
text = re.sub(r'\\[a-zA-Z]+\-?[0-9]*\s?', '', text)
|
||||
text = re.sub(r'[{}\\]', '', text)
|
||||
# Vyčisti prázdné řádky a whitespace
|
||||
lines = [l.strip() for l in text.splitlines()]
|
||||
lines = [l for l in lines if l]
|
||||
return '\n'.join(lines)
|
||||
|
||||
# Parse dekurzů
|
||||
rows = []
|
||||
@@ -45,7 +70,8 @@ for datum, cas, zkratka, prijmeni, jmeno, rodcis, poj, dekurs_blob in raw_rows:
|
||||
ostatni = sum(v for k, v in pocty.items() if k not in TOP_TYPY)
|
||||
iniciala = jmeno[0] + '.' if jmeno and jmeno.strip() else ''
|
||||
jmeno_cel = f"{prijmeni.strip()}, {iniciala}" if prijmeni else iniciala
|
||||
rows.append((datum, cas, zkratka, jmeno_cel, rodcis, poj, top, ostatni, ids_by_typ, ids_ostatni))
|
||||
text_dekurzu = rtf_na_text(rtf)
|
||||
rows.append((datum, cas, zkratka, jmeno_cel, rodcis, poj, top, ostatni, ids_by_typ, ids_ostatni, text_dekurzu))
|
||||
|
||||
# ── Načtení detailů z DB ────────────────────────────────────────────────────
|
||||
def fetch_details(cur, table, pk, id_col, fields, ids):
|
||||
@@ -62,10 +88,10 @@ def fetch_details(cur, table, pk, id_col, fields, ids):
|
||||
return result
|
||||
|
||||
def get_ids(rows, typ):
|
||||
return list({rid for _, _, _, _, _, _, _, _, ids_by_typ, _ in rows for rid in ids_by_typ[typ]})
|
||||
return list({rid for *_, ids_by_typ, _, _text in rows for rid in ids_by_typ[typ]})
|
||||
|
||||
rec_det = fetch_details(cur, 'RECEPT', 'ID', 'ID', ['LEK','DSIG'], get_ids(rows,'Rec'))
|
||||
vyka_det = fetch_details(cur, 'DOKLADD', 'ID', 'ID', ['KOD','DDGN'], get_ids(rows,'VykA'))
|
||||
vyka_det = fetch_details(cur, 'DOKLADD', 'ID', 'ID', ['KOD','DDGN','BODY'], get_ids(rows,'VykA'))
|
||||
files_det = fetch_details(cur, 'FILES', 'ID', 'ID', ['FILENAME','DATUM'], get_ids(rows,'Files'))
|
||||
medlab_det = fetch_details(cur, 'HISTDOC', 'ID', 'ID', ['DATUM','TYP'], get_ids(rows,'MEDLAB'))
|
||||
lab_det = fetch_details(cur, 'LABVH', 'IDVH', 'IDVH', ['DATUM','CISLO'], get_ids(rows,'Lab'))
|
||||
@@ -86,17 +112,17 @@ hl_fill = PatternFill("solid", fgColor="2E75B6")
|
||||
r_fill = [PatternFill("solid", fgColor="FFFFFF"), PatternFill("solid", fgColor="DCE6F1")]
|
||||
|
||||
BARVY_LISTU = {
|
||||
'Recepty': ('1F6B33', 'E2EFDA'),
|
||||
'Výkony': ('2E4057', 'D6E4F0'),
|
||||
'Soubory': ('7B3F00', 'FAE5D3'),
|
||||
'MedLab': ('4A235A', 'F5EEF8'),
|
||||
'Lab': ('145A32', 'D5F5E3'),
|
||||
'Očkování': ('7E5109', 'FDEBD0'),
|
||||
'Neschop.': ('922B21', 'FADBD8'),
|
||||
'Léčiva': ('1A5276', 'D6EAF8'),
|
||||
'SpecVys': ('0B5345', 'D1F2EB'),
|
||||
'Platby': ('4D5656', 'EAECEE'),
|
||||
'Ostatní': ('2C3E50', 'EBF5FB'),
|
||||
'Recepty': ('1F6B33', 'E2EFDA'),
|
||||
'Výkony': ('2E4057', 'D6E4F0'),
|
||||
'Soubory': ('7B3F00', 'FAE5D3'),
|
||||
'Žádanky': ('4A235A', 'F5EEF8'),
|
||||
'Lab výsl.': ('145A32', 'D5F5E3'),
|
||||
'Očkování': ('7E5109', 'FDEBD0'),
|
||||
'Neschop.': ('922B21', 'FADBD8'),
|
||||
'Léčiva': ('1A5276', 'D6EAF8'),
|
||||
'SpecVys': ('0B5345', 'D1F2EB'),
|
||||
'Platby': ('4D5656', 'EAECEE'),
|
||||
'Ostatní': ('2C3E50', 'EBF5FB'),
|
||||
}
|
||||
|
||||
def zapis_hlavicku(ws, sloupce, sirky, barva_hex):
|
||||
@@ -125,7 +151,9 @@ def hyperlink_cell(ws, row_i, col_i, cil_list, cil_radek, text, barva_hex):
|
||||
else PatternFill("solid", fgColor=barva_hex)
|
||||
cell = ws.cell(row=row_i, column=col_i)
|
||||
cell.value = str(text)
|
||||
cell.hyperlink = f'#{cil_list}!A{cil_radek}'
|
||||
# Název listu s mezerou musí být v apostrofech
|
||||
sheet_ref = f"'{cil_list}'" if ' ' in cil_list else cil_list
|
||||
cell.hyperlink = f'#{sheet_ref}!A{cil_radek}'
|
||||
cell.font = Font(color="0000FF", underline='single')
|
||||
cell.fill = fill
|
||||
cell.border = ohraniceni
|
||||
@@ -134,53 +162,63 @@ def hyperlink_cell(ws, row_i, col_i, cil_list, cil_radek, text, barva_hex):
|
||||
# ── Workbook ───────────────────────────────────────────────────────────────
|
||||
wb = openpyxl.Workbook()
|
||||
|
||||
# Pořadí listů a jejich konfigurace: (název, typ_bookmarku, detail_dict, sloupce, šířky, pk_label)
|
||||
LISTY = [
|
||||
('Recepty', 'Rec', rec_det, ['Datum','Jméno','Recept','Dávkování'], [12,25,25,12], None),
|
||||
('Výkony', 'VykA', vyka_det, ['Datum','Jméno','Kód výkonu','Diagnóza'], [12,25,14,10], None),
|
||||
('Soubory', 'Files', files_det, ['Datum','Jméno','Soubor','Datum souboru'], [12,25,35,14], None),
|
||||
('MedLab', 'MEDLAB', medlab_det, ['Datum','Jméno','Typ'], [12,25,15], None),
|
||||
('Lab', 'Lab', lab_det, ['Datum','Jméno','Číslo'], [12,25,20], None),
|
||||
('Očkování', 'Ock', ock_det, ['Datum','Jméno','Datum očkování','Vakcína'], [12,25,14,30], None),
|
||||
('Neschop.', 'Nes', nes_det, ['Datum','Jméno','Od','Do'], [12,25,12,12], None),
|
||||
('Léčiva', 'Lec', lec_det, ['Datum','Jméno','Kód','Datum výkonu'], [12,25,12,14], None),
|
||||
('SpecVys', 'SpecVys', spec_det, ['Datum','Jméno','Typ vyšetření','Datum vyšetření'], [12,25,25,14], None),
|
||||
('Platby', 'PlaPac', pla_det, ['Datum','Jméno','Datum platby','Částka','Doklad'], [12,25,14,12,15], None),
|
||||
('Ostatní', None, None, ['Datum','Jméno','Typ','ID','Název'], [12,25,12,10,30], None),
|
||||
('Recepty', 'Rec', rec_det, ['Datum','Jméno','Recept','Dávkování'], [12,25,25,12], None),
|
||||
('Výkony', 'VykA', vyka_det, ['Datum','Jméno','Kód výkonu','Diagnóza','Body'], [12,25,14,10,8], None),
|
||||
('Soubory', 'Files', files_det, ['Datum','Jméno','Soubor','Datum souboru'], [12,25,35,14], None),
|
||||
('Žádanky', 'MEDLAB', medlab_det, ['Datum','Jméno','Typ'], [12,25,15], None),
|
||||
('Lab výsl.', 'Lab', lab_det, ['Datum','Jméno','Číslo'], [12,25,20], None),
|
||||
('Očkování', 'Ock', ock_det, ['Datum','Jméno','Datum očkování','Vakcína'], [12,25,14,30], None),
|
||||
('Neschop.', 'Nes', nes_det, ['Datum','Jméno','Od','Do'], [12,25,12,12], None),
|
||||
('Léčiva', 'Lec', lec_det, ['Datum','Jméno','Kód','Datum výkonu'], [12,25,12,14], None),
|
||||
('SpecVys', 'SpecVys', spec_det, ['Datum','Jméno','Typ vyšetření','Datum vyšetření'], [12,25,25,14], None),
|
||||
('Platby', 'PlaPac', pla_det, ['Datum','Jméno','Datum platby','Částka','Doklad'], [12,25,14,12,15], None),
|
||||
('Ostatní', None, None, ['Datum','Jméno','Typ','ID','Název'], [12,25,12,10,30], None),
|
||||
]
|
||||
|
||||
# Vytvoříme listy
|
||||
ws_d = wb.active
|
||||
ws_d.title = "Dekurz"
|
||||
|
||||
# List "Text dekurzu" hned za Dekurzem
|
||||
ws_text = wb.create_sheet("Text dekurzu")
|
||||
|
||||
ws_listy = {}
|
||||
for nazev, *_ in LISTY:
|
||||
ws_listy[nazev] = wb.create_sheet(nazev)
|
||||
|
||||
# Záhlaví listů
|
||||
for nazev, typ, det, sloupce, sirky, _ in LISTY:
|
||||
barva_hl, _ = BARVY_LISTU[nazev]
|
||||
zapis_hlavicku(ws_listy[nazev], sloupce, sirky, barva_hl)
|
||||
ws_listy[nazev].freeze_panes = 'A2'
|
||||
|
||||
# Záhlaví Dekurz
|
||||
nazvy_d = ['Datum', 'Čas', 'Lékař', 'Jméno', 'Rodné číslo', 'Pojišťovna'] + TOP_TYPY + ['Ostatní']
|
||||
sirky_d = [12, 8, 8, 25, 14, 12 ] + [8]*10 + [8]
|
||||
# Záhlaví listu "Text dekurzu"
|
||||
zapis_hlavicku(ws_text,
|
||||
['Datum', 'Čas', 'Lékař', 'Jméno', 'Rodné číslo', 'Text dekurzu'],
|
||||
[12, 8, 8, 25, 14, 100],
|
||||
'2E75B6')
|
||||
ws_text.freeze_panes = 'A2'
|
||||
row_ptr_text = 2
|
||||
|
||||
# Zobrazované názvy sloupců pro TOP_TYPY (stejné pořadí)
|
||||
NAZVY_TYPY = ['VykA', 'Rec', 'Files', 'Žádanky', 'Lab výsl.', 'Ock', 'Nes', 'Lec', 'SpecVys', 'PlaPac']
|
||||
|
||||
# Záhlaví Dekurz – sloupce A–R
|
||||
nazvy_d = ['Datum', 'Čas', 'Lékař', 'Jméno', 'Rodné číslo', 'Pojišťovna'] + ['HodVyk'] + NAZVY_TYPY + ['Ostatní']
|
||||
sirky_d = [12, 8, 8, 25, 14, 12 ] + [10] + [38, 8, 8, 8, 8, 8, 8, 8, 8, 8] + [8]
|
||||
zapis_hlavicku(ws_d, nazvy_d, sirky_d, '2E75B6')
|
||||
ws_d.freeze_panes = 'A2'
|
||||
ws_d.auto_filter.ref = f"A1:Q{len(rows)+1}"
|
||||
ws_d.auto_filter.ref = f"A1:R{len(rows)+1}"
|
||||
|
||||
# Aktuální řádek pro každý list
|
||||
row_ptr = {nazev: 2 for nazev, *_ in LISTY}
|
||||
|
||||
# ── Plnění dat ─────────────────────────────────────────────────────────────
|
||||
def get_det_hodnoty(typ, rid, datum, jmeno_cel):
|
||||
"""Vrátí seznam hodnot pro řádek detailního listu."""
|
||||
if typ == 'Rec':
|
||||
d = rec_det.get(rid, ('', ''))
|
||||
return [datum, jmeno_cel, d[0] or '', d[1] or '']
|
||||
elif typ == 'VykA':
|
||||
d = vyka_det.get(rid, ('', ''))
|
||||
return [datum, jmeno_cel, d[0] or '', (d[1] or '').strip()]
|
||||
d = vyka_det.get(rid, ('', '', 0))
|
||||
return [datum, jmeno_cel, d[0] or '', (d[1] or '').strip(), d[2] or 0]
|
||||
elif typ == 'Files':
|
||||
d = files_det.get(rid, ('', ''))
|
||||
return [datum, jmeno_cel, d[0] or '', d[1]]
|
||||
@@ -208,21 +246,20 @@ def get_det_hodnoty(typ, rid, datum, jmeno_cel):
|
||||
return []
|
||||
|
||||
ZAROVNANI = {
|
||||
'Recepty': ['left','left','left','center'],
|
||||
'Výkony': ['left','left','center','center'],
|
||||
'Soubory': ['left','left','left','left'],
|
||||
'MedLab': ['left','left','center'],
|
||||
'Lab': ['left','left','center'],
|
||||
'Očkování': ['left','left','left','left'],
|
||||
'Neschop.': ['left','left','left','left'],
|
||||
'Léčiva': ['left','left','center','left'],
|
||||
'SpecVys': ['left','left','left','left'],
|
||||
'Platby': ['left','left','left','right','center'],
|
||||
'Ostatní': ['left','left','center','center','left'],
|
||||
'Recepty': ['left','left','left','center'],
|
||||
'Výkony': ['left','left','center','center','right'],
|
||||
'Soubory': ['left','left','left','left'],
|
||||
'Žádanky': ['left','left','center'],
|
||||
'Lab výsl.': ['left','left','center'],
|
||||
'Očkování': ['left','left','left','left'],
|
||||
'Neschop.': ['left','left','left','left'],
|
||||
'Léčiva': ['left','left','center','left'],
|
||||
'SpecVys': ['left','left','left','left'],
|
||||
'Platby': ['left','left','left','right','center'],
|
||||
'Ostatní': ['left','left','center','center','left'],
|
||||
}
|
||||
|
||||
for row_i, (datum, cas, zkratka, jmeno_cel, rodcis, poj, top, ostatni, ids_by_typ, ids_ostatni) in enumerate(rows, start=2):
|
||||
# Ohraničení řádku Dekurz
|
||||
for row_i, (datum, cas, zkratka, jmeno_cel, rodcis, poj, top, ostatni, ids_by_typ, ids_ostatni, text_dekurzu) in enumerate(rows, start=2):
|
||||
fill_d = r_fill[row_i % 2]
|
||||
for col_i in range(1, len(nazvy_d) + 1):
|
||||
ws_d.cell(row=row_i, column=col_i).fill = fill_d
|
||||
@@ -232,20 +269,30 @@ for row_i, (datum, cas, zkratka, jmeno_cel, rodcis, poj, top, ostatni, ids_by_ty
|
||||
ws_d.cell(row=row_i, column=2, value=str(cas)[:5] if cas else '').alignment = Alignment(horizontal='center')
|
||||
ws_d.cell(row=row_i, column=3, value=zkratka or '').alignment = Alignment(horizontal='center')
|
||||
ws_d.cell(row=row_i, column=4, value=jmeno_cel)
|
||||
ws_d.cell(row=row_i, column=5, value=rodcis or '')
|
||||
# Sloupec 5 – Rodné číslo jako hyperlink na list "Text dekurzu"
|
||||
hyperlink_cell(ws_d, row_i, 5, 'Text dekurzu', row_ptr_text, rodcis or '', 'DCE6F1')
|
||||
ws_d.cell(row=row_i, column=6, value=poj or '').alignment = Alignment(horizontal='center')
|
||||
|
||||
# Sloupce bookmarků
|
||||
# Sloupec G – HodVyk (součet bodů všech výkonů dekurzu)
|
||||
hodvyk = sum((vyka_det.get(rid, ('', '', 0))[2] or 0) for rid in ids_by_typ['VykA'])
|
||||
cell_hv = ws_d.cell(row=row_i, column=7, value=hodvyk if hodvyk else '')
|
||||
cell_hv.alignment = Alignment(horizontal='center')
|
||||
|
||||
for col_off, (typ, pocet) in enumerate(zip(TOP_TYPY, top)):
|
||||
col_i = 7 + col_off
|
||||
col_i = 8 + col_off
|
||||
if pocet == 0:
|
||||
continue
|
||||
# Najdi název listu pro tento typ
|
||||
nazev_listu = next((n for n, t, *_ in LISTY if t == typ), None)
|
||||
if nazev_listu and ids_by_typ[typ]:
|
||||
_, barva_ll = BARVY_LISTU[nazev_listu]
|
||||
hyperlink_cell(ws_d, row_i, col_i, nazev_listu, row_ptr[nazev_listu], pocet, barva_ll[1:] if len(barva_ll) > 6 else 'DCE6F1')
|
||||
# Zapiš řádky na detailní list
|
||||
# Pro výkony (VykA) přidej kódy do závorky
|
||||
if typ == 'VykA':
|
||||
kody = [str(vyka_det.get(rid, ('',))[0] or '').strip() for rid in ids_by_typ[typ]]
|
||||
kody_str = ', '.join(k for k in kody if k)
|
||||
display_text = f"{pocet} ({kody_str})" if kody_str else pocet
|
||||
else:
|
||||
display_text = pocet
|
||||
hyperlink_cell(ws_d, row_i, col_i, nazev_listu, row_ptr[nazev_listu], display_text, barva_ll[1:] if len(barva_ll) > 6 else 'DCE6F1')
|
||||
ws_det = ws_listy[nazev_listu]
|
||||
barva_hl, barva_r = BARVY_LISTU[nazev_listu]
|
||||
for rid in ids_by_typ[typ]:
|
||||
@@ -256,17 +303,32 @@ for row_i, (datum, cas, zkratka, jmeno_cel, rodcis, poj, top, ostatni, ids_by_ty
|
||||
else:
|
||||
ws_d.cell(row=row_i, column=col_i, value=pocet).alignment = Alignment(horizontal='center')
|
||||
|
||||
# Ostatní
|
||||
if ostatni:
|
||||
ws_det = ws_listy['Ostatní']
|
||||
barva_hl, barva_r = BARVY_LISTU['Ostatní']
|
||||
hyperlink_cell(ws_d, row_i, 17, 'Ostatní', row_ptr['Ostatní'], ostatni, barva_r)
|
||||
hyperlink_cell(ws_d, row_i, 18, 'Ostatní', row_ptr['Ostatní'], ostatni, barva_r)
|
||||
for typ, rid, nazev in ids_ostatni:
|
||||
zapis_radek(ws_det, row_ptr['Ostatní'],
|
||||
[datum, jmeno_cel, typ, rid, nazev],
|
||||
ZAROVNANI['Ostatní'], barva_r)
|
||||
row_ptr['Ostatní'] += 1
|
||||
|
||||
# Zápis do listu "Text dekurzu"
|
||||
fill_t = r_fill[row_ptr_text % 2]
|
||||
for col_i in range(1, 7):
|
||||
ws_text.cell(row=row_ptr_text, column=col_i).fill = fill_t
|
||||
ws_text.cell(row=row_ptr_text, column=col_i).border = ohraniceni
|
||||
c1 = ws_text.cell(row=row_ptr_text, column=1, value=datum)
|
||||
c1.number_format = 'DD.MM.YYYY'
|
||||
c1.alignment = Alignment(horizontal='left', vertical='center')
|
||||
ws_text.cell(row=row_ptr_text, column=2, value=str(cas)[:5] if cas else '').alignment = Alignment(horizontal='center', vertical='center')
|
||||
ws_text.cell(row=row_ptr_text, column=3, value=zkratka or '').alignment = Alignment(horizontal='center', vertical='center')
|
||||
ws_text.cell(row=row_ptr_text, column=4, value=jmeno_cel).alignment = Alignment(horizontal='left', vertical='center')
|
||||
ws_text.cell(row=row_ptr_text, column=5, value=rodcis or '').alignment = Alignment(horizontal='left', vertical='center')
|
||||
cell_txt = ws_text.cell(row=row_ptr_text, column=6, value=text_dekurzu)
|
||||
cell_txt.alignment = Alignment(horizontal='left', vertical='top', wrap_text=True)
|
||||
row_ptr_text += 1
|
||||
|
||||
# Autofiltr na detailních listech
|
||||
for nazev, *_ in LISTY:
|
||||
ws = ws_listy[nazev]
|
||||
|
||||
Reference in New Issue
Block a user