Power Appsissa on usein tarve tallentaa yhdellä kertaa joukko muutoksia. Esimerkiksi Excel-tyylisen taulukon solujen arvot tai ostoskorin sisältö. Kokoelman tallentaminen Patch-toiminnolla on yksinkertaisin ja suorituskykyisin tapa tehdä tämä.

Tällä kertaa käydään läpi, miten se käytännössä onnistuu.

Esimerkki – Taulukon solujen tallentaminen yhdellä kertaa

Toteutetaan kuvan Excel-taulukko Power Appsina. Taulukko, jossa henkilöille syötetään kuukausittaisia lukuja.

Tietojen tallennuspaikka – Dataverse

Luodaan tallennettaville tiedoille (taulukon soluille) oma taulu (My values) Dataverseen. Taulun sarakkeet ovat

  • Henkilön nimi (Name)
  • Vuosi ja kuukausi (Year and month)
  • Arvo (Value)

Power Apps – Kuukaudet

Avataan tyhjä Power Apps ja lisätään näytölle painike, jolla alustetaan sovellus. Painiketta painettaessa luodaan kokoelma (colMonth), joka edustaa kuukausia. Se onnistuu helposti sequence-komennolla.

Haluamme mukaan myös vuoden, joten lisätään kokoelmaan toinen sarake (Month), johon tallennetaan kuukausi muodossa kk/yyyy.

ClearCollect(colMonth, AddColumns(Sequence(12,1), "Month",Value & "/" & Year(Today())))

Kokoelman sisältö näyttää tältä.

Lisätään näytölle tyhjä galleria, jonka arvojoukkona on lista henkilöistä, joille kuukausikohtaisia lukuja syötetään.

Lisätään tauukon sarakkeille otsikkorivi. Vaakasuuntainen galleria, jonka arvojoukkona on tämän vuoden kuukaudet (colMonths).

Gallerian sisällä on otsiko (label), jonka arvona on kokoelman kuukausi (Month) -sarake.

Lopuksi lisäämme taulukko-galleriamme sisään toisen (vaakasuuntaisen) gallerian. Myös tämän arvojoukkona on kuukausi-kokoelma. Galleria sisältää tekstin syöttökentän (Text input).

Tämä alkaa hahmottumaan. Nyt on aika hieman siistiä sovellusta.

Tallennettujen arvojen esittäminen taulukossa

Arvot on tallennettuna My Values -tauluun, eli lisätään se seuraavaksi sovellukseen.

Haetaan aluksi kaikki tallennetut arvot omaan kokoelmaansa (colValues). Esimerkissämme tämä tehdään painiketta painamalla.

ClearCollect(colValues, 'My values');

Nyt voimme hakea taulukon solun oletusarvon kokoelmasta. Eli rivin, jonka henkilö ja kuukausi vastaavat kyseisen solun henkilöä ja kuukautta.

LookUp(colValues, Name = lblName.Text And 'Year and month' = ThisItem.Month).Value

Muutosten tallennus kokoelmaan

Käyttäjä voi luonnollisesti muokata solujen arvoja. Tallennetaan muuttuneet arvot solun OnChange-tapahtumassa colValues-kokoelmaan.

Tarkistetaan ensin onko kyseisen solun arvo jo tallennettu (=löytyykö kokoelmasta vastaava rivi). Mikäli ei, luodaan se. Muussa tapauksessa päivitetään arvoa.

With(
    {
        varItem: LookUp(
            colValues,
            Name = lblName.Text And 'Year and month' = ThisItem.Month
        )
    },
    If(
        IsBlank(varItem),
        Patch(
            colValues,
            Defaults('My values'),
            {
                Name: lblName.Text,
                'Year and month': ThisItem.Month,
                Value: Value(inpValue.Text)
            }
        ),
        Patch(
            colValues,
            varItem,
            {
                Value: Value(inpValue.Text)
            }
        )
    )
)

Kokoelman tallentaminen

Kokoelmamme vastaa sisällöltään My values -taulua. Se on alunperin luotu sen pohjalta. Voimme tallentaa koko kokoelman yhdellä Patch-komennolla takaisin My values -tauluun.

 Patch('My values', colValues)

