Added all

This commit is contained in:
Guillem Hernandez Sola
2026-04-07 19:37:59 +02:00
commit da6dabcc62
42 changed files with 1959 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
#!/bin/bash
# Directorio base desde donde buscar (puedes cambiarlo o usar el argumento del script)
DIRECTORIO=${1:-.}
# Encuentra archivos mayores a 1GB y muestra su tamaño ordenado
echo "Archivos mayores a 1GB en el directorio: $DIRECTORIO"
find "$DIRECTORIO" -type f -size +1G -exec du -h {} + | sort -hr
echo "Búsqueda completada."

View File

@@ -0,0 +1,57 @@
import pandas as pd
import os
import sys
print("🔍 --- Filtrant Excel segons usuaris actius del CSV ---")
# Noms dels fitxers
fitxer_csv = "Newsletter_Combinat_Final_Actius.csv"
fitxer_excel = "Contactos_Unificats.xlsx"
fitxer_resultat = "Contactos_Unificats_Filtrats.xlsx"
# Comprovem que existeixen
if not os.path.exists(fitxer_csv) or not os.path.exists(fitxer_excel):
print("❌ Error: Assegura't que els fitxers CSV i Excel són a la mateixa carpeta.")
sys.exit(1)
try:
print("⏳ Llegint els usuaris actius del CSV...")
# Llegim el CSV (sabem que està separat per punt i coma)
df_csv = pd.read_csv(fitxer_csv, sep=';', encoding='utf-8')
# Extraiem els correus de la columna 'Email_ID', els passem a minúscules i traiem espais en blanc
# per assegurar-nos que coincideixen perfectament
correus_actius = set(df_csv['Email_ID'].dropna().astype(str).str.lower().str.strip())
print(f"✅ S'han carregat {len(correus_actius)} correus únics del CSV.")
print("⏳ Processant l'Excel pestanya per pestanya...")
# Obrim l'Excel original i preparem el nou per escriure
excel_original = pd.ExcelFile(fitxer_excel)
with pd.ExcelWriter(fitxer_resultat, engine='openpyxl') as writer:
for nom_pestanya in excel_original.sheet_names:
# Llegim la pestanya actual
df_pestanya = pd.read_excel(excel_original, sheet_name=nom_pestanya)
total_inicial = len(df_pestanya)
# Normalitzem la columna 'email' de l'Excel per poder comparar-la
if 'email' in df_pestanya.columns:
correus_excel = df_pestanya['email'].astype(str).str.lower().str.strip()
# Filtrem: ens quedem només amb les files on el correu estigui a la nostra llista d'actius
df_filtrat = df_pestanya[correus_excel.isin(correus_actius)]
total_final = len(df_filtrat)
print(f" 👉 Pestanya '{nom_pestanya}': s'han mantingut {total_final} de {total_inicial} contactes.")
else:
print(f" ⚠️ Avís: La pestanya '{nom_pestanya}' no té cap columna anomenada 'email'. Es deixa intacta.")
df_filtrat = df_pestanya
# Guardem el resultat a la mateixa pestanya del nou fitxer
df_filtrat.to_excel(writer, sheet_name=nom_pestanya, index=False)
print(f"\n🎉 Procés completat amb èxit!")
print(f"📄 S'ha creat el fitxer amb els contactes filtrats: {fitxer_resultat}")
except Exception as e:
print(f"❌ S'ha produït un error: {e}")

View File

