Hävikki – Miten minimoida sitä raportoinnin avulla?

Nykypäivänä puhutaan paljon siitä, kuinka paljon ruokaa heitetään roskiin hyvinvointivaltioissa, ja kuinka taas toisaalla kärsitään nälkää. Kuluttajatasolla jokainen voi itse parantaa vanhaksi menneiden ruokien seurantaa, mutta entä sitten ruokien valmistajat? Roskiin heittäminen on firmalle tietenkin kannattamatonta, mutta myös yhteiskunnan, ilmaston ja kulutuksen kannalta epäeettistä.

Ruokavalmistajan on hyvä varmistaa, ettei varastoon jää vanhaa tavaraa ja ettei elintarvikkeissa tule päivämäärät vastaan. On myös tärkeää, että saadaan pidettyä varastossa oleva tavara mahdollisimman tuoreena. Dataa ja tietovarastoa voidaan käyttää monella tapaa hyödyksi, myös tämänkin seuraamisessa ja hävikin pienentämisessä.

Kun meillä on valmistettujen tuotteiden data tallessa, niin voidaan seurata sekä tuotteiden tuoreutta että yrittää kiihdyttää myyntiä niiden tuotteiden osalta, joilla päivämäärät ovat tulossa vastaan. Tarvitsemme tuotteista oikeastaan vain perustietojen lisäksi valmistuspäivämäärän. Toki myös tiedon siitä, että montako päivää tuote on tuore eli montako päivää lisätään valmistuspäivämäärään, että saadaan sille viimeinen käyttöpäivä tai parasta ennen päivämäärä, esimerkiksi + 10 päivää. Sekä koska voimme viimeistään toimittaa tuotteen kauppoihin myyntiin, esimerkiksi +5 päivää.

Esimerkkituotteena Oiwa reikäleipä, valmistuspäivämäärä 4.6.2019. Laskennallisesti parasta ennen päivämäärä on 14.6.2019 ja viimeinen toimituspäivämäärä on 9.6.2019. Haluamme kyseiset reikäleivät raportillemme silloin, kun viimeiseen toimituspäivämäärään on aikaa kaksi päivää. Näin tiedämme kuinka paljon mitäkin tuotetta täytyy saada maailmalle vielä, kun se on mahdollista ja ehtii kauppoihin.

Jos haluammekin vielä tarkempaa dataa tuoreudesta ja siitä kuinka tuoreena tuotteet saadaan liikkeelle, niin voimme laskea esimerkiksi päiväkohtaista tuoreusprosenttia haluamillemme tuotteille. Yritykselle on tietenkin kannattavaa, että saadaan optimoitua valmistusprosessit niin, että tuotteet ovat valmiina vähän ennen toimitusta, jolloin saadaan tuotteet lähtemään mahdollisimman tuoreina ulos. Tämä on myös osa laatua, ja liittyy osaltansa toimitusvarmuuteenkin. Kaikki yritykselle tärkeitä asioita.

Entä sitten kuluttaja? Mitä jos meillä olisi jääkaapin ovessa integroituna listaus tuotteista, joissa olisi viimeinen käyttöpäivä huomenna. Uskon, että ruokahävikki pienisi kotitalouksillakin!

Huono toimitusvarmuus syö katetta ja vie asiakkaita. Mikä avuksi?

Toimitusvarmuus on tärkeä osa yrityksen laadunvalvontaa sekä asiakastyytyväisyyden seurantaa. Samoin liikevaihdon ja kannattavuuden kannalta yksi tärkeistä mittareista monien joukossa. Jatkuva vaje toimituksissa aiheuttaa luonnollisesti liikevaihdon laskua ja sen aiheuttamat selvittelytyöt pienentävät katetta. Se, puhutaanko toimitusvarmuudesta vai -kyvystä, menee usein sekaisin. Toimituskykyä on vaikkapa se, että pystytäänkö vastaamaan kysyntään ja ottamaan tilauksia vastaan niillä määrillä ja toimitusajoilla, joilla halutaan. Tässä kirjoituksessa avaan paremminkin toimitusvarmuutta laajemmin, sillä tästä aiheesta ei mielestäni puhuta vielä tarpeeksi.

Puutteellinen tilaus on lähes aina reklamaation aihe, jota käsitellään ja hyvitellään. Tai sitten se on jatkuva prosessi jälkitoimituksineen. Kaikki tuo aiheuttaa kuluja, joita suurelta osin voitaisiin välttää. Aina tulee olemaan tilanteita, ettei kaikkea tilattua määrää pystytä toimittamaan. Näitä tilanteita pitää pyrkiä vähentämään.

