An ERP gives its users a catalogue template to fill in and upload again. If the Unidad
column only accepts UND, KG or LT, a dropdown in the cell stops anyone typing another value and the upload rejects far fewer rows. In the file that comes back, the rejected rows are marked with a fill color.
// Nyx by Example: una plantilla .xlsx de carga masiva, con listas desplegables. // // El caso real: un ERP entrega a sus usuarios una plantilla de catálogo para // llenar y volver a subir. Si la columna «Unidad» solo acepta UND, KG o LT, una // lista desplegable en la celda impide escribir otro valor y la carga rechaza // muchas menos filas. Y en el .xlsx que vuelve, las filas rechazadas se marcan // con color de relleno. // // Lo que muestra: // - validate_list(rango, valores): lista fija (Excel la guarda dentro de la // fórmula: tope de 255 caracteres en total, sin comas ni comillas en los // valores; si no cabe, xlsx_write devuelve Err); // - validate_list_range(rango, origen): la lista sale de un rango, aquí la // pestaña «Listas», sin tope de largo; // - xlsx_fill(celda, "RRGGBB"): relleno sólido, encadenable con xlsx_bold; // - los errores (color que no sea de 6 dígitos hex) salen de xlsx_write. // // Correr: nyx run -- plantilla.xlsx (sin argumento solo informa el tamaño) import "std/xlsx" import "std/error" fn plantilla() -> Result<String, Error> { var h: XlsxSheetOut = xlsx_sheet_new("Catalogo") h.row([xlsx_bold(xlsx_text("Codigo")), xlsx_bold(xlsx_text("Descripcion")), xlsx_bold(xlsx_text("Unidad")), xlsx_bold(xlsx_text("Categoria"))]) // Una fila de ejemplo y otra rechazada por la carga anterior (unidad inválida), // marcada en rojo claro con el motivo al lado. h.row([xlsx_text("T-001"), xlsx_text("Tornillo 1/4"), xlsx_text("UND"), xlsx_text("Ferreteria")]) h.row([xlsx_fill(xlsx_text("T-002"), "FFC7CE"), xlsx_fill(xlsx_text("Cemento"), "FFC7CE"), xlsx_fill(xlsx_text("SACO"), "FFC7CE"), xlsx_fill(xlsx_text("Construccion"), "FFC7CE"), xlsx_text("unidad no válida")]) h.col_width(2, 28.0) h.col_width(5, 20.0) h.freeze(1, 0) // Unidad: lista fija, corta. Categoria: sale de la pestaña «Listas». h.validate_list("C2:C500", ["UND", "KG", "LT"]) h.validate_list_range("D2:D500", "Listas!$A$1:$A$3") var listas: XlsxSheetOut = xlsx_sheet_new("Listas") listas.row([xlsx_text("Ferreteria")]) listas.row([xlsx_text("Construccion")]) listas.row([xlsx_text("Pintura")]) return xlsx_write([h, listas]) } fn main() -> int { match plantilla() { Result.Ok(bytes) => { let args: Array = get_args() if args.length() > 1 { let ruta: String = args[1] write_file(ruta, bytes) print("plantilla escrita en " + ruta + " (" + int_to_string(bytes.length()) + " bytes)") } else { print("plantilla: " + int_to_string(bytes.length()) + " bytes, empieza con " + bytes.substring(0, 2)) print("para escribirla: nyx run -- plantilla.xlsx") } return 0 } Result.Err(e) => { print("no se pudo armar la plantilla: " + error_to_string(e)) return 1 } } }
plantilla: 3213 bytes, empieza con PK para escribirla: nyx run -- plantilla.xlsx
How it works
validate_list(range, values) is a fixed list. Excel stores it inside the formula, so there is a 255-character cap in total, and the values cannot contain commas or quotes; if it does not fit, xlsx_write returns an Err. validate_list_range(range, source) takes the list from a range instead — here the Listas
tab — with no length cap. xlsx_fill(cell, "RRGGBB") gives a solid fill and chains with xlsx_bold.
Errors, such as a color that is not 6 hex digits, come out of xlsx_write. Run it with nyx run -- plantilla.xlsx to write the file; with no argument it only reports the size.