Mikä parasta, komento tallentaa ainoastaan uudet ja muokatut rivit. Vaikka soluja olisi 300, mutta käyttäjä päivittää niistä kahta, muodostuu komennosta kaksi päivityskomentoa.

Kun samalla alustamme kokoelmamme Patch-komennon paluuarvolla (uusien rivien tunnisteet päivittyvät kokoelmaan), niin voimme jatkaa.

ClearCollect(
    colValues,
    Patch(
        'My values',
        colValues
    )
)

Valmista!

Huomaa että kokoelman ei tarvitse sisältää kaikkia taulun sarakkeita. Kunhan se sisältää päivitettävät kentät, sekä tunniste-kentän. Kokoelma ei saa sisältää kenttiä, joita taulusta ei löydy.

Ja kenttien nimien tulee olla täsmälleen oikeat.

Tyhjän arvon tallentaminen?

Oletuksena Dataverseen tallennetun rivin numerokenttää ei voi jälkikäteen päivittää tyhjäksi. Mikäli poistamme solusta arvon, ei Patch-komento päivitä kyseistä riviä ollenkaan.

Voimme pakottaa riville tallentumaan tyhjän arvon (Blank()), mutta tällöinkin riville tallentuu tyhjän sijasta arvoksi 0.

Tyhjän arvon tallenntaminen on kuitenkin mahdollista. Kunhan käy ruksaamassa asetuksista seuraavan kokeellisen ominaisuuden päälle.

Muokattujen solujen lukumäärä?

Entä jos haluaisimme näyttää käyttäjälle tallentamattomien muutosten lukumäärän?

Lisätään alustuksen yhteydessä kokoelmaan uusi sarake (isModified), jossa ylläpidetään tietoa siitä onko riviä muokattu.

ClearCollect(
    colValues,
    AddColumns(
        'My values',
        "isModified",
        false
    )
);

Solun arvoa muokattaessa päivitetään sarakkeen arvoksi true.

Nyt kokoelmassamme on sarake, jota ei löydy vastaavasta Dataversen taulusta. Ennen tallennusta se tulee poistaa (DropColumns).

Jotta sovellus toimii vielä tallennuksen jälkeenkin, tulee poistettu sarake lisätä uudelleen (AddColumns) paluuarvona saatavaan kokoelmaan.

ClearCollect(
    colValues,
    AddColumns(
        Patch(
            'My values',
            DropColumns(
                colValues,
                "isModified"
            )
        ),
        "isModified",
        false
    )
)

Sarakekeen avulla voimme näyttää käyttäjälle tallentamattomien muutosten määrän.

Samaa tietoa hyödyntämällä voimme esimerkiksi passivoida tallennuspainikkeen, mikäli ei ole mitään tallennettavaa.

Suorituskyky ja Power Platform palvelupyynnöt

Kokoelman tallentaminen on todella nopeaa. Jokainen tallennettava rivi muodostaa kuitenkin oman Power Platform palvelupyyntönsä. 200 muutoksen tallennus on 200 palvelupyyntöä. Vaikka se tehdään yhdellä komennolla.

Vaihtoehtoisia toteutustapoja

Esimerkkimme taulukon solujen tallennuksen voi tietenkin tehdä monella muullakin tapaa.

Tallennus ForAll-silmukassa

Kokoelman tallennuksen sijasta kokoelman voi käydä läpi ForAll-silmukassa ja tallentaa silmukan sisällä rivin kerrallaan. Jäätävän hidasta.

Tallennus flow’n avulla

Olen kirjoittanut aiemmin jutun, jossa esitellään tapa tallentaa usea rivi tehokkaasti flow’n avulla. Huomattavasti monimutkaisempaa, kuin kokoelman tallennus. Silti joissain tilanteissa järkevää.

Tallennus riviä muokatessa

Muutoksen voi tietenkin tallentaa samantien, kun käyttäjä on sen tehnyt. Kentän OnChange-tapahtumassa. Tämä on toimiva lähestyminen, mikäli muutoksia ei tehdä kerralla paljoa ja/tai jostain syystä ei haluta käyttää erillistä tallennus-painiketta.