Samoin pitää oikeastaan suhtautua myös tilauksiin, joissa toimitettu määrä on suurempi kuin tilattu määrä. Ellei ylimenevää määrää laskuteta, on asiakas mitä ilmeisimmin tyytyväinen. Katetta tuo ei kuitenkaan paranna. Ja väittäisin, että tuolla on vaikutusta asiakastyytyväisyyteenkin. Positiivisesti? Ei välttämättä. Ainakin se on merkki yrityksen laadun tasosta ja sitä kautta aiheuttaa epäilyksiä ja epävarmuutta muihinkin toimituksiin. Usein toistuvat puutteelliset tilaukset joka tapauksessa on huonon laadun merkki sekä heikentää asiakastyytyväisyyttä. Pahimmillaan jos puhutaan esim. sähköisestä asioinnista, jossa asiakas tilaa ensimmäistä kertaa jotain tuotetta saaden siitä vain osan, on suuri pelko, ettei tämä asiakas tilaa toista kertaa mitään. Eli kerran koukutettu asiakas annetaan kadota saman tien.

Toimitusvarmuuteen on seurannan avulla hyvä panostaa ajoissa silloinkin, kun kaikki on kunnossa. Mahdollisten tilausmäärien kasvun myötäkään sen ei saisi pettää. Jotain tuotetta voidaan ruveta tilaamaan jonkin buumin, kampanjan tai markkinoinnin myötä koko ajan kasvavasti. Silloin on vaarana, että toimitusvarmuus kärsii. Jos tuotteiden seuranta on kunnossa, nähdään ongelmat ajoissa ja niihin pystytään puuttumaan heti alussa. Eikä vasta jälkikäteen, kun on jo menetetty rahaa ja kulutettu aikaa toimitusten selvittelyihin. Samoin, jos jo etukäteen nähdään, että tilausta ei saada täydellisenä perille, voidaan informoida asiakasta. Tällöin asiakaskokemus sekä -tyytyväisyys ovat varmasti paremmat kuin jos hän itse joutuu näistä jälkikäteen reklamoimaan.

Seuranta rakennetaan yleensä ryhmätasolla. Eli esimerkiksi asiakasryhmä- tai tuoteryhmätasolla kuukausittain. Näistä toki päästään aina pureutumaan tuote- tai asiakastasollekin. Tässä saattaa olla riskinä se, että esim. tuoteryhmätasolla toimitusvarmuus näyttää kohtalaisen hyvältä eikä siihen tulla puuttuneeksi. Tuoteryhmän sisällä kuitenkin saattaa jokin yksittäinen tuote sakata pahastikin muuttamatta paljon keskiarvoa. Tuote voi olla merkittävä asiakkuuksissa ja aiheuttaa hyvinkin paljon harmia. Äkillisen romahtamisen ehkä huomaa jotain kautta muutenkin, mutta pikkuhiljaa tapahtuva heikkeneminen on hankalampi havaita. Nämä pitää järjestelmän pystyä nostamaan esille normaalin seurannan yhteydessä joko indikoimalla summatasot tai tuomalla omina hälytysriveinään tai mittareinaan seurannan työpöydälle. Näihin sitten pitää pureutua syvemmälle, että syy selviäisi ja saadaan tilanne korjattua.

Nyt edellä on tullut puhuttua pelkästään määristä. Toimitusvarmuutta on kuitenkin esim. oikea määrä, hinta, aika sekä myös kaikki sovitut kuljetus tai toimitustavat pitää mennä oikein. Toimitusvarmuus on osa laadunvalvontaa mutta myös toimitettujen tuotteiden laatu pitää olla kunnossa. Se taas on osa toimitusvarmuutta. Kaikkea tuota seuraamalla nähdään aito kuva yrityksen toimitusvarmuudesta ja sitä pystytään systemaattisesti parantamaan. Seuranta onnistuu, kunhan tietoa kerätään ja analysoidaan oikein. Tämä on yksi tärkeä asia mitä me Oiwassa tehdään yhteistyössä asiakkaiden kanssa.

Laadukas data on yrityksen tärkeimpiä asioita

Yritykset saavat järjestelmistä paljon tietoa, mutta onko se hyödynnetty kaikilta osin ja kuinka laadukasta data on? Yrityksissä ei välttämättä edes olla tietoisia kaikista dataongelmista. Tärkeää olisi huomioida myös onko kaikki asiat osattu ottaa huomioon. Tämän takia yrityksessä olisikin hyvä olla tiedon laatuvastaava, jonka tehtävänä on seurata datan oikeellisuutta, kehittää tarvittavat prosessit ja ohjeistaa käyttäjät tekemään asioita oikein.

Tietovarastoinnin automatisoiduissa prosesseissa valvotaan datan virheitä ja puutteita sekä voidaan ohjata raja-arvoihin sopimattomat arvot virheiksi. Datan oikeellisuuden varmistamiseksi tehdään myös tarkistusprosesseja, joissa verrataan datoja keskenään ja etsitään poikkeamia. Virheelliset tiedot ohjataan automaattisesti virheiksi, joita seurataan päivittäin. Virheellinen data voidaan korjata operatiivisessa järjestelmässä heti ja tiedot saadaan oikeellisiksi pikaisesti. Yrityksissä on paljon myös tietoja, joilla on erityiset vaatimukset tiedon oikeellisuudesta, kuten taloushallintoon liittyvällä datalla.

