Excel-automatisering

Ontwikkelingslogboek: wat een spreadsheet met 120.000 rijen feitelijk kapot maakt

Een werksessie over een spreadsheet van 121.254 rijen en 1,8 miljoen cellen, en de vijf afzonderlijke dingen die moesten veranderen voordat een grote analyse over meerdere tabellen kon worden voltooid, de uitvoer kon worden geverifieerd en een bruikbaar opgemaakt rapport kon worden geretourneerd.

De meeste spreadsheetfuncties worden getest op gegevens die op een scherm passen. Dit logboek omvat een werksessie aan een verkoopwerkboek met 121.254 rijen verdeeld over 15 kolommen — ongeveer 1,8 miljoen cellen - en een verzoek dat gewoon klinkt: combineer de product-, klant-, order- en verkooptabellen, markeer vervolgens afnemende producten, bevoorraad risico's en klanten met een lage waarde.

Niets aan dat verzoek is exotisch. Het mislukte hoe dan ook meerdere keren, om redenen die vrijwel niets met de analyse zelf te maken hadden. Wat volgt is wat er feitelijk kapot is gegaan en wat er is veranderd.

Een platformlimiet, geen langzame zoekopdracht

De eerste fout leek op een bug in het duurzame banensysteem. De echte oorzaak was een regel in Google Apps Script: Een editor-add-on mag geen tijdgestuurde trigger creëren die vaker dan één keer per uur wordt geactiveerd.

Bij het ontwerp van de achtergrondtaak werd uitgegaan van een trigger van één minuut. Deze aanname bleef gelden tijdens de ontwikkeling, waarbij een container-gebonden script vrij kon plannen, en stopte op het moment dat dezelfde code werd uitgevoerd als een geïnstalleerde add-on. Het verzoek om de trigger te installeren verslechterde niet - het gooide en het gooide eerder de taak was gemaakt, dus het werk is nooit begonnen.

Er volgden twee wijzigingen. Het installeren van een trigger is nu de beste inspanning: hij probeert een cadans van één minuut, valt terug naar elk uur en uiteindelijk helemaal geen trigger, en hij gooit nooit. En de eerste verwerkingsstap loopt nu binnen dezelfde uitvoering die de taak heeft aangemaakt, in plaats van in een tweede aanroep waarbij de taak opnieuw moet worden opgezocht.

Dat tweede detail was belangrijker dan het klinkt. Apps Script-eigenschappen zijn niet betrouwbaar voor het lezen van uw schrijfbewerkingen tijdens uitvoeringen, dus een taak die enkele ogenblikken eerder is geschreven, kan bij de volgende aanroep terugkomen als "taak niet gevonden".

Voortgang rapporteren is niet hetzelfde als afwerking

Toen de taak eindelijk begon, was deze nog steeds niet voltooid. De tool voerde één stap uit en retourneerde vervolgens de status waarin stond dat het werk 'op de achtergrond doorgaat'.

Die zin was vals. Omdat er geen trigger voor minder dan een uur beschikbaar is, gaat er niets door op de achtergrond. De assistent las de status, gaf een percentage door aan de gebruiker en stopte, waardoor een taak voor onbepaalde tijd op 34.000 van de 121.253 rijen geparkeerd bleef staan.

De runtime zorgt er nu voor dat de taak zelf wordt voltooid, binnen een beperkt budget, en elke volgende statusoproep brengt het werk vooruit in plaats van het alleen maar te lezen. Als het budget is uitgeput, zegt de statustekst duidelijk dat de taak nog niet is voltooid en dat niets anders deze kan bevorderen.

Het principe is de moeite waard om direct te vermelden: een voortgangsrapport is geen eindproduct. Een gebruiker vroeg om een ​​tabel, niet om een ​​percentage.

Een verzoek kan alleen worden uitgevoerd door tools die het model kan zien

Om de gereedschapsselectie accuraat te houden, maakt GetSheetAI per beurt een subset van zijn gereedschappen bekend op basis van het verzoek. Dat mechanisme is gebouwd rond de Excel-toolset, en de Google Sheets-add-on registreert 22 tools die alleen daar bestaan. Deze tools werden uit elk verzoek gefilterd.

Het effect was specifiek en gemakkelijk te missen. Als je om een ​​staafdiagram vroeg, werden 6 van de 44 tools zichtbaar, waarbij het diagramtool een van de verborgen tools was. Vragen om een ​​bereik te sorteren beschreven in 5 van 44, zonder de sorteertool. De assistent weigerde niet; hij kon echt niet zien welk gereedschap het werk doet.

