import pandas as pd import os import re import logging from manejoArchivos import select_file def es_columna_tipo_xxYY(columna): # Verificar si la columna es del tipo "xx-YY" usando una expresión regular return bool(re.match(r'^[a-z]{2}-[A-Z]{2}$', columna)) def sustituir_digitos(celda): # Convertir a cadena y sustituir secuencias de dígitos por [[digits]] if pd.isnull(celda): return celda, [] digitos = re.findall(r'\d+', str(celda)) celda_sustituida = re.sub(r'\d+', '[[digits]]', str(celda)) return celda_sustituida, digitos def preprocesar_update(df_update): # Diccionario para almacenar los dígitos reemplazados por fila digitos_reemplazados = {} # Iterar sobre las filas del DataFrame de actualización for index, fila in df_update.iterrows(): clave_original = str(fila['it-IT']) clave_sustituida, digitos = sustituir_digitos(clave_original) digitos_reemplazados[index] = digitos df_update.at[index, 'it-IT_preprocessed'] = clave_sustituida # Agregar una columna preprocesada return df_update, digitos_reemplazados def configurar_logger(ruta_log): logger = logging.getLogger('actualizacion_logger') logger.setLevel(logging.INFO) fh = logging.FileHandler(ruta_log, encoding='utf-8') fh.setLevel(logging.INFO) formatter = logging.Formatter('%(asctime)s - %(message)s') fh.setFormatter(formatter) logger.addHandler(fh) return logger def update_from_master(archivo_maestro, archivo_to_update): if not os.path.exists(archivo_maestro): print("El archivo maestro no existe.") return df_maestro = pd.read_excel(archivo_maestro) df_to_update = pd.read_excel(archivo_to_update) # Configurar el logger directorio = os.path.dirname(archivo_to_update) nombre_log = os.path.join(directorio, 'actualizacion.log') logger = configurar_logger(nombre_log) # Preprocesar el archivo de actualización df_to_update, digitos_reemplazados = preprocesar_update(df_to_update) # Obtener las claves del archivo maestro claves_maestro = set(df_maestro["it-IT"].dropna().astype(str)) # Iterar sobre las filas del archivo de actualización para actualizarlas for index, fila in df_to_update.iterrows(): clave_preprocesada = str(fila['it-IT_preprocessed']) if clave_preprocesada in claves_maestro: # Obtener los dígitos originales para esta fila digitos = digitos_reemplazados.get(index, []) df_maestro_fila = df_maestro[df_maestro['it-IT'] == clave_preprocesada].iloc[0] # Verificar que la cantidad de dígitos coincida con la cantidad de [[digits]] en la clave cantidad_digits = clave_preprocesada.count('[[digits]]') if len(digitos) != cantidad_digits: logger.info(f'Fila {index}: no se actualiza porque la cantidad de dígitos no coincide.') continue # Actualizar solo las columnas que existen en df_to_update y que no sean 'it-IT' for columna in df_to_update.columns: if columna != 'it-IT' and columna != 'it-IT_preprocessed' and columna in df_maestro.columns: valor = df_maestro_fila[columna] # Convertir a cadena si no lo es y reemplazar [[digits]] con los dígitos originales if not pd.isnull(valor): valor_original = str(valor) valor_actualizado = valor_original for d in digitos: valor_actualizado = valor_actualizado.replace('[[digits]]', d, 1) # Solo actualizar si el valor ha cambiado if str(fila[columna]) != valor_actualizado: df_to_update.at[index, columna] = valor_actualizado # Registrar el cambio logger.info(f'Fila {index}, Columna {columna}: "{fila[columna]}" actualizado a "{valor_actualizado}"') # Eliminar la columna preprocesada df_to_update.drop(columns=['it-IT_preprocessed'], inplace=True) # Guardar el archivo actualizado df_to_update.to_excel(archivo_to_update, index=False) print(f"Se han actualizado las filas en {archivo_to_update} desde el archivo maestro. Detalles de los cambios en {nombre_log}") if __name__ == "__main__": archivo_maestro = "hmi_master_translates.xlsx" archivo_to_update = select_file("xlsx") if archivo_to_update: update_from_master(archivo_maestro, archivo_to_update)