Virheet voidaan ottaa siis kiinni jo datan latauksissa eikä vasta sitten, kun raportit näyttävät vääriä lukuja. Väärät luvut voivat olla raportilla pitkäänkin, ennenkuin joku huomaa ne ja näin on saatettu tehdä vääriä tulkintoja jo kauankin. Huonolla datalla voidaan tehdä vääriä päätöksiä tai pienillä asioilla voi olla suuriakin vaikutuksia.

Kilpailu on kovaa ja toiminnan pitäisi olla mahdollisimman kustannustehokasta. Tuotekustannuksen komponentteja on toimijasta riippuen useita. Esim: raaka-ainekustannukset, pakkaustarvikkeet, työkustannukset, logistikan kustannukset sekä markkinoinnin kiinteät. Jos näistä joku on analysointimielessä annettu puutteellisesti, aiheuttaa se vääristymän katteessa. Jos yksi näistä kustannuksista jää antamatta tai annetaan vaikka sen voimassaoloaika väärin, jää tuotteen kustannuksista esim 0,05 euroa pois. Vielä jos tämä osuu jonkin volyymituotteen, kuten kaupan merkkituotteen, kohdalle niin virhe kertautuu jo huomattavasti. Esimerkiksi asiakasryhmän omalla merkkituotteella 100 000 kiloa kuukaudessa muuttaa tuolla puuttuneella kustannuksella katteen 5000e paremmaksi, kuin mitä pitäisi. Toinen asiakasryhmä ei osta tuota tuotetta, joten sen kate on oikein, mutta jää virheen takia vertailussa kaikenaikaa heikommaksi. Tätä ei välttämättä heti huomata raportilla, mutta datan käsittelyssä tämä olisi helppo saada kiinni ja heti korjattavaksi.

Tiedon laatu on siis yksi tiedolla johtamisen tärkeimpiä asiota. Oletko miettinyt missä kunnossa datanne on? Viimeistään nyt kannattaisi ottaa tämä kallisarvoinen asia työpöydälle eikä enää jättää sitä vain puheiksi.

Käytännöllinen työkalu tietokannan versionhallintaan

Versionhallinta on koitunut yllättävän hankalaksi tietovaraston ylläpidossa. Tälle on useita syitä. Yksi suurimpia syitä mielestäni on se, että SSMS (SQL Server Management Studio) ei tue suoraan versionhallintaa. Tähän kyllä löytyy maksullisia kolmannen osapuolen työkaluja. Toisena vaihtoehtona on tietokantaprojektit. Tämä kuitenkin määrää sen, että kaikki muutokset tulee tehdä tietokantaprojektin kautta, jolloin ne päätyvät versionhallintaan. Synkronoinnin voi myös tehdä jälkeenpäin, mutta tällöin ei ole varmuutta, että kaikki välivaiheet muutoksissa säilyisivät.

Tämän pohjalta heräsi idea. Miksi pakosti muuttaa tapojaan, kun suurin tarve versionhallinnalle piilee kuitenkin historian ja muutosten säilymisessä, jos unohdetaan branchit ja muut hienoudet. Eikö muutoksia saisi talteen ilman, että käyttäjän tarvitsee tehdä mitään? Tästä syntyi idea ja sen pohjalta kehittelin pienen työkalun:

Mitä giffissä tapahtui:

  1. Tein muutoksen proseduuriin ajamalla ALTER-lauseen
  2. Scripti poimi muutokset automaattisesti
  3. Muutokset vietiin Azure DevOps (VSTS) versionhallintaan

Mitä pinnan alla tapahtui:

  1. ALTER lause käynnisti tietokantatriggerin, joka poimi muutokset logi-tauluun
  2. Sovellus pollasi logi-taulua ja löysi uuden rivin
  3. Sovellus haki kannasta objectille CREATE lauseen ja tallensi sen levylle .sql -tiedostoon, git repositoryyn
  4. Muutoksille tehtiin commit ja pushattiin remoteen (VSTS)
  5. Logi-taulusta tyhjättiin edelliset muutokset

Hyvin yksinkertainen konsepti, joka ei rasita liialti kantaa. Suurin kuorma tuleekin scriptien generoinnissa ja levylle kirjoittamisessa, mutta sovelluksen voikin laittaa pyörimään, mille tahansa koneelle, jolta on pääsy kantaan. Tyhjän taulun pollaus ei juurikaan rasita kantaa ja pollauksen voi tehdä itselleen sopivalla intervallilla. Kaikki muutokset löytyvät kuitenkin taulusta, jolloinka ei ole väliä kuinka nopealla syklillä muutoksia poimitaan versionhallintaan. Pollaus ei toki ole tässä tapauksessa paras vaihtoehto, mutta esimerkiksi Service Brokerin käyttöönotto vaatisi muutoksia nykyisiin kantainstansseihin, mikä ei ole tämän projektin tavoite.