@@ -0,0 +1,67 @@
import csv
import glob
import os
import sys
# 1. Comprovem si s'ha passat la ruta com a argument
if len(sys.argv) < 2:
print("❌ Error: Has d'indicar la ruta de la carpeta.")
print("💡 Ús correcte: python juntar_csv.py /ruta/de/la/carpeta")
sys.exit(1)
# 2. Agafem la ruta (el primer argument després del nom de l'script)
carpeta_origen = sys.argv[1]
# Netegem possibles cometes que la terminal hagi afegit
carpeta_origen = carpeta_origen.strip("'").strip('"').strip()
# 3. Comprovem que la carpeta existeix
if not os.path.isdir(carpeta_origen):
print(f"❌ Error: La ruta '{carpeta_origen}' no és vàlida o no és una carpeta.")
sys.exit(1)
print(f"📁 Cercant fitxers CSV a: {carpeta_origen}")
ruta_cerca = os.path.join(carpeta_origen, "*.csv")
fitxers_csv = glob.glob(ruta_cerca)
# Definim el nom del fitxer final
fitxer_resultat = os.path.join(carpeta_origen, "Newsletter_Combinat_Final.csv")
if not fitxers_csv:
print("⚠️ No s'han trobat fitxers CSV a la carpeta indicada.")
else:
# Filtrem per no incloure el fitxer resultat si ja existeix d'una execució anterior
fitxers_a_processar = [f for f in fitxers_csv if f != fitxer_resultat]
if not fitxers_a_processar:
print("⚠️ Només s'ha trobat el fitxer combinat anterior. No hi ha res de nou per unir.")
sys.exit(0)
print(f"🔄 S'han trobat {len(fitxers_a_processar)} fitxers. Processant...")
# 4. Unifiquem els fitxers
with open(fitxer_resultat, 'w', newline='', encoding='utf-8') as sortida:
escrivent = csv.writer(sortida, delimiter=';')
fitxers_processats = 0
for nom_fitxer in fitxers_a_processar:
with open(nom_fitxer, 'r', encoding='utf-8') as f:
lector = csv.reader(f, delimiter=';')
try:
capcalera = next(lector)
except StopIteration:
continue # Saltem el fitxer si està completament buit
# Escrivim la capçalera només pel primer fitxer vàlid
if fitxers_processats == 0:
escrivent.writerow(capcalera)
# Escrivim la resta de dades
for fila in lector:
escrivent.writerow(fila)
fitxers_processats += 1
print(f"✅ Èxit! S'han combinat {fitxers_processats} fitxers.")
print(f"📄 Fitxer creat a: {fitxer_resultat}")

73
file-management/mautic.py Normal file
View File

@@ -0,0 +1,73 @@
import pandas as pd
import csv
def filtrar_i_consolidar_etiquetes(tags_str):
"""Filtra i agrupa les etiquetes segons les regles de negoci."""
if pd.isna(tags_str) or str(tags_str).strip().lower() == 'nan':
return ''
# 1. Separem les etiquetes i les netegem
llista_tags = [t.strip().lower() for t in str(tags_str).split(',')]
# Utilitzem un 'set' per evitar etiquetes duplicades al final
tags_finals = set()
for t in llista_tags:
# 2. Regla de conservació directa: test_, int_ i rrhh
if t.startswith('test_') or t.startswith('int_') or t == 'rrhh':
tags_finals.add(t)
continue
# 3. Regles d'agrupació (l'ordre és important per als prefixos llargs)
if t.startswith('skupspo2-') or t.startswith('pspo2-'):
tags_finals.add('pspo2')
elif t.startswith('pspo-'):
tags_finals.add('pspo')
elif t.startswith('psm2-'):
tags_finals.add('psm2')
elif t.startswith('psm-'):
tags_finals.add('psm')
elif t.startswith('psux-') or t.startswith('psu-'):
tags_finals.add('psu')
elif t.startswith('sps-'):
tags_finals.add('sps')
elif t.startswith('safe-'):
tags_finals.add('safe-ls')
elif t.startswith('pal_ebm-'):
tags_finals.add('pal_ebm')
elif t.startswith('pal-'):
tags_finals.add('pal')
# 4. Si tenim etiquetes vàlides, les ordenem, les unim amb | i hi posem cometes
if tags_finals:
# Ordenar-les (sorted) fa que el resultat sigui més fàcil de llegir al CSV
tags_units = '|'.join(sorted(list(tags_finals)))
return f'"{tags_units}"'
else:
return ''
# --- INICI DEL PROCÉS ---
# 1. Carregar el fitxer original
df = pd.read_excel('contactes_mautic/Contactos_2602026_7881pax.xlsx')
# 2. Seleccionar només les columnes que ens interessen
columnes_mautic = ['email', 'nombre_x', 'apellidos_x', '*ciudad_x', '*pais_x', 'etiquetas_x']
df_net = df[columnes_mautic].copy()
# 3. Reanomenar les columnes perquè Mautic les auto-detecti
df_net.rename(columns={
'nombre_x': 'firstname',
'apellidos_x': 'lastname',
'*ciudad_x': 'city',
'*pais_x': 'country',
'etiquetas_x': 'etiquetes'
}, inplace=True)
# 4. APLICAR EL FILTRE I LA CONSOLIDACIÓ
df_net['etiquetes'] = df_net['etiquetes'].apply(filtrar_i_consolidar_etiquetes)
# 5. Guardar com a CSV llest per importar
df_net.to_csv('Contactes_Mautic_Consolidats.csv', index=False, encoding='utf-8', quoting=csv.QUOTE_NONE, escapechar='\\')
print("✅ Fitxer preparat! Les etiquetes s'han filtrat i agrupat correctament.")

