Problema El contexto
Un centro de distribución necesita saber cada día cuántas líneas de órdenes de traslado hay que preparar, cuánto valen y en qué estado están: pendientes, con entrega generada o ya trabajadas.
Esa información está repartida en 7 reportes de SAP, y la salida de uno es la entrada del siguiente. A mano implicaría ejecutar cada transacción, exportarla, copiar listas de un reporte a otro y cruzar todo en Excel con precios, unidades de medida y datos maestros.
No existía un reporte que cubriera todo el flujo. Un equipo del centro de distribución revisaba a mano solo las órdenes con entrega generada, una vez al día y en unos 30 minutos. El RPA sigue el flujo completo: orden de traslado → entrega → HU.
Solución Qué resolví
- El orquestador abre hasta 5 sesiones de SAP GUI y lanza un worker por transacción: primero los pedidos de la ventana de fechas y las entregas; con esa lista, el resto de reportes en paralelo.
- Polars lee los archivos TXT por posición de columna (los nombres cambian entre versiones de SAP) y convierte los tipos de forma explícita.
- Los datos se cargan en tablas de staging de MotherDuck dentro de una transacción.
- Si faltan días de ajuste o datos maestros, se descargan reportes complementarios de SAP.
- Una consulta SQL con CTEs genera la proyección operativa diaria: una fila por línea de pedido, con importe, fecha de entrega ajustada, gerencia y estado.
- Al terminar, Power Automate avisa en Microsoft Teams si el resultado fue correcto, parcial o con error.
- Streamlit consume la tabla final: KPIs, generado vs. pendiente, ritmo diario/semanal/mensual, brecha acumulada, desglose por gerencia y unidad de negocio, filtros y exportación a Excel.
El robot también se empaqueta como .exe con PyInstaller para ejecutarlo en equipos sin Python.
Arquitectura técnica
PC Windows · robot en Python
- OrquestadorUn subproceso por transacción: dependencias, tiempo máximo y reintento
- Workers · SAP GUIHasta 5 sesiones a la vez; cada worker usa la suya y exporta un TXT
- Lectores en PolarsTXT a DataFrame por posición, con tipos explícitos
Mutex de Windows: un solo robot usa SAP y un solo worker usa el portapapeles a la vez. Job de Windows: si el robot se detiene, sus workers también.
MotherDuck (DuckDB en la nube)
- Staging y maestrosPedidos de la ventana, unidades de medida, precios y datos maestros
- SQL con CTEsImporte, fecha de entrega ajustada y estado de cada línea
- Proyección finalUna fila por línea de pedido, validada contra staging
Consumo · Streamlit
- Dashboard ejecutivoKPIs, ritmo, brecha acumulada, desgloses y filtros
- Exportación a ExcelRango filtrado, hasta 500,000 filas
Avisos y control
- Estado correcto, parcial o con error → aviso en Microsoft Teams vía Power Automate.
- Código de salida: 0 (correcto o parcial), 1 (error), 2 (SAP ya en uso por otro robot).
- Si falla un reporte complementario, la carga continúa y el resultado queda como parcial.
Extracción en paralelo
Arrancan juntas
- Pedidos de la ventana de fechas
- Entregas
Con la lista de pedidos
- HU por pedido× 4
- Unidades de medida
- Precios
Solo si faltan datos
- Ajuste de fecha de entrega
- Maestro de materiales
La lista de pedidos se reparte en 4 partes contiguas y sin huecos, para que el reporte más pesado corra en 4 sesiones a la vez.
Resultados y validación Resultados y evidencia
−83%
tiempo por ejecución (de ~30 min a ~5 min)
Valores aproximados. La revisión manual solo cubría las órdenes con entrega; el RPA cubre todo el flujo.
1 → varias
ejecuciones al día
Por su duración, el proceso manual se hacía solo una vez al día; el RPA puede ejecutarse varias veces.
Valores aproximados, estimados a partir de la operación diaria.
Además, automatiza de punta a punta la descarga y el cruce de 7 reportes de SAP, y avisa del resultado sin que nadie tenga que revisarlo.
Uso actual: el dashboard lo usa la gerencia de Non Food y Supply Chain. A futuro lo verán las demás gerencias, a medida que se trabajen las lógicas que necesita cada una.
Decisiones técnicas Cómo pensé
- Descarté la macro de VBA: había que conocer el historial de cada pedido, y una base de datos es más adecuada que archivos Excel.
- Extracción en paralelo: cada transacción de SAP corre en un proceso independiente con su propia sesión de SAP GUI. Elegí procesos y no hilos porque SAP GUI Scripting usa COM; además, un proceso bloqueado se puede detener sin afectar a los demás.
- Un orquestador controla las dependencias entre reportes, el tiempo máximo por transacción y un reintento en otra sesión.
- Cargas idempotentes: se borra la ventana de fechas y se vuelve a insertar, o se insertan solo los registros nuevos. Reintentar no duplica datos.
- Una transacción por base de datos, con rollback si algo falla: nunca quedan tablas a medias.
- Separé una capa reutilizable (conexión a SAP, orquestación, cargas y avisos) del proceso concreto, para que un nuevo robot pueda aprovecharla sin modificarla.
- Los tokens de MotherDuck y Power Automate se leen desde un archivo .env, fuera del código y del repositorio.
- Elegí MotherDuck porque ya conocía DuckDB y, además de funcionar como almacén de datos, permite generar dashboards con Dives. Planeo profundizar en Flights.
Calidad de datos y pruebas
- 43 pruebas automatizadas que se ejecutan sin SAP (orquestador, candados y cargas). MotherDuck se reemplaza por una DuckDB local para probar todo el SQL.
- Validación final: si las filas de la proyección no coinciden con las de staging (señal de que un JOIN duplicó líneas), se revierte toda la carga.
- Cada TXT debe ser de la ejecución actual y no estar vacío; el archivo anterior se borra antes de descargar.
- INSERT … BY NAME: las columnas se emparejan por nombre, así un cambio de orden no guarda datos en la columna equivocada.
- Las fechas de la tabla principal se convierten en modo estricto: si una viene mal, el proceso falla antes de cargar datos incorrectos.
- El dashboard exige al menos una gerencia y una clase de documento, valida el rango de fechas y limita la exportación a 500,000 filas.
Estructura del código
comun/Herramientas reutilizables: configuración, logging, candados, transacciones en MotherDuck, avisos y lector de TXTcomun/sap/Conexión a SAP GUI, orquestador y workerprocesos/proyeccion_ot/El proceso concreto: configuración, transacciones, lectores, cargas SQL y flujo principaldashboards/proyeccion_ot/Dashboard en Streamlit: consultas, gráficos y componentes en módulos separadostests/Pruebas automatizadas sin SAPherramientas/Script para compilar el .exe con PyInstallerrequirements.txtDependencias del robot (el dashboard tiene las suyas)
Dependencias principales
Limitaciones y siguientes pasos
La extracción depende de SAP GUI en Windows, por lo que no es reproducible fuera del entorno de la empresa.
- La lectura por posición depende de que las variantes de SAP no cambien; por eso están protegidas.
- El portapapeles se comparte con el usuario: el equipo no debe usarse mientras el robot descarga.
- El historial crece sin límite; propongo una política de retención.
¿Quieres conversar sobre este proyecto?
Puedo explicar la arquitectura, las decisiones y las limitaciones en una entrevista.
Contactar por LinkedIn