Tarkkasilmäisimmät varmaan huomasivat, että muutoksella ei ollut järkevää kommenttia. Kommentit toki ei ole mahdollisia, jos kaikki on automaattista. Mielestäni pääasia tässä ei olekaan täydellisen versiohallinnan ja muutosten selittäminen, vaan historian mahdollistaminen ympäristöissä, joissa ei muuten jäisi historiaa talteen.

Tällä hetkellä scripti poimii proseduurien, funktioiden, taulujen ja näkymien muutokset. Tätä on helppo laajentaa sillä triggereitä on helppo jatkaa ja SMO mahdollistaa helpohkon tavan luoda erilaisille objecteille scriptejä.

Jos kiinnostus heräsi, alla on linkki github repositoryyn, jossa voit käydä selailemassa koodeja tai käydä lataamassa sovelluksen itsellesi. Asennukseen on muutama scripti ja ohjeet. Githubiin tullaan myös julkaisemaan jo tiedossa olevat ongelmat. Jos heräsi kysymyksiä tai kommentteja, jätä viestiä githubiin tai laita postia timo.myllymaki@oiwasolutions.fi.

https://github.com/oiwa-solutions/sql-server-git-sync

SQL Tips: Harmeja NULL-arvosta

SQL-kyselyissä NULL-arvot aiheuttavat usein harmeja. On tärkeää ymmärtää, että NULL tarkoittaa puuttuvaa arvoa. Se ei tarkoita välilyöntiä eikä nollaa vaan tuntematonta arvoa. Jos mahdollista, pyri muuttamaan NULL-arvot aina joko nollaksi (0) tai tyhjäksi (’’) niin säästyt monelta harmilta.

Totuus on, että tauluista löytyy kuitenkin aina myös NULL-arvoja. Siksi onkin syytä huomioida, ettei NULL käyttäydy samoin kuin muut arvot.

Tässä ensin esimerkkitaulujen tiedot ja esimerkit NULL-arvojen toiminnasta.

Jos laskukaavassa on mukana NULL-arvo palauttaa laskenta aina NULL. AlennettuHinta jää siis laskennassa NULL-arvoksi, koska Alennus on NULL.

NOT IN kyselyssä Fakta-taulun TuoteID on NULL-arvo, joten seuraava lause ei palauta mitään vaikka periaatteessa TuoteID 223 puuttuukin Fakta-taulusta.

NULL ei toimi taulujen liitoksissa (JOIN tai MERGE). Vaikka molempien taulujen avainkentässä olisi NULL, niin se ei yhdistä rivejä ja rivi jää puuttumaan. Esim. jos Fakta2 taulu olisi samanlainen taulu kuin Fakta ja yhdistetään ne TuoteID sekä Yhtio kenttien avulla. Kysely ei palauta yhtään riviä vaikka TuoteID 222 löytyykin molemmista tauluista ja Yhtio molemmissa on NULL.

Merge lauseessa syntyy joka kerta uudet rivit, koska NULL-arvo ei yhdistä avaimia.

Ongelman voi kiertää NULL tarkistuksilla, kuten esim. lisäämällä IS NULL -ehdot tai käyttämällä COALESCE()-funktiota.

Tai

Saatat myös ymmärtää NULL-arvon ja tyhjän arvon eron seuraavan havainnollistavan kuvan avulla:


Kuva: DevRant

SQL Tips: INT-muotoisen kentän jakolaskut

Jakaessa kahta INT-tyyppistä kenttää keskenään tulos on aina myös INT ja vieläpä niin, että tulosta ei pyöristetä, vaan se katkaistaan.

Esim. alla oleva SQL-lause palauttaa vastaukseksi 1.

SELECT 9 / 5

Jos taas lauseen jompikumpi arvo konvertoidaan desimaaliksi esimerkiksi näin

SELECT 9 * 1.0 / 5

tai näin

SELECT CAST(9 as float) / 5

palauttaa SQL vastaukseksi 1,8.

Samoin toimii sisäänrakennetut aggregointifunktiot, esim. AVG.

Esim. Tässä yksinkertainen taulu, jossa int-tyyppisessä kentässä arvoja

Normaali AVG-funktio palauttaa keskiarvoksi 2.

Kun taas konvertoituna palauttaa näin

Desimaalin muuttamiseksi kannattaa valita kyselyyn sopiva suorituskykyisin keino

Tekoäly vedenkulutuksen jäljillä

Optical character recognition (tekstintunnistus) on jo vanha tekniikka, mutta uusia käyttökohteita sille keksitään varmasti jatkuvalla syötöllä. Kaikille lienee tuttu aihe esimerkiksi ajoneuvon rekisterikilven koneellinen lukeminen tai postin lajittelu koneellisesti. Molemmissa tapauksissa syötteestä tunnistetaan automaattisesti tekstiä.