View File

@@ -0,0 +1,84 @@
import pandas as pd
import os
import csv
def simplificar_etiqueta(tag):
"""Filtra i redueix les etiquetes a la seva essència."""
tag = tag.strip().lower()
# 1. Traducció dels noms llargs oficials
if 'professional-scrum-master' in tag: return 'psm'
if 'professional-scrum-product-owner' in tag: return 'pspo'
if 'professional-scrum-developer' in tag: return 'psd'
if 'professional-agile-leadership' in tag: return 'pal'
# 2. Protecció de nivells avançats (Molt important posar-ho abans que els normals)
if 'psm2' in tag or 'psm-2' in tag: return 'psm2'
if 'pspo2' in tag or 'pspo-2' in tag: return 'pspo2'
if 'pspo-a' in tag: return 'pspo-a'
# 3. Agrupació per paraula clau (Si conté la paraula, s'assigna a l'etiqueta base)
if 'psm' in tag: return 'psm'
if 'pspo' in tag: return 'pspo'
if 'psu' in tag: return 'psu'
if 'psd' in tag: return 'psd'
if 'aps' in tag: return 'aps'
if 'apk' in tag: return 'apk'
if 'pal' in tag: return 'pal'
if 'sps' in tag: return 'sps'
# 4. Altres agrupacions útils que he detectat a la teva llista
if 'okr' in tag: return 'okr'
if 'scrumday' in tag or 'sd20' in tag or 'sd21' in tag: return 'scrumday'
# 5. Si no és cap de les importants, la deixem tal qual (però neta de test_)
if tag.startswith('test_'):
return tag.replace('test_', 'int_', 1)
return tag
# --- INICI DEL PROCÉS ---
nom_fitxer = 'contactes_mautic/Contactos_2602026_7881pax.xlsx'
print(f"Llegint el fitxer {nom_fitxer}...")
df = pd.read_excel(nom_fitxer)
columnes = {
'email': 'email',
'nombre_x': 'firstname',
'apellidos_x': 'lastname',
'*ciudad_x': 'city',
'*pais_x': 'country',
'etiquetas_x': 'tags'
}
df_net = df[list(columnes.keys())].rename(columns=columnes)
df_net = df_net.dropna(subset=['email', 'tags'])
carpeta_sortida = 'Mautic_CSVs_per_Tag'
os.makedirs(carpeta_sortida, exist_ok=True)
# Apliquem la nostra súper funció de simplificació
df_net['tag_individual'] = df_net['tags'].apply(
lambda x: [simplificar_etiqueta(tag) for tag in str(x).split(',') if tag.strip()]
)
# Expandim i eliminem duplicats
df_exploded = df_net.explode('tag_individual')
df_exploded = df_exploded.drop_duplicates(subset=['email', 'tag_individual'])
etiquetes_uniques = df_exploded['tag_individual'].unique()
print(f"🎉 Màgia feta! Hem reduït centenars d'etiquetes a només {len(etiquetes_uniques)} úniques.")
for tag in etiquetes_uniques:
df_tag = df_exploded[df_exploded['tag_individual'] == tag].copy()
df_tag['tags'] = tag
df_tag = df_tag.rename(columns={'tags': tag})
df_tag = df_tag.drop(columns=['tag_individual'])
nom_tag_net = str(tag).replace(' ', '_').replace('/', '_').replace(':', '')
ruta_fitxer = os.path.join(carpeta_sortida, f"etiqueta_{nom_tag_net}.csv")
df_tag.to_csv(ruta_fitxer, index=False, encoding='utf-8', sep=',', quoting=csv.QUOTE_ALL)
print(f"✅ Tots els fitxers nets estan a la carpeta '{carpeta_sortida}'.")

View File

