La identificación manual de registros repetidos en hojas de cálculo representa una tarea propensa a errores humanos y consume tiempo valioso. Mediante el uso de Python junto a la biblioteca xlwings, es posible implementar un proceso automatizado que compare múltiples columnas por fila, identifique coincidencias bajo criterios específicos y aplique formato de resaltado directamente en el archivo original.
Instalación de dependencias
La interacción con la aplicación nativa de Excel requiere la instalación de la librería correspondiente mediante el gestor de paquetes estándar:
pip install xlwings
Lógica de implementación
El siguiente script extrae los valores de las columnas objetivo, evalúa condiciones compuestas para identificar duplicados y modifica el color de la primera celda en las filas afectadas. Se ha estructurado con un enfoque basado en diccionarios para optimizar el acceso a los datos y un conjunto para evitar comparaciones redundantes.
import xlwings as xw
import os
def analizar_duplicados(ruta_archivo):
"""
Procesa un archivo Excel, compara filas según criterios múltiples
y resalta visualmente las coincidencias en la columna A.
"""
app = xw.App(visible=False, add_book=False)
try:
libro = app.books.open(ruta_archivo)
hoja = libro.sheets[0]
limite_fila = hoja.used_range.last_cell.row
if limite_fila < 2:
print("El documento no contiene datos suficientes para procesar.")
return
# Mapeo estructurado de columnas (A, C, H, K, N)
registros = {
'identificador': [hoja.range(f"A{f}").value for f in range(2, limite_fila + 1)],
'tipo_gasto': [hoja.range(f"C{f}").value for f in range(2, limite_fila + 1)],
'departamento': [hoja.range(f"H{f}").value for f in range(2, limite_fila + 1)],
'monto': [hoja.range(f"K{f}").value for f in range(2, limite_fila + 1)],
'proveedor': [hoja.range(f"N{f}").value for f in range(2, limite_fila + 1)]
}
filas_procesadas = set()
cantidad = len(registros['monto'])
for idx in range(cantidad):
fila_idx = idx + 2
if fila_idx in filas_procesadas:
continue
base = {k: registros[k][idx] for k in registros}
for cmp_idx in range(idx + 1, cantidad):
fila_cmp = cmp_idx + 2
if fila_cmp in filas_procesadas:
continue
cmp = {k: registros[k][cmp_idx] for k in registros}
# Evaluación de criterios: monto y contexto coinciden, ID difiere
condicion_monto = (base['monto'] == cmp['monto'])
condicion_contexto = (
base['departamento'] == cmp['departamento'] and
base['tipo_gasto'] == cmp['tipo_gasto'] and
base['proveedor'] == cmp['proveedor']
)
condicion_id = (base['identificador'] != cmp['identificador'])
if condicion_monto and condicion_contexto and condicion_id:
hoja.range(f"A{fila_idx}").color = (0, 255, 255)
hoja.range(f"A{fila_cmp}").color = (0, 255, 255)
filas_procesadas.update({fila_idx, fila_cmp})
print(f"Coincidencia identificada: Filas {fila_idx} y {fila_cmp}")
libro.save()
finally:
libro.close()
app.quit()
if __name__ == "__main__":
entrada = input("Ruta del archivo Excel: ").strip().strip('"')
if os.path.isfile(entrada):
analizar_duplicados(entrada)
print("Ejecución completada.")
else:
print("No se encontró el archivo especificado.")
input("Presione una tecla para cerrar...")
Embalaje como binario independiente
Para entornos corporativos donde la instalación de entornos de desarrollo no es viable, pyinstaller permite compilar el script en un ejecutable portátil que incluye el intérprete y las dependencias necesarias.
Instalación del empaquetador:
pip install pyinstaller
Generación del ejecutable con configuración mínima:
pyinstaller --onefile --icon=aplicacion.ico script_revisión.py
El indicador --onefile consolida todos los componentes en un único archivo ejecutable, mientras que --icon asigna un recurso gráfico en formato .ico. La salida binaria se almacena en el directorio dist/ tras finlaizar la compilación.