Periaatehan OCR:ssä on hyvin yksinkertainen; se on joko mekaaninen tai sähköinen prosessi, jossa pyritään tunnistamaan tekstiä ja saattamaan se käyttäjälle helpompaan muotoon. Normaalisti se helpompi muoto on digitaalinen muoto, mutta aikanaan on käytetty myös esim. äänimerkkejä (savumerkeistä en tiedä).

Omat OCR-kokeiluni olen aloittanut noin kymmenisen vuotta sitten. Tein silloin kotiautomaatioprojektia, jossa halusin myös vesimittarin lukeman digitaaliseen muotoon – ja mieluiten reaaliajassa. Tuossa tapauksessa en käyttänyt mitään valmiita kirjastoja, vaan “opetin” koodini tunnistamaan vesimittarissa käytettävät numerot. Siihen aikaan se oli vielä mekaaninen rullamittari. Hieman nihkeää pikselitason koodailua, mutta toimiva tuli. Ja reaaliajassa lukemat sai kiinni, kun webbikamera oli asennettuna vesimittarin päälle ja kameran livekuvasta tehtiin frame kerrallaan tunnistusta.

Nykypäivänä voidaan helposti tehdä tekstintunnistussovelluksia, joissa käytetään valmiina olevia OCR-tekoälykirjastoja. Nämä kirjastot ovat opetettu tunnistamaan erilaista tekstiä ja tukemaan eri kieliä. Samoissa kirjastoissa saattaa olla tuki myös muulle kuin OCR:lle, vaikkapa hahmontunnistus. Osa kirjastoista on myös sellaisia, että niitä voidaan jatko-opettaa. Esimerkiksi puuttuva kielituki saadaan, kun opetetaan uusi kieli itse. Näiden kirjastojen käytöllä oman koodin tuottamisen tarve on vähäinen ja (tekoäly)projektien aloituskynnys on matalalla.

Vesimittarin luenta tekoälyvälineillä

Optical character recognition (tekstintunnistus) on jo vanha tekniikka, mutta uusia käyttökohteita sille keksitään varmasti jatkuvalla syötöllä. Kaikille lienee tuttu aihe esimerkiksi ajoneuvon rekisterikilven koneellinen lukeminen tai postin lajittelu koneellisesti. Molemmissa tapauksissa syötteestä tunnistetaan automaattisesti tekstiä.

Periaatehan OCR:ssä on hyvin yksinkertainen; se on joko mekaaninen tai sähköinen prosessi, jossa pyritään tunnistamaan tekstiä ja saattamaan se käyttäjälle helpompaan muotoon. Normaalisti se helpompi muoto on digitaalinen muoto, mutta aikanaan on käytetty myös esim. äänimerkkejä (savumerkeistä en tiedä).

Omat OCR-kokeiluni olen aloittanut noin kymmenisen vuotta sitten. Tein silloin kotiautomaatioprojektia, jossa halusin myös vesimittarin lukeman digitaaliseen muotoon – ja mieluiten reaaliajassa. Tuossa tapauksessa en käyttänyt mitään valmiita kirjastoja, vaan “opetin” koodini tunnistamaan vesimittarissa käytettävät numerot. Siihen aikaan se oli vielä mekaaninen rullamittari. Hieman nihkeää pikselitason koodailua, mutta toimiva tuli. Ja reaaliajassa lukemat sai kiinni, kun webbikamera oli asennettuna vesimittarin päälle ja kameran livekuvasta tehtiin frame kerrallaan tunnistusta.

Nykypäivänä voidaan helposti tehdä tekstintunnistussovelluksia, joissa käytetään valmiina olevia OCR-tekoälykirjastoja. Nämä kirjastot ovat opetettu tunnistamaan erilaista tekstiä ja tukemaan eri kieliä. Samoissa kirjastoissa saattaa olla tuki myös muulle kuin OCR:lle, vaikkapa hahmontunnistus. Osa kirjastoista on myös sellaisia, että niitä voidaan jatko-opettaa. Esimerkiksi puuttuva kielituki saadaan, kun opetetaan uusi kieli itse. Näiden kirjastojen käytöllä oman koodin tuottamisen tarve on vähäinen ja (tekoäly)projektien aloituskynnys on matalalla.

Mikä oli sitten testauksen lopputulos? Jos lähdetään liikkeelle OpenCVSharp3 -kirjaston käytöstä USB-kameran kanssa, niin se toimi juuri niin kuin pitikin. Helppo käyttää ja omaa koodia tarvitaan melko vähän. Tesseract -kirjaston peruskäyttö on myös helppoa ja oman koodin tarve vähäinen. Tesseract on kuitenkin hirveän tarkka sisään menevästä syötteestä. Jos teet itse kuvan vaikkapa Paintilla ja laitat kuvaan tekstiä (ja vieläpä suoraan), niin sellaisen Tesseract tunnistaa virheettömästi. Jos taasen kuva tulee heikkolaatuiselta USB-kameralta livenä, niin kuvalle pitää tehdä monenmoista käsittelyä, että Tesseract tunnistaa siitä edes jotain. Suurin aika tässä testissä menikin kuvanlaadun säätämiseen ja kuvankäsittelyn koodaukseen.