Spreadsheets heeft nu zijn eigen tool-to-bundle-toewijzing, waarbij elke Excel-tegenhanger wordt gespiegeld, en het filter passeert elk hulpmiddel waar het geen mening over heeft in plaats van het te laten vallen. Een test leest nu de geregistreerde toolnamen rechtstreeks uit de broncode, dus het toevoegen van een tool zonder deze te classificeren mislukt de build in plaats van deze stilletjes onbereikbaar te maken.

Dezelfde klasse van hiaten kwam voor in de frasering. Een Chinees verzoek dat 'maak een nieuw blad' betekende, voldeed aan geen enkele regel, omdat het patroon slechts één van de twee veelgebruikte woorden voor een blad herkende. De tool voor het maken van werkbladen bleef verborgen en de assistent meldde dat het maken van een werkblad onmogelijk was. Dat was het niet.

Foutmeldingen maken deel uit van het product

Verschillende mislukkingen kwamen neer op een bericht dat een probleem vermeldde zonder de uitweg aan te geven.

Schrijven naar een blad dat niet bestaat, retourneert "De gevraagde bron bestaat niet." Dat leest als een kapotte invoegtoepassing. Er staat nu dat het blad niet bestaat, dat het schrijfgereedschap geen bladen maakt, en welke twee oproepen dat wel doen.

Het weigeren van classificatie op rijniveau voor een zeer groot bereik leverde een kale weigering op. Het labelen van een geaggregeerd resultaat werkt op elke grootte, dus het bericht noemt nu dat pad: eerst groeperen en vervolgens classificatieregels toepassen op het gegroepeerde resultaat.

Een overschrijfbeveiliging retourneerde niets anders dan blocked: true, wat als een fout wordt gelezen. Er wordt nu uitgelegd dat het doelwit al gegevens bevat en hoe verder te gaan.

Geen van deze is cosmetisch. In elk geval beëindigde het vorige bericht een taak die nog steeds kon worden voltooid.

Deterministische uitdrukkingen hadden meer rekenkunde nodig

Voor het afleiden van een jaar-maand zoals 201707 uit een datumsleutel met geheel getal zoals 20170702 is floor(x / 100) of een modulo vereist. Geen van beide bestond. Twee pogingen mislukten en de afgeleide kolom werd verlaten.

De expressielaag bevat nu floor, round, abs en mod, en de niet-ondersteunde functiefout geeft de volledige set weer en geeft die exacte expressie, in plaats van alleen te benoemen wat werd afgewezen.

Waar het staat

In dezelfde werkmap is het duurzame pad nu voltooid: alle 121.253 rijen zijn verwerkt, gegroepeerd, geschreven en geformatteerd, waarbij elk resultaatdeel is geverifieerd. Op Excel leverde hetzelfde verzoek een classificatie op voor alle 397 producten (132 zonder recente verkopen, 101 gemarkeerd vanwege herbevoorradingsrisico, 99 dalend, 65 normaal) berekend met native SUMIFS tegen de brontabel in plaats van de gegevens ergens anders naartoe te verplaatsen.

De wetenswaardige bedrijfswaarden:

  • duurzame routeringsdrempel: meer dan 100.000 cellen;
  • source chunking: begrensde leesbewerkingen, geverifieerd per chunk bij terugschrijven;
  • regressiedekking: 826 testen gedurende de gedeelde runtime;
  • achtergronduitvoering op add-ons voor Google Spreadsheets: op zijn best per uur, dus de zijbalk stuurt lange taken aan terwijl deze open is.

Dat laatste punt is eerder een reële dan een tijdelijke grens. Een geïnstalleerde add-on kan het werk niet vaker plannen, dus een grote taak wordt uitgevoerd terwijl de zijbalk geopend is. De duurzame controlepunten betekenen dat bij het sluiten geen voltooid werk verloren gaat, maar de eerlijke beschrijving is dat het werk wordt aangestuurd en niet gepland.

De bredere les uit deze sessie ging niet over schaal. Al deze fouten waren een gevolg van het feit dat het systeem iets wist dat de gebruiker niet kon zien: een platformregel, een verborgen tool, een ondersteund pad dat nergens in de fout werd genoemd. Het was de grootte die ze allemaal tegelijk zichtbaar maakte.