Creación, edición y análisis de XLSX
| Tarea | Enfoque |
|---|---|
| Crear o editar con fórmulas/formato | openpyxl — ver errores comunes más abajo |
| Datos masivos de entrada o salida | pandas (read_excel, to_excel) |
| Vistazo rápido a una hoja | markitdown archivo.xlsx — ## NombreHoja por hoja; también lee .xlsm. No muestra coordenadas de celdas, así que no planees ediciones a partir de él |
| Leer un modelo (fórmulas y valores) | dos pasos de load_workbook — ver errores comunes |
openpyxl,pandasymarkitdownestán preinstalados — no ejecutespip installprimero; escribe el script e importa directamente. Solo si una importación falla (o el comandomarkitdownno se encuentra): ejecutapip installdel paquete faltante.
Las rutas de los scripts a continuación son relativas al directorio de esta habilidad.
Requisitos para cada salida
- Fuente profesional (Arial, Times New Roman) en todo el documento, a menos que el usuario indique lo contrario.
- Cero errores de fórmula. Nunca entregues mientras
recalc.pyreporteerrors_found. Si crees que un error existía antes de tu intervención, demuéstralo: carga el archivo original condata_only=Truey revisa esa celda. Un error que introdujiste se ve exactamente igual que uno que heredaste. - Usa fórmulas, nunca resultados hardcodeados. Escribe
sheet['B10'] = '=SUM(B2:B9)', no el total calculado en Python. La hoja debe recalcularse cuando sus entradas cambien. - Sigue literalmente la especificación del usuario. Nombres de pestañas exactos, encabezados de columna exactos y la fórmula que especificó. Un rediseño que calcula algo diferente falla, por más elegante que sea.
- Documenta cada suposición y número hardcodeado donde el lector pueda verlo — un comentario de celda, o una celda adyacente al final de una tabla. Cita una fuente real cuando exista (
Fuente: Informe 10-K de la Compañía, AF2024, Página 45, Nota de Ingresos, [URL SEC EDGAR]); cuando el número provino del usuario, dila claramente. - Un libro que creas para que alguien lo llene necesita una leyenda corta que nombre qué celdas editar, y una fila de ejemplo con valores realistas que muestre el formato esperado. Nunca agregues esa fila a un archivo que te pidieron editar.
- Editar un archivo existente: respeta sus convenciones exactamente. Ellas anulan cualquier directriz aquí. Primero encuentra sus celdas de entrada designadas — un color de fuente, relleno o sombreado distinto las marca — escribe solo allí y deja intacta cada fórmula existente.
Recalcular (obligatorio cuando el archivo contiene fórmulas)
openpyxl escribe fórmulas como cadenas de texto sin valores almacenados en caché. Hasta que recalcules, cada
celda de fórmula se lee como None para cualquier cosa que lea valores en caché — pandas,
load_workbook(data_only=True) y la mayoría de los previsualizadores.
python scripts/recalc.py salida.xlsx [segundos_timeout] # predeterminado 30
LibreOffice calcula cada fórmula, el archivo se reescribe en el lugar, y obtienes JSON:
status (success | errors_found), total_formulas, total_errors, y un
error_summary que nombra hasta 100 celdas por tipo de error (locations_truncated dice cuántas
omitió — confía en total_errors, no en la longitud de la lista). Corrige lo que nombre y ejecútalo
nuevamente. JSON con una clave error en lugar de status significa que no se recalculó nada, y
solo ese caso sale con código distinto de cero — errors_found sale con 0, así que nunca trates una salida limpia como un libro limpio.
Un recálculo verde prueba que tus fórmulas evalúan, no que sean correctas. Un rango desplazado por uno o una referencia a la fila equivocada produce un archivo limpio y sin errores con números incorrectos. Escribe 2–3 fórmulas primero y verifica que obtengan los valores que esperas, antes de construir una cuadrícula.
Un libro que enlaza a otro archivo pierde esos enlaces si lo guardas de nuevo con openpyxl y luego
recalculas. Tal fórmula lee ='[1]Returns Analysis'!$B$2 — el [1] es un índice
de la lista de referencias externas del libro, que nombra un archivo separado en disco, no una hoja.
Ese archivo rara vez está presente aquí, por lo que el valor almacenado en caché de la celda es lo único que conserva sus
datos. openpyxl elimina ese valor al guardar; LibreOffice entonces tiene que resolver la referencia realmente,
falla, escribe #NAME? y elimina todos los enlaces. recalc.py se niega a ejecutarse en ese estado
— copia los valores de esas celdas del original antes de guardar sobre ellas (--force anula,
y acepta la pérdida).
Elegir fórmulas que sobrevivan a la verificación
LibreOffice implementa menos funciones que Excel, y una que no puede evaluar se convierte en un
literal #NAME? grabado en el archivo que entregas.
- Prefiere funciones de la era de Excel 2007 —
SUMIFS,INDEX,MATCH,IFERROR,SUMPRODUCT— que no necesitan prefijo. - Seis funciones posteriores a 2007 funcionan, pero solo con el prefijo
_xlfn., porque openpyxl escribe tu fórmula en el XML textualmente y Excel almacena los nombres posteriores a 2007 con prefijo (su UI oculta el prefijo):_xlfn.TEXTJOIN,_xlfn.CONCAT,_xlfn.IFS,_xlfn.SWITCH,_xlfn.MAXIFS,_xlfn.MINIFS. Escritas sin prefijo, cada una produce#NAME?. - Nunca uses
XLOOKUP,XMATCH,SORT,FILTER,UNIQUEoSEQUENCE. El LibreOffice del tiempo de ejecución no puede evaluarlas bajo ningún prefijo. Versiones más nuevas sí las evalúan, pero son funciones de matriz derramada y un archivo escrito por openpyxl no tiene metadatos de derrame, por lo que solo la celda superior izquierda del rango obtiene un valor — yrecalc.pyreportatotal_errors: 0en el resultado truncado. UsaINDEX/MATCHpara búsquedas, y ordena, filtra y elimina duplicados en Python antes de escribir las celdas. - Una fórmula que LibreOffice no pudo analizar se escribe de vuelta en minúsculas — una pista rápida junto a un
#NAME?.
Errores comunes de openpyxl
- Leer un modelo requiere dos cargas.
data_only=Trueproduce valores almacenados en caché sin las fórmulas; la opción predeterminada produce cadenas de fórmula sin valores. Un solo paso no puede darte ambos. data_only=Truees destructivo si guardas. Ese libro no tiene fórmulas restantes, por lo que guardar reemplaza cada una con un literal — permanentemente.data_only=Trueen un archivo que openpyxl acaba de escribir devuelveNoneen todas partes — ejecutarecalc.pyprimero. (Una fórmula cuyo resultado es""también se lee comoNone).- Celdas combinadas: escribe solo el ancla superior izquierda. Cada otra celda en el rango es un
MergedCellcuyo.valuees de solo lectura. .xlsmpierde sus macros a menos que paseskeep_vba=Trueaload_workbook.- Un nombre de hoja que contenga un espacio debe ir entre comillas en una referencia entre hojas:
='Supuestos de Entrada'!$B$5. Sin comillas, evalúa a#VALUE!.
Modelos financieros
A menos que el usuario indique lo contrario, o que el archivo existente ya haga algo diferente.
Color: texto azul (0,0,255) para entradas hardcodeadas y palancas de escenario · negro para fórmulas ·
verde (0,128,0) para enlaces a otra hoja · rojo (255,0,0) para enlaces a otro archivo ·
relleno amarillo (255,255,0) para supuestos clave y celdas que el usuario debe llenar.
Números: moneda $#,##0, con la unidad nombrada en el encabezado (Ingresos ($mm)) · ceros
se muestran como -, incluso en porcentajes ($#,##0;($#,##0);-) · negativos entre paréntesis ·
porcentajes 0.0%, almacenados como fracciones (0.15 muestra 15.0%; almacenar 15 muestra
1500.0%) · múltiplos de valoración 0.0x · años como texto ("2024", nunca 2,024).
Estructura: cada supuesto en su propia celda etiquetada, referenciado por las fórmulas que lo usan
(=B5*(1+$B$6), nunca =B5*1.05) · fórmulas consistentes en cada período de proyección, ya que una
celda editada aislada en medio de una fila es el error silencioso más común · protege denominadores que pueden ser cero.
Dependencias
openpyxl, pandas, markitdown (pip, preinstalados — instala solo si una importación falla o el comando falta) · LibreOffice (soffice, configurado automáticamente para entornos aislados mediante scripts/office/soffice.py)