1. Kanban-tavle #
En af de ting man har mest behov for, er en kanban board af den ene eller anden slags. Dette gør dagligdagen nemmere, da dokumentation på igangværende og udførte opgaver er gemt. Herunder er et par eksempler på software, man kan bruge til dette formål. Der findes dog en uendelig mængde af muligheder.
Navn | Note | Link |
Microsoft Teams Microsoft Planner | Begge er inkluderet i de fleste O365 licenser til virksomheder. Teamet kan indeholde en Planner, og yderligere kan man lave kanaler som robotterne kan skrive debugging ind i, såfremt man bruger Power Automate som sit RPA-software. | https://www.microsoft.com/da-dk/microsoft-365/business/task-management-software https://www.microsoft.com/da-dk/microsoft-teams/group-chat-software?ms.url=teamscom Intern Power Automate – Introduktion |
Microsoft Devops Board | Et mere hardcore værktøj fra Microsoft, nok mest tiltænkt større teams/organisationer. | https://azure.microsoft.com/da-dk/products/devops/boards/ |
Monday | En online platform, hvor man kan skræddersy en løsning til projektstyring. De har et godt værktøj til at lave kanban tavler, hvor man kan tilpasse kolonner og trin i disse. | https://monday.com/work-management https://support.monday.com/hc/en-us/articles/115005317249-The-basics-of-a-board |
Et eksempel fra Monday om hvordan man kan sætte dette op.
2. Gevinstrealisering #
Når robotter overtager arbejde, så er det typisk en gevinstrealisering. Dette kan være sparet tid, penge, øget kvalitet af udført arbejde (mindske fejl, meget svær at følge op på) og lignende. Typisk er det noget afdelingerne selv, ledere eller lignende gerne vil følge med i. Man kan lave en kolonne i sit kanban board, og skrive en cirka årlig besparelse i denne. Det vil kun være et estimat, og kan være svært at tracke over robottens levetid.
Hvis man vil have et mere præcist tal, som også er gemt når en robot eventuelt pensioneres, så kan man eksempelvis bruge en database. Denne kan indeholde tabeller som en robot logger data i, hver gang den er færdig med en kørsel. På den måde kan man se mere præcist, hvad der bliver sparet løbende efter robotten er sat i drift. Det giver også historiske data, som man kan sortere i. Derfor er det en god idé at sætte dette op fra starten, selvom man ikke tænker man skal bruge det.
Det skal nævnes, at man ikke kan bruge disse tal til at måle produktiviteten i RPA-teamet. Hvorimod man kan sige at et årsværk i timer er 1924 timer, så kan det ikke forventes, at hver enkelt udvikler kan levere dette indenfor det første år af projektet. Yderligere når man har været gang i en årrække, kan man have et år, hvor der ikke bliver udviklet meget nyt, men hvor tidligere robotter forsat tæller op i timerne. Det er heller ikke alle processer som har en direkte tidsbesparelse eller monetær værdi. Mindre robotter kan være en kvalitetssikring, der mindsker fejl af udført arbejde, som ellers ville have kostet tid/penge i den anden ende. Yderligere vil der gå tid med læring og øvelse, og det vil være en løbende proces igennem årene. Endvidere jo flere robotter man har, jo mere vedligehold vil man også have. Der kan også være tidspunkter, hvor man investere tid til at udvikle skabeloner (genbrugligt kode, API-opsætninger m.m.), hvor gevinsten først ses senere i forløbet. Hvis man har robotter kørende i årevis, tjener de deres udviklingstid tilbage, og vil give et naturligt overskud fremover. Af denne årsag burde man over en årrække kunne se, at man får flere årsværk ud af projektet end det man har investeret.
Tabel til logning af kørsler. Antal vil være hvad robotten udfører. Det kan være man måler besparelsen per delopgave der udføres, eksempelvis +1 per faktura der laves. I andre scenarier hvor det kan være svært at måle i delopgaver, men man ved cirka hvad total besparelsen i tid er per gang robotten kører, kan man notere antal som 1 altid per kørsel. Man kan også tage en gevinst for at robotten starter, og tjekker om den har noget at lave. Som eksempel kan det være at tjekke en indbakke for relevante mails, som skal behandles, ligesom en medarbejder ville sætte tid af til.
ID | Robotnavn | Dato | Antal |
Tabel til besparelse per kørt antal for en robot. Heri vil man have en række per robot, som man så kan koble op med den anden tabel og regne total besparelsen sammen. Sekunder er den besparelse der er i sekunder per antal kørsler der findes (eksempelvis 300 sekunder per udfyldt faktura), og det samme med kroner hvis dette er relevant.
ID | Robotnavn | Fagområde | Sekunder | Kroner | Ajourføring | Kommentar | Procesejer | Udvikler |
Hvis man vil udstille sin data (datavisualisering), kan man benytte nedenstående til formålet.
Navn | Note | Link |
Power Pivot | Indbygget funktionalitet i Excel | https://www.rpahelp.org/docs/microsoft-excel/#7-toc-title |
Microsoft Power BI | Power BI – Introduktion – RPA Help https://www.microsoft.com/en-us/power-platform/products/power-bi | |
Metabase | https://www.metabase.com/ |
3. Procesdokumentation #
Det er svært at sige hvad og hvor meget dokumentation, man reelt skal bruge til sine robotter. Der er ikke nogen faste krav, man skal dog have noget liggende omkring hver robot. Der er ikke behov for at tage billeder af hver enkelt klik, som man laver med musen eller lignende. Det er meget tidskrævende at lave sådan dokumentation, og samtidigt er det heller ikke retvisende for, hvordan robotten reelt udfører opgaven. Det kan være procesejeren skal igennem en brugergrænseflade for at udføre opgaven, hvor robotten kan gøre det via scripts med API-kald.
Herunder er hvad jeg selv benytter af afsnit, og en kort beskrivelse af hvad disse indeholder. Selve dokumentationen er linket på et kanban board, hvor der findes yderligere information om procesejeren, gevinstrealisering m.m..
- Procesbeskrivelse – En kort overordnet beskrivelse af processen, som robotten skal udføre.
- Beskrivelse af kode – En kort beskrivelse af hver subflow i koden, og hvad denne foretager sig.
- Flow diagram – Et flow diagram som viser processen. Denne afspejler også relationen imellem nogle subflows i koden.
- GDPR overvejelser – Et afsnit der kun findes, såfremt der har været GDPR-overvejelser med i processen.
- Eventuelle bilag
3.1 Eksempel #
Følgende er et eksempel fra en modul opbygget proces til at uploade digitale blanketter til et ESDH system.
1. Beskrivelse #
Selve koden er udviklet til at arbejde i robot-brugernes indbakke, hvor den gennemgår mails fra XFlow, og journalisere blanketter til eDoc sager. Dette betyder at i takt med at behovet opstår, kan man løbende opsætte nye cases til enten robot-brugere i 10.10 eller blanketter i 20.10.
Liste over blanketter som robotten håndterer:
Fagområde | Blanket | Kommentar |
VIS | Diæt og Befordring | Tager sig af alle 6x blanketter (Beboerklagenævnet, Bevillingsnævnet, Børn og Ungeudvalget, Handicaprådet, Hegnssyn, Huslejenævnet) |
2. Kodebeskrivelse #
Kort overblik over variablerne som bruges til eDoc API’et, og hvad disse gør:
Navn | Beskrivelse |
BoolEdocDokument | Bruges til at aktiver en else-if, så robotten trækker EdocDokumentID ud af JSON |
BoolEdocProjekt | Bruges til at aktiver en else-if, så robotten trækker EdocProjektID ud af JSON |
EdocCaseFileIdentifier | En sags unikke ID i backend |
EdocDokumentDato | Påkrævet når der journaliseret, som udgangspunkt dagsdato dd-mm-yyyy. Kan overskrides ved behov, da den nulstilles imellem hvert loop. |
EdocDokumentID | Et dokuments unikke ID i backend |
EdocDokumentNr | Et dokuments nummer ud mod brugergrænsefladen |
EdocKategori | ID’et på den kategori som skal bruges, for liste se: R:\SCRIPTS\PowerShell\eDoc\GetItemList\edoc\CaseCategory.txt |
EdocOpretSag | Bruges i en Switch til at afgøre hvad skal oprettes |
EdocProjektID | Et projekts unikke ID i backend |
EdocProjektNr | Et projekts nummer ud mod brugergrænsefladen |
EdocSagsbehandler | Initialerne på en sagsbehandler |
EdocSagsnummer | En sags nummer ud mod brugergrænsefladen |
EdocSkabelon | Den skabelon som skal bruges til oprettelse |
EdocSøgEfter | Bruges i en Switch til at afgøre hvad der skal søges efter |
EdocTitel | En titel i eDoc enten til søgning eller oprettelse |
EdocType | eDoc sagstypen: Slettet sag Administrativsag Borgersag Ejendomssag PPR – Sag |
JSONEdocJournaliser JSONEdocOpret JSONEdocSøg | De respektive JSON filer som indlæses efter hvert API kald. Som udgangspunkt levere de kun en EdocCaseFileIdentifier, EdocProjektID eller EdocDokumentID tilbage. Resten skal man selv lave i sin kode hvis der er behov for at trække yderligere ud. |
Koden er delt op i følgende subflows, hvori der er kommentarer med #TODO i koden, hvis man aktivt skal foretage ændringer:
Main: Dette er hovedfunktionen, der orkestrerer hele processen. Herfra kaldes andre funktioner i rækkefølge, for at håndtere forskellige dele af arbejdsgangen.
00.10 Initialize: Forbereder miljøet ved at opsætte nødvendige variabler, mapper og logdetaljer. Heri findes variabler til debugging og logning til SQL, som skal overskrides til nyt brug.
99,99 Exit: Håndterer oprydningen og logningen i slutningen af processen, herunder afsendelse af fejlrapporter, hvis det er nødvendigt.
Global Error Handler: Giver en mekanisme til at fange og logge fejl, der opstår under udførelsen af automatiseringen, som ville stoppe processen helt fra at afvikle. Dette sikrer, at eventuelle problemer registreres, og en fejlmeddelelse sendes til udvikler.
00.20 – MonthNumber to MonthName: Laver kørselsdatoens måned om til månedens navn i “MonthName” variabel. Tiltænkt hvis man har behov for at navngive sager / dokumenter med indeværende måned.
10.10 – Loop credentials: Ud fra forudindstillede cases, køres hver enkelt robot bruger igennem, og tjekker efter mail i dennes postkasse. Hvis relevant køres 20.10 efterfølgende.
20.10 – Loop emails: Har en Switch indbygget, hvor der skal være en Case per XFlow blanket.
20.20 – Find vedhæftninger: Finder PDF og JSON filen fra vedhæftninger på mailen.
20.30 – Afslut behandling: Tæller +1 på SQL, flytter mailen til behandlet mappen i postkassen, og nulstiller alle relevante variabler så de ikke forstyrrer næste loop.
30.10 – eDoc søg: Bruges til at kunne søge efter sag, dokument eller projekt. Returnere enten en EdocCaseFileIdentifier eller EdocProjektID.
EdocSøgEfter | Mulige variabler til søgning |
Sag | EdocCaseFileIdentifier EdocSagsbehandler EdocSagsnummer EdocType VarCPR |
Projekt | EdocProjektID EdocProjektNr |
Dokument | EdocCaseFileIdentifier EdocDokumentID EdocDokumentNr EdocSagsbehandler EdocType |
Default | ErrorList – “30.10 – Sagstype blev ikke genkendt, sprunget over – %EdocOpretSag%” Next Loop |
Error Handling | ErrorList – “30.10 – ScriptError fandt sted ved søgning – %ScriptError%” CurrentMail flyttes til ErrorMailFolder Next Loop |
Return | JSONEdocSøg EdocProjektID eller EdocCaseFileIdentifier |
30.20 – eDoc opret: Kan bruges til at oprette nedenstående
EdocOpretSag | Mulige variabler til oprettelse |
Borger (Borgerskabelon) | EdocKategori EdocProjektID EdocSagsbehandler EdocSkabelon EdocTitel VarCPR |
Ejendom (Ejendomsskabelon) | EdocKategori EdocProjektID EdocSagsbehandler EdocSkabelon EdocTitel VarBFE |
Sagskabelon | EdocKategori EdocProjektID EdocSagsbehandler EdocTitel EdocSkabelon |
Sag | EdocKategori EdocProjektID EdocSagsbehandler EdocTitel EdocType |
Projekt | EdocKategori EdocSagsbehandler EdocTitel |
Default | ErrorList – “30.20 – Sagstype blev ikke genkendt, sprunget over – %EdocOpretSag%” Next Loop |
Error Handling | ErrorList – “30.20 – ScriptError fandt sted ved oprettelse – “%ScriptError%”” CurrentMail flyttes til ErrorMailFolder Next Loop |
Return | JSONEdocOpret EdocProjektID eller EdocCaseFileIdentifier |
30.30 – eDoc journaliser filer: Journalisere filerne som er tilknyttet %ListUpload%. Vær opmærksom på at dokument status altid er sat til “Endelige”, har man brug for andet se afsnit om vedligehold, og opret variabel til dette.
Oversigt | Variabler |
Journaliser | EdocCaseFileIdentifier EdocType EdocSagsbehandler EdocTitel ListUpload |
Error Handling | ErrorList – “30.30 – ScriptError fandt sted ved journalisering af %EdocTitel% til %EdocSagsnummer% – “%ScriptError%”” CurrentMail flyttes til ErrorMailFolder Next Loop |
Return | JSONEdocJournaliser EdocDokumentID |
3. Ny blanket huskeliste #
I 20.10 – Loop, laves en ny case, som skal hedde det samme som mailemnet -PVA. XFLowPDFName variablen udfyldes med filnavnet på PDF-filen med XFlow blanketten -pdf (robotten finder selv ud af (1) (2) og lignende ekstra autonummering). Hvis der er yderligere vedhæftninger som skal journalisere, sætter man BoolMultiAttachments til true. PDF af XFlow blanketten vil altid være hoveddokumentet, JSON springes over da den ikke er relevant, og alle andre vedhæftninger sættes på listen vilkårligt. Hvis det er simpel journalisering, kan man nøjes med at udfylde variablerne til journaliseringen, og efterfølgende køre 30.30 – Edoc journaliser filer. Har man behov for at trække data ud af blanketten, lave et større mængde kode, så opretter man en 40.xx +1 fra sidst oprettede, og udfylder denne med arbejdsgangen. Se eventuelt 40.00 som eksempel. Dette for at undgå at 20.10 bliver uoverskuelig.
Hvis man skal bruge flere variabler end dem som eksistere, eksempelvis til logik, må man gerne lave en forkortelse og sætte foran navnene, så det er nemt at se hvilke variabler hører til hvilken blanket. Eksempelvis hvis blanketten hedder “Ferie – Aftale om afvikling på forskud” man kan forkorte det ned til eksempel FerieAAF<variabelnavn> og sætte det reelle variabel navn bagved. Man kan eventuelt også sætte det i en kommentar øverst i casen.
4. Vedligehold #
Det mest almindelige vedligehold vil være behovet for at kunne udfylde en variabel til et API-kald, som ikke i forvejen er skrevet ind. Det er direkte ULOVLIGT at hardcode det ind i feltet, da det vil have indflydelse på alle andre blanketter fremover også. Hvis man som nedenfor eksempel har brug for BOM Sagsnummer, er det lovligt at lave en variabel til dette. Den skal dog hedde Edoc + det som står ud fra teksten, i eksemplet EdocBOMSagsnummer. Herefter må man gerne tjekke 30.10, 30.20 og 30.30 igennem for at se om andre API-kald også har denne og udfylde.
Til sidst –SKAL– den nulstilles i 20.30 – Afslut behandling i regionen til nulstilling. Eller risikere man at den forsat lever videre i næste loop.