Suena el pager, el panel está en rojo y la pregunta ejecutiva llega a tu bandeja con la sutileza de un ladrillo: “¿Por qué estamos pagando dinero negativo a clientes?”
Rastreas la “tubería de datos” y descubres que la última milla no es Kafka ni Snowflake. Es una hoja final_FINAL_reallyfinal_v7.xlsx en el escritorio de alguien, exportada a CSV los viernes y luego subida manualmente a producción. Lo aterrador no es que esto exista. Lo aterrador es que funciona—hasta que deja de hacerlo.
Por qué Excel sigue ganando (incluso en 2026)
Excel es la plataforma de programación para usuarios finales más exitosa jamás lanzada. No porque sea “fácil”, sino porque está disponible, permite iterar rápido y deja que los expertos de dominio actúen sin esperar la capacidad de ingeniería. Una hoja de cálculo es una interfaz de usuario, un almacén de datos, un motor de cálculo y un generador de informes. En un solo archivo. Con copiar/pegar.
También por eso es peligrosa. Colapsa las barreras en las que confían los sistemas de producción: control de versiones, esquemas tipados, compilaciones deterministas, controles de acceso, entornos reproducibles, pruebas automatizadas y propiedad clara. La superpotencia de Excel es que elude la gobernanza por ser “solo un archivo”.
En términos SRE, las hojas de cálculo se convierten en producción cuando:
- Son la fuente de la verdad para decisiones que afectan a clientes (precios, elegibilidad, pagos, inventario).
- Están en la ruta crítica (ejecución semanal de facturación, cierre de fin de mes, informes de cumplimiento).
- No tienen un SLO documentado pero sin duda arruinarán tu semana si están equivocadas.
- Tienen dos responsables (significa: ninguno).
La gente no usa Excel porque sea imprudente. Lo usa porque es el camino más corto de la pregunta a la respuesta. Tu trabajo es evitar que ese camino vaya al precipicio.
Una cita para tener en el escritorio
Werner Vogels, hablando sobre fiabilidad a escala, lo puso sin rodeos: “Todo falla, todo el tiempo.”
Traduce eso a la realidad de las hojas de cálculo: todo se corrompe, todo el tiempo. No siempre de forma ruidosa. A veces como un cambio silencioso de formato que convierte identificadores en notación científica y arruina tus claves de unión.
Broma #1: Excel es una base de datos maravillosa siempre que tu base de datos necesite exactamente un usuario, una tabla y una crisis nerviosa.
Hechos e historia: cómo llegamos aquí
El horror de Excel no es nuevo. Lo que es nuevo es cuántos sistemas modernos todavía terminan en él. Aquí hay hechos concretos y puntos de contexto que explican por qué las hojas de cálculo siguen apareciendo en lugares serios:
- VisiCalc (1979) suele acreditarse como la “killer app” que vendió los primeros ordenadores personales a empresas—las hojas de cálculo fueron fundamentales, no una característica secundaria.
- Excel debutó en 1985 (primero para Macintosh), y rápidamente se convirtió en el estándar para el modelado empresarial porque combinaba cálculo con una interfaz de cuadrícula flexible.
- Excel introdujo las tablas dinámicas en los 1990s, haciendo el análisis ad-hoc accesible a no programadores—genial para obtener insights, terrible para la gobernanza.
- Los lenguajes de macro de las hojas (como VBA) convirtieron archivos en programas ejecutables con prácticas de despliegue débiles: copias el archivo y ya has desplegado código.
- CSV se convirtió en el intercambio universal no porque sea bueno, sino porque está en todas partes; Excel hizo que CSV pareciera “estándar” incluso cuando las comillas y las codificaciones no lo son.
- La inferencia automática de tipos de Excel (fechas, números, notación científica) es una elección de diseño optimizada para conveniencia interactiva, no para integridad de datos.
- Los límites de filas importaron históricamente (65.536 filas en versiones antiguas); la gente aprendió a dividir datos en varias hojas/archivos y luego unirlos manualmente.
- Industrias reguladas adoptaron hojas de cálculo porque los equipos de auditoría podían “ver” la lógica en una hoja; la visibilidad reemplazó a la corrección como control percibido.
- Las exportaciones modernas de SaaS siguen siendo “primero Excel” porque los interesados quieren descargas que abran en Excel, no en un notebook o herramienta BI.
Si intentas erradicar Excel de tu organización, empieza reconociendo una verdad dura: Excel no es una herramienta; es un tratado entre ingeniería y negocio. Rompe ese tratado sin ofrecer una alternativa y solo lo empujarás bajo tierra.
Los verdaderos modos de fallo: no es “error humano”, sino comportamiento predecible del sistema
Cuando un incidente se culpa a “alguien editó una hoja”, suele ser porque nadie quiso describir el sistema honestamente. El sistema es: flujos de trabajo manuales, esquemas implícitos, exportaciones frágiles y aprobaciones hechas por impresiones.
1) Coerción silenciosa de tipos (Excel te “ayuda”)
Excel adivina. Adivina agresivamente. Adivina mal de formas que parecen correctas.
- IDs numéricos largos se vuelven notación científica; los ceros a la izquierda desaparecen.
- Cadenas que parecen fechas se convierten en fechas reales; “03-04” puede ser 3 de abril o 4 de marzo según la configuración regional.
- Enteros grandes pierden precisión cuando se tratan como punto flotante.
Resultado operativo: fallan las uniones, falla la desduplicación y aparecen “registros faltantes” en sistemas aguas abajo. No recibes una excepción; recibes dinero incorrecto.
2) Esquemas implícitos y deriva de columnas
Las hojas invitan a la deriva de columnas: alguien inserta una columna para “Notas”, otro renombra “SKU” a “Sku”, alguien fusiona celdas para “hacerlo bonito”. A la herramienta downstream no le importa que esté bonito. Le importa que la columna 7 solía ser price.
3) La cadena de suministro copy/paste
La “tubería” más común es: exportar → pegar en otro libro → filtrar → copiar filas visibles → pegar valores → exportar. En cada paso puedes perder filas, reordenarlas, conservar fórmulas obsoletas o exportar solo lo que está visible.
Filtrar es especialmente brutal: crea un estado de UI que no es obvio en la salida exportada. Tu “conjunto de datos completo” podría ser “lo que estaba visible cuando exportaste”.
4) Concurrencia sin bloqueos
Los archivos no se fusionan limpiamente. La gente manda adjuntos por email. Mantienen dos versiones abiertas. Hacen “guardar como” para resolver conflictos. Esto es sistemas distribuidos sin ninguna de las partes divertidas.
5) Macros y enlaces externos: el grafo de dependencias oculto
Libros que referencian otros libros, recursos compartidos de red o fuentes ODBC se comportan como programas con dependencias en tiempo de ejecución. Un cambio de permisos en un share o una carpeta movida puede romper la lógica silenciosamente. A veces “se arregla” solo porque se usa un valor en caché, lo cual es peor.
6) Hoja-de-cálculo-como-base-de-datos: precipicios de rendimiento
La gente ordena 200k filas, usa fórmulas volátiles y se pregunta por qué Excel se congela. Luego “optimiza” dividiendo el archivo, lo que crea problemas de reconciliación. O desactiva el cálculo, lo que crea totales obsoletos. O exporta a CSV e importa en otra cosa, lo que introduce problemas de codificación y comillas.
Broma #2: Una hoja de cálculo es solo un programa donde cada variable se llama “Columna F” y cada informe de bug empieza con “Antes sí funcionaba”.
Tres microhistorias corporativas desde el frente de las hojas de cálculo
Microhistoria #1: El incidente causado por una suposición errónea
En una empresa mediana, el equipo de precios mantenía una hoja que generaba niveles de descuento para renovaciones empresariales. Sales ops exportaba la hoja semanalmente a CSV y la subía a una herramienta administrativa interna, que empujaba los niveles a un servicio de precios. El flujo era antiguo, aburrido y todos asumían que estaba “bien”.
Se lanzó una nueva región. Alguien añadió una columna llamada Region e insertó cerca del inicio para mantener la hoja “legible”. La exportación seguía produciendo un CSV, la subida seguía dando éxito y la herramienta administrativa seguía mostrando un verde “Import complete.” El importador era posicional, no basado en cabeceras. Trató la nueva columna como CustomerSegment, desplazando todo por uno.
El servicio de precios no se cayó. Aceptó basura alegremente. De pronto, ciertos clientes recibieron descuentos destinados a otro segmento, mientras otros perdieron sus niveles negociados. El on-call recibió paginaciones por “caída de conversión” y “aumento de tickets”, no por una falla de integridad de datos.
La causa raíz no fue “alguien añadió una columna”. La suposición errónea fue pensar que un trabajo de importación que dice “completo” significa “correcto”, y que los humanos nunca reorganizarían una hoja. La solución tampoco fue “decirle a la gente que pare”. Cambiaron el importador para que coincidiera por nombre de cabecera, validaron campos requeridos, rechazaron columnas desconocidas y produjeron un reporte diff. La hoja pudo cambiar de forma, pero el sistema no la aceptaría silenciosamente.
Microhistoria #2: La optimización que salió mal
Un equipo de logística tenía un libro que calculaba cantidades de reposición para almacenes. Extraía datos de un informe exportado y usaba una maraña de fórmulas. El libro se volvió lento. Para “acelerarlo”, un analista reemplazó fórmulas por valores estáticos después de la actualización semanal—copiar, pegar valores, listo. Funcionó. También era una bomba de tiempo.
Meses después, se añadió un nuevo almacén. El libro tenía rangos con nombre y algunas fórmulas que debían extenderse automáticamente. No lo hicieron. Porque la hoja era ahora mayormente valores pegados, el almacén faltante nunca entró en el cálculo. El panel seguía pareciendo saludable porque los totales estaban lo suficientemente cerca. Nadie notó que una instalación entera se reabastecía usando el patrón del mes pasado y ajustes manuales.
Cuando la precisión de inventario bajó lo suficiente para disparar alarmas, ingeniería intervino. Encontraron un libro “rápido” cuya lógica había sido amputada para hacerlo responsivo. La optimización no estaba mal en espíritu—resolvía un problema real de rendimiento—pero destruyó la capacidad del libro para adaptarse a entradas cambiantes.
La solución fue mover los cálculos a una tubería adecuada: extraer datos del informe, validar esquema, calcular reposición en código, almacenar salidas y dejar que Excel sea una capa de vista si la gente aún la necesitaba. El rendimiento mejoró y la lógica dejó de ser editable por cirugía de copiar/pegar accidental.
Microhistoria #3: La práctica aburrida pero correcta que salvó el día
Un equipo de operaciones financieras ejecutaba pagos mensuales a socios. Sus datos fuente llegaban como hojas desde múltiples canales. El proceso tenía reputación de frágil, así que un ingeniero de ops insistió en algo profundamente poco glamoroso: checksums, entradas crudas inmutables y un paso de transformación reproducible.
Requisitaron que cada archivo entrante se almacenara sin cambios en un directorio “incoming” con marca de tiempo, luego se convirtiera a CSV normalizado mediante un proceso scriptado. El script validaba cabeceras, conteos e invariantes básicos (no montos negativos salvo que estén marcados, IDs de socios que coincidan con patrones esperados). También generaba un informe resumen y un diff contra los totales del mes anterior por socio.
Un mes, el archivo de un socio llegó con un problema sutil: la columna “Amount” contenía valores con comas en un formato específico de localidad, y Excel los mostraba bien. El script de transformación rechazó el archivo porque el parseo numérico falló. En lugar de “arreglar” silenciosamente, el proceso forzó una decisión humana: solicitar un archivo corregido o usar una configuración de parseo explícita para ese socio.
El pago se retrasó unas horas. Ese fue el “coste”. El coste evitado fue un pago erróneo de siete cifras y un evento de cumplimiento. La práctica aburrida ganó: trata las hojas como entradas no confiables, almacena artefactos crudos inmutables, valida agresivamente y fuerza fallos temprano donde son baratos.
Guía de diagnóstico rápido: encuentra el cuello de botella pronto
Cuando Excel está involucrado en resultados de producción, tu triage de incidentes debe cubrir tanto la infraestructura como la canalización con humanos. El camino más rápido es determinar si tienes un problema de correctitud de datos, de frescura de datos o de disponibilidad del sistema.
Primero: clasifica el incidente en 5 minutos
- Correctitud: los números están mal, pero los trabajos “sucedieron”. Busca parseo, coerción, deriva de columnas, subidas duplicadas, fórmulas obsoletas.
- Frescura: los números están anticuados. Busca subidas perdidas, fallos de cron, colas atascadas, paso manual no ejecutado, confusión de zonas horarias.
- Disponibilidad: los trabajos de la tubería fallan ruidosamente. Busca almacenamiento lleno, permisos, share de red caído, outages de API, fallos de constraint en BD.
Segundo: identifica el “límite de entrega”
Siempre hay un momento donde “sistema” se convierte en “hoja” (exportación), y otro donde “hoja” se convierte en “sistema” (importación). La mayoría de fallos se concentran en estos límites:
- Cambio de codificación/locale en la exportación (UTF-8 vs Windows-1252, coma decimal vs punto).
- Fila de cabecera ausente o duplicada.
- Sólo filas visibles exportadas por filtrado.
- Excel auto-convirtió identificadores.
- Script de importación asume posiciones de columnas.
Tercero: comprueba invariantes, no solo logs
Los logs te dicen si el trabajo corrió. Las invariantes te dicen si hizo lo correcto. Quieres “smoke tests” rápidos:
- Conteo de filas dentro del rango esperado.
- Claves únicas que realmente son únicas.
- Totales que reconcilian con la línea base dentro de tolerancia.
- Esquema que coincide con cabeceras y tipos esperados.
Cuarto: decide si parar la línea
Si se mueve dinero, para la línea cuando fallen invariantes. No “parches” editando la hoja en el lugar. Así se pierde auditabilidad y terminas discutiendo qué se cambió y cuándo. Congela las entradas, vuelve a ejecutar las transformaciones y solo entonces reimporta.
Tareas prácticas: comandos, salidas y decisiones (la edición SRE)
A continuación hay tareas reales que puedes ejecutar durante un incidente o como higiene preventiva. Cada una incluye un comando, salida de ejemplo, lo que significa y la decisión a tomar.
Task 1: Confirmar que el archivo que vas a procesar es inmutable (hashearlo)
cr0x@server:~$ sha256sum /data/incoming/pricing_tiers.xlsx
a3f2c1d8bb9c2d2bb1e0e1e2b72f16c4d6b3a2a0c3c1ad4f1c9c0b7a3d8e2f11 /data/incoming/pricing_tiers.xlsx
Significado: Esta es la huella del archivo exacto usado para el procesamiento.
Decisión: Almacena el hash junto con la metadata de la ejecución. Si alguien “arregla la hoja”, requiere un archivo nuevo y un hash nuevo; nunca sobrescribas.
Task 2: Ver cuándo cambió el archivo (capturar edits de última hora)
cr0x@server:~$ stat /data/incoming/pricing_tiers.xlsx
File: /data/incoming/pricing_tiers.xlsx
Size: 4821932 Blocks: 9424 IO Block: 4096 regular file
Device: 0,42 Inode: 1311042 Links: 1
Access: (0640/-rw-r-----) Uid: ( 1001/ ingest) Gid: ( 1001/ ingest)
Access: 2026-01-22 08:11:17.000000000 +0000
Modify: 2026-01-22 08:10:59.000000000 +0000
Change: 2026-01-22 08:10:59.000000000 +0000
Significado: La hora de modificación cercana al tiempo de ejecución puede indicar que alguien editó y volvió a subir a mitad de proceso.
Decisión: Si un archivo cambió durante la ventana de ejecución, cuaréntalo y vuelve a ejecutar desde una instantánea estable.
Task 3: Convertir XLSX a CSV de forma determinista (evitar exportación desde Excel)
cr0x@server:~$ ssconvert --export-type=Gnumeric_stf:stf_csv /data/incoming/pricing_tiers.xlsx /data/staging/pricing_tiers.csv
Importing file `/data/incoming/pricing_tiers.xlsx'
Saving file `/data/staging/pricing_tiers.csv'
Significado: Has convertido usando una herramienta server-side; la salida es reproducible y scriptable.
Decisión: Estandariza la conversión en CI/CD o en un job controlado. No confíes en “Guardar como CSV” manual.
Task 4: Detectar codificaciones no UTF-8 (fuente de corrupción silenciosa)
cr0x@server:~$ file -bi /data/staging/pricing_tiers.csv
text/plain; charset=utf-8
Significado: Confirma que el archivo es UTF-8; si fuera Windows-1252 esperarías otro charset.
Decisión: Si no es UTF-8, conviértelo explícitamente antes de parsear y documenta la codificación del sistema fuente.
Task 5: Comprobar rápido delimitadores/comillas raras
cr0x@server:~$ head -n 3 /data/staging/pricing_tiers.csv
customer_id,segment,region,discount_pct
001234,enterprise,EU,12.5
009876,midmarket,US,7.0
Significado: Mirada rápida: cabecera esperada, comas presentes, decimales con punto.
Decisión: Si ves puntos y comas, comillas inconsistentes o saltos de línea embebidos, ajusta la configuración del parser o rechaza y solicita una exportación corregida.
Task 6: Validar conteo de filas contra lo esperado (smoke test de frescura/correctitud)
cr0x@server:~$ wc -l /data/staging/pricing_tiers.csv
4821 /data/staging/pricing_tiers.csv
Significado: 4.821 líneas incluye la cabecera; compáralo con el rango típico de ejecuciones previas.
Decisión: Si el conteo baja o sube inesperadamente, detén la importación e investiga filtros, hojas faltantes o secciones duplicadas.
Task 7: Confirmar que las cabeceras coinciden exactamente con el contrato (matar deriva de columnas)
cr0x@server:~$ head -n 1 /data/staging/pricing_tiers.csv | tr ',' '\n' | nl -ba
1 customer_id
2 segment
3 region
4 discount_pct
Significado: Tienes una lista ordenada de columnas; esta es tu interfaz de esquema.
Decisión: Si falta, cambia o se añade alguna columna, falla la tubería ruidosamente. No intentes adivinar.
Task 8: Detectar claves duplicadas (un clásico de “pegar dos veces”)
cr0x@server:~$ awk -F, 'NR>1{print $1}' /data/staging/pricing_tiers.csv | sort | uniq -d | head
001234
004455
Significado: Estos IDs de cliente aparecen más de una vez.
Decisión: Decide la política: rechazar duplicados, o requerir una columna “effective_date” y reglas deterministas de resolución.
Task 9: Detectar daño por “notación científica” en identificadores
cr0x@server:~$ awk -F, 'NR>1 && $1 ~ /E\+/ {print NR ":" $1; exit}' /data/staging/pricing_tiers.csv
129:1.23457E+11
Significado: Un ID fue convertido a notación científica en algún punto del proceso.
Decisión: Rechaza el archivo y arregla la ruta de exportación. Los IDs deben tratarse como cadenas de extremo a extremo.
Task 10: Comprobar sanidad numérica (valores negativos, porcentajes imposibles)
cr0x@server:~$ awk -F, 'NR>1 && ($4<0 || $4>100){print NR ":" $0}' /data/staging/pricing_tiers.csv | head
77:008812,enterprise,US,150
Significado: 150% de descuento probablemente no es una estrategia; es un error de parseo o de entrada de datos.
Decisión: Define invariantes y aplícalos como puertas. Si existen excepciones, requiere una columna de override y aprobaciones explícitas.
Task 11: Comparar totales de hoy con una línea base (captar cambios silenciosos)
cr0x@server:~$ awk -F, 'NR>1{sum+=$4} END{printf "%.2f\n", sum}' /data/staging/pricing_tiers.csv
39210.50
Significado: Un agregado burdo. No probará corrección, pero detectará desviaciones enormes.
Decisión: Si la suma se desvía fuera de una banda de tolerancia de ejecuciones previas, bloquea la importación e inicia una investigación.
Task 12: Validar frescura revisando logs del pipeline por la última ejecución exitosa
cr0x@server:~$ journalctl -u pricing-importer --since "2 days ago" | tail -n 8
Jan 22 08:12:03 server pricing-importer[24911]: Starting import: /data/staging/pricing_tiers.csv
Jan 22 08:12:04 server pricing-importer[24911]: Parsed rows=4820 rejected=0
Jan 22 08:12:05 server pricing-importer[24911]: Upsert complete
Jan 22 08:12:05 server pricing-importer[24911]: Import success run_id=7b3d2c
Significado: Confirma que el importador corrió recientemente y cuántas filas se parsearon/rechazaron.
Decisión: Si la última ejecución exitosa es muy antigua, trátalo como incidente de frescura y busca handoffs atascados.
Task 13: Revisar la BD por la marca de tiempo del dato más reciente (no confíes en el log del job)
cr0x@server:~$ psql -d pricing -c "select max(updated_at) from discount_tiers;"
max
---------------------
2026-01-22 08:12:05
(1 row)
Significado: Confirma que el estado downstream cambió cuando crees que lo hizo.
Decisión: Si las marcas de tiempo están rezagadas, la importación puede haber “sido exitosa” pero no escribió nada (constraints, reglas de desduplicación, mapeos de clave erróneos).
Task 14: Confirmar que el almacenamiento no está lleno (porque “import failed” suele ser “disco lleno”)
cr0x@server:~$ df -h /data
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 500G 496G 4.0G 100% /data
Significado: Vives al límite. Archivos temporales y conversiones fallarán de forma impredecible.
Decisión: Libera espacio inmediatamente y añade alertas sobre utilización de filesystem con estimaciones de tiempo hasta llenado.
Task 15: Encontrar los mayores consumidores en el área de staging
cr0x@server:~$ du -sh /data/staging/* | sort -h | tail -n 5
3.2G /data/staging/archive
5.8G /data/staging/tmp
7.1G /data/staging/exports
Significado: El espacio lo consumen archives/tmp; la política de limpieza puede estar rota.
Decisión: Implementa retención (por ejemplo, conserva las últimas N versiones) y mueve almacenamiento a object storage con reglas de ciclo de vida.
Task 16: Verificar que el cron/systemd timer realmente se disparó (chequeo de “nadie apretó el botón”)
cr0x@server:~$ systemctl list-timers --all | grep pricing
Thu 2026-01-22 08:12:00 UTC 2min ago Thu 2026-01-22 08:12:00 UTC 2min ago pricing-import.timer pricing-import.service
Significado: El timer se disparó; si el servicio no corrió, mira fallos del servicio o dependencias.
Decisión: Si los timers no se disparan, hay problemas de programación/host. Si se disparan pero los datos están mal, enfócate en entradas/parseo.
Task 17: Capturar deriva de esquema diffando cabeceras contra un contrato fijado
cr0x@server:~$ diff -u /etc/pricing/header_contract.txt <(head -n 1 /data/staging/pricing_tiers.csv)
--- /etc/pricing/header_contract.txt
+++ /dev/fd/63
@@ -1 +1 @@
-customer_id,segment,region,discount_pct
+customer_id,segment,Region,discount_pct
Significado: Un cambio de mayúsculas (“Region” vs “region”) puede romper parsers estrictos o mapeos downstream.
Decisión: Decide si las cabeceras distinguen mayúsculas; haz cumplir la consistencia. Mi consejo: sé estricto y exige cumplimiento a los productores.
Task 18: Verificar permisos en la ubicación compartida de subida (fallos de ingestión que parecen “sin datos”)
cr0x@server:~$ namei -l /data/incoming
f: /data/incoming
drwxr-xr-x root root /
drwxr-xr-x root root data
drwxrwx--- ingest ingest incoming
Significado: Solo el grupo ingest puede escribir. Si un uploader humano no está en el grupo, “subirá” en otra parte o fallará silenciosamente.
Decisión: Arregla la membresía de grupo y documenta la ruta de subida; considera una carga web con autenticación en lugar de una carpeta compartida.
Errores comunes: síntoma → causa raíz → solución
Estos aparecen una y otra vez. Trátalos como vulnerabilidades conocidas.
1) “Import completed” pero los valores downstream son nonsense
Síntoma: Logs del job muestran éxito; los dashboards cambian de forma drástica; no hay excepciones.
Causa raíz: Parseo posicional de CSV con deriva de columnas, o exportación desde Excel que reordenó columnas.
Solución: Parsear por nombre de cabecera, validar columnas requeridas/permitidas y fallar ante campos desconocidos. Producir un reporte diff legible para humanos antes de aplicar cambios.
2) Registros faltantes después de una actualización de hoja
Síntoma: Un subconjunto de clientes/productos desaparece tras una “edición menor”.
Causa raíz: Filtros activos en Excel; solo se exportaron filas visibles. O una pestaña no fue incluida en la exportación.
Solución: Conversión server-side desde el XLSX crudo; rechazar archivos con rangos filtrados (si se detecta) y validar conteos de filas y cobertura de claves.
3) IDs dejan de coincidir entre sistemas
Síntoma: Fallan las joins; aparecen “nuevas” entidades que parecen duplicados.
Causa raíz: IDs auto-coaccionados (ceros a la izquierda perdidos, notación científica, redondeo numérico).
Solución: Forzar IDs como cadenas en el primer paso de ingestión; validar patrones (longitud/regex). Nunca aceptes IDs numéricos desde una hoja sin formateo explícito.
4) En el cierre de mes “simplemente toma más tiempo ahora”
Síntoma: El procesamiento de hojas crece hasta convertirse en una situación de emergencia.
Causa raíz: La hoja se transformó en motor de cálculo; fórmulas volátiles, rangos enormes, búsquedas entre hojas.
Solución: Mover cálculo a un pipeline o base de datos; mantener Excel como front-end o artefacto de informe. Establecer un límite duro de filas/complejidad.
5) Dos equipos juran que usaron “el mismo archivo”
Síntoma: Resultados conflictivos, señalar con el dedo, resultados no reproducibles.
Causa raíz: No hay inmutabilidad, no hay retención de artefactos, no hay checksums; archivos sobrescritos o enviados por email.
Solución: Almacenar entradas crudas inmutables con hashes y timestamps. Requerir run IDs y adjuntar artefactos a la ejecución.
6) “Lo arreglamos” pero vuelve a fallar la próxima semana
Síntoma: Incidentes repetidos con pequeñas variaciones nuevas.
Causa raíz: La solución fue un parche manual en la hoja; la tubería acepta cualquier cosa que llegue; no hay pruebas ni contratos.
Solución: Escribir un contrato de esquema, aplicar invariantes, añadir puertas de validación pre-importación y asignar propiedad con control de cambios.
7) Problemas de moneda/decimales entre regiones
Síntoma: Valores errados por 10x/100x; decimales aparecen como separadores de miles.
Causa raíz: Desajuste de locale (coma vs punto), formato de Excel vs valor crudo, o CSV exportado con separadores localizados.
Solución: Normalizar formatos numéricos en la capa de ingestión. Requerir códigos ISO de moneda y separadores decimales explícitos. Rechazar formatos ambiguos.
8) La importación empieza a fallar “aleatoriamente” tras actualizaciones del SO
Síntoma: La misma hoja “funciona en mi máquina”, falla en el servidor o viceversa.
Causa raíz: Deriva de dependencias: versiones de conversores, diferencias en librerías de parseo o ajustes de seguridad de macros.
Solución: Contenerizar herramientas de conversión/parseo; fijar versiones; crear fixtures dorados y ejecutarlos en cada despliegue.
Listas de verificación / plan paso a paso
Esto no es aspiracional. Es lo mínimo para evitar que las operaciones impulsadas por hojas se conviertan en una categoría recurrente de incidentes.
Checklist A: Si Excel es fuente de la verdad, trátalo como código de producción
- Definir responsabilidad: un responsable único (no un comité), con un backup.
- Definir un contrato de esquema: columnas requeridas, permitidas, tipos e invariantes.
- Evitar sobrescrituras: almacenar cada archivo entrante inmutable con timestamp + hash.
- Automatizar conversión: XLSX → CSV normalizado usando herramientas server-side, no la UI de Excel.
- Validar antes de importar: rangos de conteo de filas, claves únicas, chequeos de tipo, invariantes y agregados de sanidad.
- Hacer importaciones idempotentes: re-ejecutar el mismo archivo produce el mismo estado en BD.
- Producir un diff de aprobación: “Esto es lo que cambiará” resumen para revisión humana.
- Loggear run IDs: cada cambio downstream ligado a un run ID y hash de entrada.
Checklist B: Respuesta a incidentes paso a paso cuando se sospecha la hoja
- Congelar la tubería: pausar importaciones o deshabilitar el job para detener daños acumulativos.
- Identificar la última ejecución buena: encontrar run ID, hash de entrada y marca de tiempo downstream.
- Recolectar artefactos: XLSX crudo, CSV normalizado, reportes de validación, logs del importador.
- Ejecutar invariantes: conteos de filas, duplicados, diff de esquema, chequeos de sanidad numérica.
- Comparar con la línea base: totales y distribuciones de claves vs ejecución previa.
- Decidir estrategia de rollback: revertir la BD al último estado bueno o re-importar archivo conocido bueno.
- Arreglar en el límite: no “corregir” la hoja en su lugar; corrige el contrato de ingestión o solicita un nuevo archivo.
- Post-incidente: añade una puerta que hubiera prevenido la misma clase de fallo.
Checklist C: Plan de migración (Excel a algo más seguro) sin una guerra civil
- Inventariar hojas críticas: cuáles mueven dinero, cambian derechos de clientes o afectan cumplimiento.
- Escoger el primer objetivo por radio de impacto: mayor impacto × mayor frecuencia de cambios.
- Extraer el modelo: identificar entradas, salidas y dependencias ocultas (otras hojas, enlaces externos, macros).
- Escribir una implementación de referencia: código que reproduzca salidas desde las mismas entradas.
- Ejecutar en paralelo: hoja y nuevo sistema producen salidas lado a lado hasta entender las diferencias.
- Mantener Excel como UI si es necesario: permitir export/import pero bajo contrato, con validación y aprobaciones.
- Hacer el corte con guardarraíles: feature flag, plan de rollback y monitoreo de invariantes.
- Bloquear la vía antigua: eliminar “subida manual” o convertirla en flujo solo para emergencias con aprobaciones explícitas.
Preguntas frecuentes
1) ¿Excel es “malo”?
No. Excel es fantástico para exploración, prototipos y análisis puntuales. Se vuelve peligroso cuando es el sistema de registro sin controles de nivel productivo.
2) ¿Cuál es el control de mayor palanca para añadir?
Almacenamiento inmutable de entradas con checksums y run ID. Si no puedes probar qué archivo produjo qué salida, no tienes operaciones—tienes folclore.
3) ¿Por qué no decir simplemente que la gente deje de usar hojas?
Porque no lo harán. O cumplirán públicamente y seguirán haciéndolo en privado. Sustituye el flujo: ofrece una herramienta más segura que sea tan rápida como Excel para su trabajo.
4) CSV parece simple. ¿Por qué causa tantos outages?
Porque “CSV” no es un único formato. Delimitadores, reglas de comillas, codificaciones, saltos de línea embebidos y números específicos de localidad convierten lo “simple” en “ambiguo”. Las exportaciones desde Excel amplifican esa ambigüedad.
5) Ya tenemos un data warehouse. ¿Por qué importa aún Excel?
Porque las decisiones a menudo ocurren fuera del warehouse: alguien descarga, edita y vuelve a subir. El warehouse puede estar impecable mientras el archivo operativo de la última milla es un caos.
6) ¿Cómo detecto incidentes impulsados por hojas más temprano?
Monitorea invariantes: conteos de filas, unicidad de claves, cambios en distribuciones y totales de conciliación. Alerta por desviaciones, no por “job failed”, porque los fallos de hoja suelen reportarse como éxitos.
7) ¿Cuál debería ser el límite entre Excel y los sistemas de producción?
Excel puede ser una entrada, pero solo a través de una ruta de ingestión controlada que normalice formatos, valide esquema y produzca un diff de aprobación. Excel no debería escribir directamente al estado de producción sin puertas.
8) ¿Las macros siempre son inaceptables?
En flujos regulados o de alto impacto, trata las macros como código no revisado que corre en endpoints aleatorios—porque eso son. Si debes mantenerlas, versiónalas, fírmales y mueve la ejecución al servidor.
9) ¿Cómo manejamos “pero la hoja contiene lógica de negocio que no podemos perder”?
Extrae y codifícala. Empieza escribiendo pruebas a partir de entradas/salidas históricas conocidas y luego reimplementa la lógica en código. Mantén Excel como vista durante la transición, no como motor.
10) ¿Cuál es un objetivo pragmático de migración inicial?
Cualquier hoja que alimente un job de importación. Reemplaza “exportación/importación manual” por: captura de artefacto crudo → conversión determinista → validación → importación idempotente → rastro de auditoría.
Conclusión: qué hacer el lunes
Si Excel está en tu cadena de producción, no estás condenado. Solo necesitas tratarlo como una interfaz no confiable y de alta varianza—como Internet pública, pero con más celdas fusionadas.
Pasos siguientes que realmente reducen incidentes:
- Encuentra las cinco hojas principales que mueven dinero o permisos. Anota responsables, cadencia y dependencias downstream.
- Instala guardarraíles en los límites: almacenamiento inmutable, hashes, conversión determinista, contratos de esquema, chequeos de invariantes.
- Haz el fallo ruidoso y temprano: rechaza archivos ambiguos, bloquea importes por deriva y exige un nuevo artefacto para cualquier “arreglo”.
- Mueve el cómputo fuera de Excel: si un libro hace transformaciones serias, pertenece al código y a la base de datos.
- Deja de depender de heroicidades: construye la tubería aburrida que hace que lo correcto sea también lo fácil.
Excel seguirá gobernando el mundo. Tu trabajo es evitar que gobierne tu cola de incidentes.