Yhteenvetona voi todeta, että OCR:n käyttö livekameran kuvan kanssa on melko nopeaa ja helppoa, mutta kuvanlaatuun tulee panostaa. Jos kuvanlaatu olisi ollut hyvä, niin tekoälyn kanssa oman koodin tarve on vain murto-osa vanhaan vastaavaan toteutukseen verrattuna.

Nykyisin kaikissa uusissa vesimittareissa alkaa olemaan etäluentaominaisuudet toteutettuna esim. M-Bus -väylällä. Mielestäni kaikille käyttäjille, riippumatta kunnasta tai vesiosuuskunnasta, pitäisi tarjota mahdollisuus liittää uusi älykäs vesimittari lähiverkkoon, jolloin mittaukset saataisiin reaaliajassa. Tämä vähentäisi entisestään vesihuollon tarvetta ajella autolla ympäri kyliä lukemassa ”etämittareita”. Wireless M-Bus -väylän luentaetäisyyshän on kymmenistä satoihin metreihin, riippuen rakenteista ja kelistä. Ja mikä parasta, reaaliaikamittauksella saataisiin uutta dataa ja pohjaa uusille palveluille – vaikkapa softapohjainen vesivuotovahti.

Jos aihe herätti ajatuksia tai ideoita uusista projekteista, niin otapa yhteyttä!

Risto on Oiwan teknologiajohtaja, jolla on taipumusta luovaan ajatteluun ja tekemiseen. Tutustu Ristoon lisää täällä.

Datan rakennus- ja pelastushommat

Jos datan hyödyntämisen kanssa ollaan ongelmissa, puhutaan oikeastaan kahdenlaisista tilanteista. Tyypillinen tilanne on, että dataa ei joko hyödynnetä ollenkaan tai sitä pyöritellään vaikeasti ja raportteja koostetaan paljon käsin. Toinen tapaus on se, että datan hyödyntämistä on automatisoitu, mutta toteutustavat ontuvat. Tällöin data pitää pelastaa toimimattomista ratkaisuista.

Siispä haalarit jalkaan ja auttamaan asiakasta! Tarkastellaanpas näitä kahta tilannetta erikseen.

Datan hyödyntäminen

Talousjohtaja (tai pienemmissä firmoissa toimitusjohtaja itse) käyttää joka viikko kaksi päivää työajastaan keräämällä dataa. Hän koostaa sitä eri järjestelmistä omin käsin, osa tiedoista tulee muiden ylläpitämistä, sähköpostilla lähetetyistä exceleistä. Edistyksellisemmässä tilanteessa Excel-tiedostot ovat jaettuja tiedostoja pilvessä, mutta silti talousjohtaja lähettää osastopäällikölle sähköpostin: ”Onko tieto ajan tasalla?”

Hikeä otsalta pyyhkien talousjohtaja saa johtoryhmän kokoukseen raportit kasaan, mutta koska niiden koostamiseen on mennyt niin paljon työaikaa, hän ei ole ehtinyt analysoida keräämäänsä dataa ja ennustaa tulevaa sen pohjalta. Johtoryhmä keskittyy katsomaan menneisyyteen.

Datan pelastaminen

Yrityksessä on alusta datan jalostamiselle ja analysoinnille. Kaikki ei kuitenkaan suju, niin kuin pitäisi. Virheellinen data kaataa kaikki ajot yöllä ja aamulla IT-osaston ihmisten työhyvinvointi on koetuksella. Kyseessä on sekasotku, jonka ylläpito maksaa paljon ja josta saatuun tietoon ei voi täysin luottaa. Alkaa selittely liiketoimintajohdolle, joka ei voi ymmärtää, miten tämmöiseen tilanteeseen on päädytty. Käytävillä käydään tiukkoja keskusteluja. Johtoryhmässä arvaillaan, onko data ajan tasalla, vai onko syytä epäillä. Pahimmassa tapauksessa koko tuotanto seisoo, kun tuotantoa ohjaavat raportit uupuvat.

Toisessa yrityksessä järjestelmä on otettu käyttöön nopeasti ja siihen ollaan oltu tyytyväisiä. Ongelmat ilmenevät vasta siinä vaiheessa, kun yritys ostaa uuden yrityksen, jonka ERP:stä data haluttaisiin myös raportointiin mukaan tai päätetään ottaa yhteinen uusi ERP käyttöön. Ilmenee, että ERP:n vaihto vaatii muutoksen lähes jokaiseen raporttiin ja että vanhasta ERP:stä haettu data ei olekaan tallessa missään. Koko vanha raportointiratkaisu on siis melko hyödytön ja muutokset tulevat maksamaan todella paljon.