@@ -0,0 +1,17 @@
import pandas as pd
# 1. Carregar el fitxer original
df = pd.read_excel('contactes_mautic/Contactos_2602026_7881pax.xlsx')
# 2. Quedar-nos només amb els emails vàlids
df_net = df.dropna(subset=['email'])[['email']].copy()
# 3. Ordre d'esborrat múltiple
# Afegim el signe '-' davant de l'etiqueta estranya i també del 'nan' normal
# La 'r' al davant indica a Python que llegeixi les barres invertides literalment
df_net['etiquetes'] = r'-\"-nan\"|-nan'
# 4. Guardem el CSV de manera natural (sense forçar paràmetres d'escapament)
df_net.to_csv('Neteja_Definitiva_Tags.csv', index=False, encoding='utf-8')
print("✅ Fitxer preparat! Les etiquetes errònies s'han marcat per ser esborrades.")

View File

@@ -0,0 +1,53 @@
import csv
import sys
import os
# Comprovem que s'ha passat el fitxer com a argument
if len(sys.argv) < 2:
print("❌ Error: Has d'indicar la ruta del fitxer CSV.")
print("💡 Ús correcte: python netejar_desuscrits.py /ruta/al/Newsletter_Combinat_Final.csv")
sys.exit(1)
fitxer_origen = sys.argv[1].strip("'").strip('"').strip()
if not os.path.isfile(fitxer_origen):
print(f"❌ Error: No s'ha trobat el fitxer '{fitxer_origen}'.")
sys.exit(1)
fitxer_desti = fitxer_origen.replace(".csv", "_Actius.csv")
usuaris_eliminats = 0
usuaris_actius = 0
print(f"🔍 Analitzant el fitxer: {fitxer_origen}")
with open(fitxer_origen, 'r', encoding='utf-8') as f_in, \
open(fitxer_desti, 'w', newline='', encoding='utf-8') as f_out:
lector = csv.reader(f_in, delimiter=';')
escrivent = csv.writer(f_out, delimiter=';')
# Llegim i escrivim la capçalera
capcalera = next(lector)
escrivent.writerow(capcalera)
# Busquem l'índex de la columna de desuscripció
try:
index_unsub = capcalera.index("Unsubscribe_Date")
except ValueError:
print("❌ Error: No s'ha trobat la columna 'Unsubscribe_Date' al fitxer.")
sys.exit(1)
# Filtrem les files
for fila in lector:
# Si la columna està buida, l'usuari és actiu
if len(fila) > index_unsub and not fila[index_unsub].strip():
escrivent.writerow(fila)
usuaris_actius += 1
else:
usuaris_eliminats += 1
print("✅ Neteja completada amb èxit!")
print(f"📉 Usuaris desuscrits eliminats: {usuaris_eliminats}")
print(f"📈 Usuaris actius conservats: {usuaris_actius}")
print(f"📄 Nou fitxer creat a: {fitxer_desti}")

View File

@@ -0,0 +1,32 @@
import pandas as pd
# 1. Definir los nombres de los archivos
archivo_entrada = 'Contactos_2602026_totales.xlsx'
archivo_salida = 'Contactos_2602026_Limpios.xlsx'
print(f"Cargando el archivo: {archivo_entrada}...")
# 2. Leer el archivo Excel
# Asumimos que los datos están en la primera hoja (Sheet1)
df = pd.read_excel(archivo_entrada)
# Contar cuántos registros hay inicialmente
total_inicial = len(df)
print(f"Registros iniciales encontrados: {total_inicial}")
# 3. Eliminar duplicados basados en la columna 'email'
# keep='first' conserva la primera aparición del correo y elimina las siguientes
df_limpio = df.drop_duplicates(subset=['email'], keep='first')
# Contar cuántos registros quedaron y cuántos se eliminaron
total_final = len(df_limpio)
duplicados_eliminados = total_inicial - total_final
print(f"Se han eliminado {duplicados_eliminados} contactos duplicados.")
print(f"Registros finales únicos: {total_final}")
# 4. Exportar el resultado a un nuevo archivo Excel
print("Guardando el nuevo archivo limpio...")
df_limpio.to_excel(archivo_salida, index=False)
print(f"¡Proceso completado! Archivo guardado como: {archivo_salida}")

View File

