Cose che si possono fare con Excel (e Dynamo)
La scorsa settimana ho pubblicato il primo pezzo di una serie di post derivati da una lezione inusuale di Dynamo: una lezione su estrazione e gestione dati, analisi schedule, interfaccia con Excel. Non mi è mai andato in crash Dynamo così tante volte in vita mia. E ci sono state volte in cui Dynamo è […]
La scorsa settimana ho pubblicato il primo pezzo di una serie di post derivati da una lezione inusuale di Dynamo: una lezione su estrazione e gestione dati, analisi schedule, interfaccia con Excel. Non mi è mai andato in crash Dynamo così tante volte in vita mia. E ci sono state volte in cui Dynamo è andato in crash tante volte, nella mia vita…
In ogni caso, se Excel è parte del vostro workflow, tanto per cominciare vi consiglio di guardare questo. L’autore del video è Matt Parker, auto-definito stand-up mathematician, di cui ho consigliato un libro qualche settimana fa. No, il video non c’è in italiano. No, non ci sono i sottotitoli. No, non ho intenzione di mettermi a farli.
Se siete ancora convinti di voler usare Excel, dopo aver visto il video, procediamo pure. Per chi non ha visto il video, facciamo cose con Excel che non dovremmo fare. Tipo i computi metrici. Oppure inserire dati relativi alla salute pubblica. Ma se ritenete invece che ciò che state facendo sia appropriato da inserire all’interno di uno spreadsheet, la scorsa settimana abbiamo visto come lavorare con Dynamo per maneggiare le schedule e questo non può che essere un naturale seguito. Ecco quindi qualche workflow per interagire con Excel in modo meno bieco e primitivo di quello che viene offerto dal core.
1. Leggere da uno spreadsheet
Nel core di Dynamo esiste un nodo, molto semplice, che ci consente di accedere ai dati contenuti in uno spreadsheet di Excel e non è troppo diverso dal nodo che ci consente di leggere i dati contenuti in un file CSV (un file di testo in cui si codifica che i campi del futuro spreadsheet siano separati da un tab o da una virgola… o da un punto e virgola, o da una banana, che in ogni caso chiameremo delimitatore. Sono concetti che ci torneranno decisamente più comodi quando tenteremo di scrivere in un file Excel, quindi per adesso possiamo anche ignorare tutto ciò che riguarda delimitatori e qualificatori di testo.
1.1. Pescare il file
Fino a questo punto chiaramente l’operazione è semplice: dobbiamo solo ricordarci dove abbiamo salvato il nostro file.
Bisogna solo ricordarsi che l’output di File Path non è ciò che viene richiesto in input dai nodi che chiedono un File: per soddisfare quelli, avremo bisogno del nodo che dal percorso estrae il file per sé, File From Path per l’apppunto.
Prima che me lo domandiate, sì: in teoria è possibile andare a pescare un file direttamente su un sistema cloud, incluso BIM360.
Ma sulla relazione tra Dynamo e BIM360, ammesso che di BIM360 si possa parlare ancora a lungo, è necessario fare un punto a parte, che deve necessariamente esulare dal discorso che stiamo facendo ora.
1.2. Leggere dal file
A meno che chi ci ha lavorato non avesse il ditino facile su celle unite e formattazioni balorde, uno spreadsheet è un insieme più o meno strutturato di dati, che da Dynamo verranno letti e importati sotto forma di liste più o meno strutturate. Ciò che normalmente accade è che ci sono spreadsheet di lavoro, da cui e verso cui viaggiano i dati nella loro forma pura, e ci sono spreadsheet che pescano da quegli spreadsheet, in cui viene fatta la formattazione. Prima di passare quindi a leggere i dati con Dynamo e tirarli in Revit, esattamente come facciamo per un dwg, andiamo a verificare l’integrità e la struttura del file da cui stiamo pescando. In particolare, consiglio di verificare:
- la presenza di titoli inutili;
- la presenza di gerarchie non veicolate dalla struttura dati ma dalla formattazione;
- la presenza di celle unite;
- la presenza di celle strette strette strette usate al posto dei bordi (c’è un girone dell’inferno apposta per chi formatta gli spreadsheet in questo modo).
Per approfondire il concetto di struttura, consiglio anche questo articolo.
In ogni caso, una volta verificato che il nostro spreadsheet sia brutto ma funzionale (non necessariamente brutto, ma necessariamente funzionale), abbiamo di fatto due soluzioni davvero valide per leggere da un Excel: quella fornita dal core e quella fornita dal package Bumblebee, di Konrad Sobon. Confrontiamoli e vediamo perché preferisco di gran lunga Bumblebee.
1.2.1. Il nodo core
Insieme al core di Dynamo, troverete un nodo semplicemente chiamato Data.ImportExcel. Non un nodo eccezionale.
I primi due input del nodo sono il File (non il Path, quindi qui avremo bisogno di ciò che esce da File From Path) e il nome del worksheet (quello che in italiano si chiama Foglio all’interno del file che viene definito Cartella), una stringa che secondo loro io mi dovrei ricordare a memoria e dovrei inserire con un input manuale.
Questo sarà uno dei punti principali di miglioramento con Bumblebee, ma non è il solo. Gli altri due input riguardano l’autoconversione dei valori in stringhe (tutti quanti? e perché poi?) e un toggle che ci consente di non aprire Excel ogni volta che lanciamo lo script, cosa che consiglio vivamente di impostare da subito.
Come si vede dall’anteprima nel mio nodo, confrontandola con lo screenshot dello spreadsheet, la struttura iniziale di importazione è raggruppata per riga, cosa che difficilmente torna davvero utile. Nel mio caso, ad esempio, devo trasporre la lista per ottenere delle liste che contengano tutti i nomi delle famiglie, tutti i valori di Type Mark, Length e Cut Length.
In questo, il nodo non è molto più intelligente di quello che legge un csv, anzi, lo è di meno: per lo meno, Data.ImportCSV mi consente di trasporre sul momento.
1.2.2. Bumblebee
Come accennavo, la prima miglioria fornita da Bumblebee è la possibilità di leggere l’Excel per estrarre i nomi dei worksheet. Perché non c’è nessuna possibilità che io me li ricordi a memoria o che abbia voglia di andarli a vedere sul file.
Una cosa da ricordare è che il nodo Get Worksheet Names restituisce una lista, assumendo che la cartella contenga più fogli di lavoro. Se state lavorando con file che contengono un solo foglio, la lista che uscirà dal nodo di lettura sarà inutilmente strutturata con un livello in più e potrebbe quindi essere il caso di appiattirla.
Ciascuno dei nodi Bumblebee avrà bisogno di quel valore booleano in input a runIt, per funzionare. Pensatelo come un pulsante di accensione. Una valida alternativa ad essere in modalità manuale tutto il tempo, per quanto mi riguarda.
Il vero e proprio nodo di lettura di Bumblebee si chiama semplicemente Read Excel e per la prima parte non è troppo diverso da quello core: richiede il percorso del file (il Path, quindi, direttamente) e il nome dello Sheet, che possiamo inserire direttamente dal nodo di lettura.
La funzione byColumn, funziona un poco come l’input a Transpose nel nodo di lettura di un CSV: di default è impostato a falso, ma impostato a vero ci consente di importare una lista dati già trasposta e, quindi, con sottoliste raggruppate per colonna anziché per riga.
Ancora più utili sono gli altri due input, perché seriamente che senso ha importare tutti i dati e filtrarli in Dynamo, se ce ne servono solo alcuni?
Il funzionamento degli input origin ed extent è spiegato in modo chiarissimo sul primer di Bumblebee:
- origin determina l’inizio da cui si desidera partire per leggere il file;
- extent determina la fine della matrice.
Usati entrambi, ci consentono di individuare un range specifico, un intervallo da cui leggere.
In ogni caso, stiamo lavorando con un solo spreadsheet e quindi consiglio di appiattire la lista di un livello.
2. Leggere da uno spreadsheet e ricreare una schedule
2.1. Ricreare una schedule corrispondente
A patto che il workflow sia controllato e che sia possibile individuare una corrispondenza esatta tra le intestazioni dello spreadsheet e gli attributi all’interno di Revit, possiamo combinare quello che abbiamo appena visto con quello che abbiamo visto la settimana scorsa, e quindi pescare i dati dallo spreadsheet per ricrearci una schedule corrispondente all’interno di Revit, estrarre i valori dei parametri e confrontare ciò che è contenuto nell’Excel con quello che abbiamo nel modello, per intercettare le differenze.
Come nome possiamo usare lo stesso output che otteniamo da Get Worksheet Names, eventualmente aggiungendo un prefisso di identificazione. Naturalmente la categoria va indicata a mano, cosa su cui si potrebbe lavorare con un’appropriata convenzione di nomenclatura.
Come abbiamo visto in precedenza, la schedule viene creata vuota e deve quindi essere popolata di campi. Possiamo sceglierli attraverso il nodo ScheduleView.SchedulableFields, ma questa volta anziché scegliere i campi a mano possiamo utilizzare le intestazioni dello spreadsheet per cercare valori corrispondenti nell’elenco dei parametri a disposizione. Naturalmente nessuno deve aver pensato di modificare l’intestazione dello spreadsheet. Il nodo List.AllIndicesOf ci restituirà gli indici nella lista dei parametri a disposizione, mano a mano che avrà trovato stringhe che corrispondono a quelle dell’intestazione nello spreadsheet. Bisogna solo ricordarsi di trasformare in stringhe la lista di SchedulableFields.
Gli indici naturalmente ci servono per pescare i campi effettivi, da aggiungere alla schedule. Dato che la lista è strutturata buffa (un gruppo per ogni volta che il nodo ha trovato corrispondenza), possiamo appiattire. Non vi preoccupate se il nodo ha trovato due volte lo stesso parametro, come nel mio caso: nella schedule verrà aggiunto una volta sola.
2.2. Confrontare schedule e spreadsheet
Per confrontare i dati, dobbiamo prima estrarre quelli contenuti nella schedule e possiamo farlo agilmente con un paio di nodi nel package BiMorph. In particolare possiamo scegliere se estrarre i dati organizzati per colonna o per riga: nel nostro caso ci servono organizzati per colonna, come quelli che stiamo leggendo dallo spreadsheet, quindi il nodo che ci serve è Schedule.GetDataColumns. Purtroppo, il nodo pesca anche la dannata riga bianca tra le intestazioni e i dati, quindi tendenzialmente c’è da rimuovere l’indice 1 di ogni sottolista.
A questo punto abbiamo la lista dei valori letti da Excel e la lista dei valori presenti in una schedule creata usando le stesse intestazioni di Excel per individuare i parametri. Lo ripeto ancora una volta, il workflow funziona se a nessuno lato Excel viene la malsana idea di rinominare le intestazioni nella prima riga per renderle più pucciose.
Il confronto tra le due liste può essere banalmente fatto con un operatore condizionale, che oltre a confrontare valori può anche confrontare stringhe.
Otteniamo una lista di valori booleani che possono essere usati in una maschera, per individuare gli elementi di Excel che non corrispondono al modello o, alla bisogna, viceversa. Con quella lista di elementi possiamo fare tutto ciò che vogliamo: possiamo compilare un parametro in Revit, oppure – come vedremo nel prossimo set di esercizi – scrivere direttamente sul foglio Excel.
One Comment