Mikä avuksi?

Oiwan haalareissa kun tullaan paikalle, pystytään syvällä kokemuksella havaitsemaan, että rakennushommat ovat alun perinkin lähteneet väärään suuntaan. Ei se haittaa, ei kaikkea voi hallita, siksi tehdään yhdessä korjausliike. Se tarkoittaa koeponnistusta rajatulla osa-alueella. Siirretään vaikkapa myynnin tai HR:n data täysin uuteen tietovarastoon, pyöritellään sitä kuutioissa ja tuotetaan johtoryhmälle pitkälle analysoitua dataa. Sen jälkeen voidaan laittaa koko homma, osa kerrallaan, kuntoon.

Molemmissa tapauksissa on pohjimmiltaan kyse siitä, että datan hyöty liiketoiminnan ennustamisessa on ymmärretty, mutta sitä tehdään kustannustehottomasti. Joko se vie liikaa ihmisten aikaa tai datan jalostamiseen ja analysointiin kehitetty ratkaisu ei toimi.

Aihe on lähellä sydäntäni ja toivoisinkin, että yritykset käyttäisivät arvokasta dataa paremmin hyödyksi liiketoiminnassaan. Fakta on, että vain murto-osa yrityksistä on oivaltanut datan hyödyntämisen mahdollisuuden bisneksensä kasvattamisessa!

Hanna on Oiwan toimitusjohtaja ja tiedon hyödyntämisen ammattilainen. Tutustu Hannaan täällä.

Se ihmiselle luettavampi Business Intelligence Markup Language (Biml)

Olen perehtynyt viimeisen parin viikon aikana bimliin eli Business Intelligence Markup Languageen. Biml on Varigencen kehittämä XML-pohjainen merkintäkieli. Biml on hyvin samanluontoinen kuin SSIS-pakettien takaa löytyvä XML, mutta ihmiselle paljon luettavampaa. Biml mahdollistaa SSIS-pakettien, SQL skriptien ja SSAS-kuutioiden kehityksen ohjelmallisesti. Itse perehdyn tässä blogissa SSIS-pakettien kehitykseen.

Jos olet niinkuin minä ja tykkäät mieluummin tehdä kaiken kirjoittaen, kuin hiirellä raahaillen, niin nyt se on myös SSIS-pakettien kohdalla mahdollista. Biml kaikessa yksinkertaisuudessaa on työkalu, jonka avulla voit kirjoittaa SSIS-pakettien sisällön ja näin generoida perinteisen .DTSX -tiedoston.

Bimlillä koodailluun löytyy useampi työkalu. Varigencella on oma maksullinen editori BimlStudio, mutta myös Visual Studiolle on saatavilla lisäosia. Näistä suosituimpia lienevät Varigencen BimlExpress ja open source BI Developer Extensions. Omissa demoissani olen kokeillut vasta BimlExpressiä.

Kuinka sitä käytetään?

BimlExpressin avulla voi lisätä SSIS-projektille biml-tiedostoja. Biml-tiedostoja voi käyttää samaantapaan kuin JavaScript-tiedostoja ja yhdistellä niitä mielen mukaan. Kaikkea ei tarvitse laittaa yhteen tiedostoon vaan esimerkiksi ConnectionStringit voi siirtää omaan "Environment.biml" -tiedostoon. Kun kokonaisuudet on tehty biml-tiedostoihin ne maalaamalla ja hiiren kakkospainiketta painamalla löytyy "Generate SSIS Packages", joka nimensä mukaan generoi biml-tiedostojen määrittelemät DTSX-tiedostot. Eli biml ei pois sulje myöskään perinteistä paketin muokkausta. Bimlin avulla voi yhtä hyvin tehdä paketille pelkän rungon ja käsin muokkaamalla voi pakettiin helposti lisäillä tarvittavat palikat.

Miltä se näyttää?

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection 
            Name="target" 
            ConnectionString="Data Source=localhost;Initial Catalog=Staging;Provider=SQLNCLI11;Integrated Security=SSPI;">
        </OleDbConnection> 
    </Connections>
    <Packages>
        <Package Name="Demo_Package">
            <Tasks>
                <ExecuteSQL Name="Get tables" ConnectionName="target">
                   <DirectInput>
                       SELECT * FROM sys.tables
                   </DirectInput>
                </ExecuteSQL>
            </Tasks>
        </Package>
    </Packages>
</Biml>

Tässä yksinkertainen esimerkki, jossa luodaan paketti nimeltä "Demo_Package", jolla on yksi ExecuteSQL-taski. Kuten esimerkistä huomaa, on tätä XML paljon helpompi lukea verrattuna paketin takaa löytyvään XML. Vielä tässä muodossa biml jää hieman vaisuksi, eikä tuo paljon muuta lisäarvoa kuin hiiren käytön jättämisen. Onneksi tämän ympärille on lisätty ruutia BimlScriptillä.