@@ -0,0 +1,46 @@
import pandas as pd
import numpy as np
import math
# Load the Excel file
file_name = 'Contactos_2602026_7881pax.xlsx'
print("Llegint el fitxer Excel...")
# --- CORRECCIÓ AQUÍ ---
# Fem servir read_excel en lloc de read_csv
df = pd.read_excel(file_name)
# ----------------------
# Display head and info to understand the structure
print(df.head())
print(df.info())
# Total number of rows
total_rows = len(df)
print(f"Total rows: {total_rows}")
# Number of splits
n = 6
# Fem servir math.ceil o np.ceil per assegurar que no deixem files fora
chunk_size = int(np.ceil(total_rows / n))
# Split and save
output_files = []
print(f"Dividint en {n} parts...")
for i in range(n):
start_row = i * chunk_size
end_row = min((i + 1) * chunk_size, total_rows)
# Si per algun motiu start_row supera el total, parem
if start_row >= total_rows:
break
chunk = df.iloc[start_row:end_row]
output_filename = f'Contactos_linkedin_part_{i+1}.xlsx'
chunk.to_excel(output_filename, index=False)
output_files.append(output_filename)
print(f"Files created: {output_files}")

104
file-management/teams.py Normal file
View File

@@ -0,0 +1,104 @@
import pandas as pd
import glob
import re
import os
import csv
def extreure_minuts(temps_str):
"""Converteix cadenes de text com '2h 15m', '45m' o '1h' a minuts totals."""
if pd.isna(temps_str):
return 0
temps_str = str(temps_str).lower()
hores = 0
minuts = 0
match_h = re.search(r'(\d+)\s*h', temps_str)
if match_h:
hores = int(match_h.group(1))
match_m = re.search(r'(\d+)\s*m', temps_str)
if match_m:
minuts = int(match_m.group(1))
return (hores * 60) + minuts
fitxers = glob.glob("*.csv")
dades_alumnes = {}
if not fitxers:
print("⚠️ No s'han trobat fitxers CSV a la carpeta actual.")
else:
print(f"S'han trobat {len(fitxers)} fitxers. Processant dades...\n")
for fitxer in fitxers:
try:
# 1. Obrim el fitxer manualment per buscar a quina fila comencen les dades
with open(fitxer, 'r', encoding='utf-16') as f:
linies = f.readlines()
fila_capcalera = -1
separador = '\t'
# Busquem la línia que conté "Nom" o "Nombre" o "Name"
for i, linia in enumerate(linies):
if 'Nom' in linia or 'Nombre' in linia or 'Name' in linia:
fila_capcalera = i
# Detectem si fa servir tabulacions o comes
if ',' in linia and '\t' not in linia:
separador = ','
break
if fila_capcalera == -1:
print(f"⚠️ Saltant '{fitxer}': No s'ha trobat cap fila amb la paraula 'Nom'.")
continue
# 2. Llegim el CSV dient-li exactament on comença
df = pd.read_csv(fitxer, sep=separador, encoding='utf-16', skiprows=fila_capcalera)
# 3. Busquem les columnes dinàmicament
col_durada = next((col for col in df.columns if 'durada' in col.lower() or 'duración' in col.lower() or 'duration' in col.lower()), None)
col_nom = next((col for col in df.columns if 'nom' in col.lower() or 'nombre' in col.lower() or 'name' in col.lower()), None)
if not col_nom or not col_durada:
print(f"⚠️ Saltant '{fitxer}': Columnes invàlides. Trobades: {list(df.columns)}")
continue
for index, row in df.iterrows():
nom = row[col_nom]
if pd.isna(nom):
continue
minuts = extreure_minuts(row[col_durada])
# Apliquem la regla del 5 de febrer (límit de 205 minuts)
if "2-05-26" in fitxer and minuts > 205:
minuts = 205
if nom in dades_alumnes:
dades_alumnes[nom] += minuts
else:
dades_alumnes[nom] = minuts
except UnicodeError:
print(f"❌ Error de codificació al fitxer '{fitxer}'. Intenta obrir-lo i guardar-lo de nou.")
except Exception as e:
print(f"❌ Error processant el fitxer '{fitxer}': {e}")
# 4. Resultats
if dades_alumnes:
print("="*50)
print("📊 RESULTATS D'ASSISTÈNCIA (Mínim requerit: 1581 min)")
print("="*50)
for nom in sorted(dades_alumnes.keys()):
minuts_totals = dades_alumnes[nom]
if minuts_totals >= 1581:
estat = "✅ Supera el 80%"
else:
estat = "❌ No arriba"
h = minuts_totals // 60
m = minuts_totals % 60
print(f"{nom}: {minuts_totals} minuts ({h}h {m}m) -> {estat}")

View File