BimlScript toimii muuten samaantapaan, kuin perinteisempi biml, mutta sen kylkeen voi lisätä C# tai VB koodia. Tämä tekee bimlistä jo paljon houkuttelevamman työkalun, kun pakettien teosta tulee paljon dynaamisempaa.

Kuinkas se sitten toimii?

<#
List<string> tables = new List<string>{
    "sys.schemas",
    "sys.tables",
    "sys.columns"
};
#>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection 
            Name="target" 
            ConnectionString="Data Source=localhost;Initial Catalog=Staging;Provider=SQLNCLI11;Integrated Security=SSPI;">
        </OleDbConnection> 
    </Connections>
    <Packages>
        <Package Name="Demo_Package_v2">
            <Tasks>
                <# foreach (string table in tables) { #>
                    <ExecuteSQL Name="Get <#=table#>" ConnectionName="target">
                        <DirectInput>
                            SELECT * FROM <#=table#>
                        </DirectInput>
                    </ExecuteSQL>
                <# } #>
            </Tasks>
        </Package>
    </Packages>
</Biml>

Lisäämällä XML sekaan "<# #>" -tagit saimme upotettua C# koodia. Näin saimme helposti tehtyä paketin, jossa on kolme ExecuteSQL-taskia joidenka nimet ja kyselyt tulevat dynaamisesti määrittelemästämme listasta.

Mitä tällä saavutetaan?

Mahdollisuuksia on todella paljon. Kaikki itseään toistavat paketit voidaan kirjoittaa parametrisoiduksi BimlScriptiksi ja näin säästetään paljon työaikaa. BimlScript sisältää myös muita mahtavia työkaluja. Esimerkiksi ympäristön toisintaminen, vaikka kehitykseen on todella helppoa.

<# var sourceConnection = RootNode.DbConnections["Source"]; #>
<# var importResults = sourceConnection.GetDatabaseSchema(; #>
<ImportOptions.ExcludeForeignKey | ImportOptions.ExcludeColumnDefault | ImportOptions.ExcludeViews);#>
<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Packages>
        <Package Name="Create tables" ConstraintMode="Linear">
            <Tasks>
                <# foreach (var table in importResults.TableNodes) { #>
                    <ExecuteSQL Name="Create <#=table.Name#>" ConnectionName="Target">
                        <DirectInput><#=table.GetTableSql()#></DirectInput>
                    </ExecuteSQL>
                <# } #>
            </Tasks>
        </Package>
    </Packages>
</Biml>

Oheinen skripti käyttää hyväkseen tietokannan metadatoja. GetDatabaseSchema() tuo tietokannan metadatat käsiteltäviksi objekteiksi. Näin voidaan foreachilla loopittaa kaikki kannan taulut. Foreach-loopin table olio on tyyppiä AstTableNode, jonka metodi GetTableSql() palauttaa SQL-lauseen, joka tarkistaa onko kyseinen taulu jo olemassa ja jos taulu löytyy pudottaa se sen. Tämän jälkeen se luo uuden taulun metadatojen perusteella.

Edellistä esimerkkiä kokeillessani törmäsin yhteen haasteeseen koskien BimlScriptiä. Biml aina loppuviimein käännetään SSIS-paketiksi. Tällöin biml-kääntäjällä tulee olla saatavilla kaikki samat tiedot mitä SSIS-pakettiakin tehtäessä. Eli tietääkseni ei ole mahdollista tehdä pakettia, joka loisi taulut, jos ne puuttuvat ja tämän jälkeen toisi tauluihin testidataa, vaikka tuotannosta, koska tauluja ei välttämättä ole olemassa ennen paketin generoimista. Tällöin ei ole mahdollista tehdä Data Flow Taskissa mappauksia. Tämän pystyy tietysti ohittamaan sillä, että luo eri paketit taulujen luomiselle ja datan viemiselle. Tällöin on mahdollista luoda taulut ennen toisen paketin generointia.

Mitä jatkossa?

Biml tuo toivottua dynaamisuutta ssis-paketteihin. Käyttötarkoituksia ja tapoja on varmasti monia. Itse yritän jatkossa korvata yksinkertaiset taskit BimlScripteillä ja näin haen lisää ymmärrystä kyseisestä työkalusta. Lyhyen tutustumiseni jälkeen löysin myös muutamia blogeja, joissa oli hyviä esimerkkejä. Näihin perehtyessä löytyy varmasti muitakin käyttötarkoituksia ja toimintatapoja.

Tässä pari edellämainituista blogeista: https://www.solisyon.de/biml https://www.cathrinewilhelmsen.net/biml

Eniten informaatiota löytyy BimlScriptin omilta sivuilta.