@@ -0,0 +1,40 @@
import pandas as pd
import csv
def preparar_etiquetes_per_esborrar(tags_str):
"""Afegeix un '-' a cada etiqueta, les uneix amb | i les tanca entre cometes."""
# 1. Si la cel·la està buida, la deixem en blanc
if pd.isna(tags_str) or str(tags_str).strip().lower() == 'nan':
return ''
# 2. Separem les etiquetes originals per coma i traiem espais
llista_tags = [t.strip() for t in str(tags_str).split(',')]
# 3. Afegim el signe '-' davant de CADA etiqueta (excepte si està buida)
tags_per_esborrar = [f"-{t}" for t in llista_tags if t]
# 4. Les unim amb | i hi afegim les cometes dobles manualment
if tags_per_esborrar:
tags_units = '|'.join(tags_per_esborrar)
return f'"{tags_units}"'
else:
return ''
# --- INICI DEL PROCÉS ---
# 1. Carregar el fitxer original
df = pd.read_excel('contactes_mautic/Contactos_2602026_7881pax.xlsx')
# 2. Seleccionar només l'email i les etiquetes
df_esborrar = df[['email', 'etiquetas_x']].copy()
# 3. Reanomenar la columna
df_esborrar.rename(columns={'etiquetas_x': 'etiquetes'}, inplace=True)
# 4. APLICAR LA TRANSFORMACIÓ
df_esborrar['etiquetes'] = df_esborrar['etiquetes'].apply(preparar_etiquetes_per_esborrar)
# 5. Guardar el CSV respectant les nostres cometes literals
df_esborrar.to_csv('Contactes_Mautic_Esborrar_Etiquetes.csv', index=False, encoding='utf-8', quoting=csv.QUOTE_NONE, escapechar='\\')
print("✅ Fitxer preparat! Les etiquetes tenen el '-' i estan entre cometes dobles.")

View File

@@ -0,0 +1,19 @@
import pandas as pd
# 1. Cargar el primer archivo (tiene encabezados)
df1 = pd.read_excel('Contactos_linkedin_120126_agile_6589pax_filtrado.xlsx')
# 2. Cargar el segundo archivo (sin encabezados, asignamos los principales)
# Asumimos que las primeras 3 columnas son email, apellidos y nombre
df2 = pd.read_excel('lista_contactos_brevo_20251023_1394pax_AGILE611.xlsx', header=None)
df2.rename(columns={0: 'email', 1: 'apellidos_x', 2: 'nombre_x'}, inplace=True)
# 3. Unir ambos archivos (apilarlos uno debajo del otro)
df_final = pd.concat([df1, df2], ignore_index=True)
# 4. Eliminar contactos duplicados basados en la columna 'email'
df_final.drop_duplicates(subset=['email'], keep='first', inplace=True)
# 5. Exportar el resultado a un nuevo archivo Excel
df_final.to_excel('Contactos_Unificados_Agile611.xlsx', index=False)
print("¡Archivo unificado creado con éxito!")

View File

@@ -0,0 +1,40 @@
import pandas as pd
import os
import sys
print("📊 --- Unificador de fitxers Excel ---")
# Definim els noms dels fitxers d'entrada i el de sortida
fitxer1 = "Contactos_rrhh_040226.xlsx"
fitxer2 = "Contactos_2602026_7881pax.xlsx"
fitxer_resultat = "Contactos_Unificats.xlsx"
# Comprovem que els fitxers existeixen a la carpeta actual
if not os.path.exists(fitxer1):
print(f"❌ Error: No s'ha trobat el fitxer '{fitxer1}'.")
sys.exit(1)
if not os.path.exists(fitxer2):
print(f"❌ Error: No s'ha trobat el fitxer '{fitxer2}'.")
sys.exit(1)
print("⏳ Llegint els fitxers... (això pot trigar uns segons depenent de la mida)")
try:
# Llegim els dos fitxers Excel
df1 = pd.read_excel(fitxer1)
df2 = pd.read_excel(fitxer2)
# Creem el nou fitxer Excel amb múltiples pestanyes
with pd.ExcelWriter(fitxer_resultat, engine='openpyxl') as writer:
# Escrivim cada DataFrame en una pestanya diferent
df1.to_excel(writer, sheet_name='RRHH', index=False)
df2.to_excel(writer, sheet_name='Contactos_7881', index=False)
print(f"✅ Procés completat amb èxit!")
print(f"📄 S'ha creat el fitxer: {fitxer_resultat}")
print(" - Pestanya 1: 'RRHH'")
print(" - Pestanya 2: 'Contactos_7881'")
except Exception as e:
print(f"❌ S'ha produït un error durant el procés: {e}")