Tabele

Uwaga

Microsoft Power Fx to nowa nazwa języka formuł dla aplikacji kanw. Te artykuły są pracą w toku, gdyż stale wyodrębniamy język z aplikacji kanw, integrujemy go z innymi produktami Microsoft Power Platform i udostępniamy jako rozwiązanie open source. Zacznij od przeglądu Microsoft Power Fx, aby znaleźć wprowadzenie do języka.

W Microsoft Power Fx można napisać formułę uzyskującą dostęp do informacji w Microsoft Excel, SQL Server, SharePoint oraz kilku innych źródłach, które przechowują dane w rekordach i tabelach. Aby wydajnie korzystać z danych tego typu, warto zapoznać się z pojęciami dotyczącymi takich struktur.

  • Rekord zawiera co najmniej jedną kategorię informacji dotyczących osoby, miejsca lub rzeczy. Na przykład rekord może zawierać imię i nazwisko, adres e-mail i numer telefonu jednego klienta. W innych narzędziach rekordy mogą funkcjonować pod nazwą „wiersz”, „element” lub „pozycja”.
  • Tabela zawiera jeden rekord lub wiele rekordów, które zawierają te same kategorie informacji. Tabela może na przykład zawierać imiona i nazwiska, adresy e-mail i numery telefonów 50 klientów.

Można utworzyć rozmaite formuły przyjmujące nazwę tabeli jako argument (analogicznie do formuł w programie Excel, które używają odwołań do komórek jako argumentów). Niektóre formuły w usłudze Power Fx zwracają tabelę, która odzwierciedla inne określone przez Ciebie argumenty. Można na przykład utworzyć formułę:

  • w celu zaktualizowania rekordu w tabeli, określając tę tabelę jako jeden z wielu argumentów funkcji Patch
  • w celu dodania lub usunięcia kolumn w tabeli albo zmiany ich nazw, określając tę tabelę jako argument funkcji AddColumns, DropColumns lub RenameColumns. Żadna z tych funkcji nie modyfikuje oryginalnej tabeli. Zamiast tego funkcja zwraca inną tabelę utworzoną na podstawie innych określonych argumentów.

Elementy tabeli

Elementy tabeli.

Rekordy

Każdy rekord zawiera co najmniej jedną kategorię informacji dotyczących osoby, miejsca lub rzeczy. W powyższym przykładzie przedstawiono rekordy dotyczące poszczególnych produktów (Chocolate, Bread, and Water) i kolumny zawierające różne kategorie informacji (Price, Quantity on Hand i Quantity on Order).

W formule można się odwołać do samego rekordu, z pominięciem kontekstu tabeli. W tym celu należy użyć nawiasów klamrowych. Na przykład rekord { Name: "Strawberries", Price: 7.99 } nie jest skojarzony z tabelą. Pamiętaj, że nazwy pól, takie jak Name i Price w tym przykładzie, nie są ujęte w cudzysłów.

Pola

Pole to fragment informacji zawartych w rekordzie. Pole takie można sobie wyobrazić jako wartość w kolumnie odpowiadająca określonemu rekordowi.

Podobnie jak w przypadku kontrolek, do pola lub rekordu można się odwołać za pomocą .operatora w rekordzie. Na przykład funkcja First(Products).Name zwraca pole Name odpowiadające pierwszemu rekordowi w tabeli Products.

Pole może zawierać inny rekord lub tabelę, co widać w przykładzie dotyczącym funkcji GroupBy. Można zagnieździć dowolną liczbę poziomów rekordów i tabele.

Kolumny

Kolumna odwołuje się do tego samego pola dla co najmniej jednego rekordu w tabeli. W powyższym przykładzie każdy produkt ma pole ceny — cena znajduje się w tej samej kolumnie dla wszystkich produktów. Powyższa tabela ma cztery kolumny, przedstawione w poziomie u góry:

  • Nazwisko
  • Cena
  • Ilość rzeczywista
  • Ilość w zamówieniu

Nazwa kolumny odzwierciedla pola w niej zawarte.

Wszystkie wartości w kolumnie reprezentują ten sam typ danych. W powyższym przykładzie kolumna „Quantity on Hand” zawiera tylko liczby. Nie zawiera ona ciągów — dla żadnego rekordu nie zobaczymy zatem w tej kolumnie ciągu typu „12 jednostek”. Pole może być także puste.

W niektórych narzędziach kolumny są nazywane „polami”.

Tabela

Tabela składa się z co najmniej jednego rekordu. Każdy rekord ma wiele pól mających spójne nazwy dla wszystkich rekordów.

Każda tabela przechowywana w źródle danych lub kolekcji ma nazwę. Nazwa umożliwia odwoływanie się do tabeli i przekazywanie jej do funkcji przyjmujących tabele jako argumenty. Tabele mogą być również wynikiem działania funkcji lub formuły.

Jak przedstawiono w poniższym przykładzie, tabelę można wyrazić w formule, korzystając z funkcji Table i zestawu rekordów ujętych w nawiasy klamrowe:

Table( { Value: "Strawberry" }, { Value: "Vanilla" } )

Można również zdefiniować jednokolumnową tabelę, korzystając z nawiasów kwadratowych. Odpowiednikiem powyższych danych byłby następujący zapis:

[ "Strawberry", "Vanilla" ]

Formuły tabel

W programie Excel i usłudze Power Fx można za pomocą formuł w podobny sposób modyfikować liczby i ciągi tekstowe:

  • W programie Excel można na przykład wpisać wartość typu 42 w komórce A1, a następnie w innej komórce wpisać formułę, taką jak A1+2, w celu uzyskania wartości 44.
  • W usłudze Power Apps ustaw właściwość Default elementu Slider1 na wartość 42 i ustaw właściwość Text etykiety na wartość Slider1.Value + 2, aby została wyświetlona wartość 44.

W obu przypadkach obliczona wartość zmienia się automatycznie, jeśli zmienisz wartości argumentów (np. liczbę w komórce A1 lub wartość elementu Slider1).

W podobny sposób można za pomocą formuł korzystać z danych w tabelach i rekordach oraz manipulować nimi. Nazwy tabel mogą stanowić argumenty w niektórych formułach, takich jak formuła Min(Catalog, Price) umożliwiająca przedstawienie najniższej wartości w kolumnie Price tabeli Catalog. Inne formuły zwracają wyniki w postaci całych tabel. Na przykład formuła RenameColumns(Catalog, "Price", "Cost") zwraca wszystkie rekordy z tabeli Catalog, ale zmienia nazwę kolumny Price na Cost.

Podobnie jak w przypadku liczb, formuły obejmujące tabele i rekordy są automatycznie przeliczane, jeśli zmieni się źródłowa tabela lub rekord. Jeśli koszt produktu w tabeli Catalog zostanie zmniejszony poniżej poprzedniej wartości minimalnej, wartość zwrócona przez formułę Min zostanie automatycznie zmieniona z uwzględnieniem nowego kosztu.

Funkcje tabel i właściwości kontrolek

Rozważ użycie funkcji Lower. Jeśli zmienna welcome zawiera ciąg tekstowy „Hello, World”, formuła Lower(welcome) zwraca wartość „hello, world”. Ta funkcja w żaden sposób nie zmienia wartości w zmiennej. Lower jest funkcją czystą, która jedynie przetwarza dane wejściowe i generuje dane wyjściowe. To wszystko; nie ma żadnych efektów ubocznych. Wszystkie funkcje w programie Excel i większość funkcji usługi Power Fx to czyste funkcje, które umożliwiają automatyczne ponowne obliczanie wartości dla skoroszytu lub aplikacji.

Usługa Power Fx oferuje zestaw funkcji, które operują na tabelach w taki sam sposób. Te funkcje umożliwiają pobieranie tabel jako danych wyjściowych, a następnie filtrowanie, sortowanie, przekształcanie, redukowanie i podsumowywanie całych tabel danych. W rzeczywistości funkcji Lower i wiele innych funkcji, które zwykle akceptują pojedynczą wartość, może również akceptować jednokolumnową tabelę jako dane wejściowe.

Wiele funkcji korzysta z tabeli o jednej kolumnie do tworzenia danych wejściowych. Jeśli cała tabela zawiera tylko jedną kolumnę, można określić ją według nazwy. Jeśli tabela zawiera wiele kolumn, można określić jedną z tych kolumn, korzystając ze składni Table.Column. Na przykład Products.Name zwraca tabelę jednokolumnową wyłącznie z wartościami Nazwa z tabeli Produkty.

Można całkowicie zmienić kształt tabeli, używając funkcji AddColumns, RenameColumns, ShowColumns lub DropColumns. Te funkcje również zmieniają tylko dane wyjściowe, a nie źródło.

Formuły behawioralne

Inne funkcje zostały zaprojektowane specjalnie do modyfikowania danych i powodują efekty uboczne. Ponieważ te funkcje nie są funkcjami czystymi, należy je starannie skompilować. Nie mogą one brać udziału w automatycznym przeliczaniu wartości w aplikacji. Tych funkcji można używać tylko w formułach behawioralnych.

Zakres rekordów

Niektóre funkcje działają przez ocenę formuły względem wszystkich poszczególnych rekordów tabeli. Wyniki formuły są używane na różne sposoby:

  • AddColumns — formuła udostępnia wartość dodanego pola.
  • Average, Max, Min, Sum, StdevP, VarP — formuła udostępnia wartość do zagregowania.
  • Filter, Lookup — formuła określa, czy rekord powinien być uwzględniony w danych wyjściowych.
  • Concat — formuła określa ciągi, które mają zostać połączone.
  • Distinct — formuła zwraca wartość służącą do zidentyfikowania zduplikowanych rekordów.
  • ForAll — formuła może zwrócić dowolną wartość. Możliwe są efekty uboczne.
  • Sort — formuła zawiera wartość, według której rekordy mają zostać posortowane.
  • With — formuła może zwrócić dowolną wartość. Możliwe są efekty uboczne.

W ramach tych formuł można odwoływać się do pól przetwarzanego rekordu. Każda z tych funkcji tworzy „zakres rekordów”, w którym jest oceniana formuła. Pola rekordu stanowią identyfikatory najwyższego poziomu. Z całej aplikacji możesz też odwoływać się do właściwości kontrolki i innych wartości.

Przyjmijmy na przykład tabelę produktów umieszczoną w zmiennej globalnej:

Wymagane tabele.

Set( Products,
    Table(
        { Product: "Widget",    'Quantity Requested': 6,  'Quantity Available': 3 },
        { Product: "Gadget",    'Quantity Requested': 10, 'Quantity Available': 20 },
        { Product: "Gizmo",     'Quantity Requested': 4,  'Quantity Available': 11 },
        { Product: "Apparatus", 'Quantity Requested': 7,  'Quantity Available': 6 }
    )
)

Aby sprawdzić, czy w przypadku jakiegokolwiek produktu nie zażądano ilości większej niż dostępna, można posłużyć się następującą funkcją:

Filter( Products, 'Quantity Requested' > 'Quantity Available' )

Pierwszy argument, który zostanie uwzględniony w funkcji Filter, to tabela rekordów objętych działaniami, a drugi argument to formuła. Funkcja Filter pozwala uzyskać zakres rekordów do oceny tej formuły. Zakres udostępnia pola poszczególnych rekordów — w tej sytuacji są to pola Product, Quantity Requested i Quantity Available. Wynik porównania określa, czy każdy rekord powinien być uwzględniony w wyniku funkcji:

Potrzebne tabele.

W ramach tego przykładu możemy też obliczyć ilość poszczególnych produktów, jaką należy zamówić:

AddColumns( 
    Filter( Products, 'Quantity Requested' > 'Quantity Available' ), 
    "Quantity To Order", 'Quantity Requested' - 'Quantity Available'
)

Do wyniku zostaje dodana kolumna obliczeniowa. Funkcja AddColumns ma własny zakres rekordów służący do obliczenia różnicy między ilością żądaną i ilością dostępną.

Dodaj kolumny.

Na koniec możemy zredukować tabelę wynikową, aby zawierała tylko potrzebne kolumny:

ShowColumns(
    AddColumns(
        Filter( Products, 'Quantity Requested' > 'Quantity Available' ),
        "Quantity To Order", 'Quantity Requested' - 'Quantity Available'
    ),
    "Product",
    "Quantity To Order"
)

Produkt tylko do zamówienia.

Zauważ, że powyżej w niektórych miejscach jest używany cudzysłów podwójny ("), a w innych — cudzysłów pojedynczy ('). Podczas odwoływania się do wartości obiektu, takiego jak pole lub tabela, którego nazwa zawiera spację, wymagany jest cudzysłów pojedynczy. Cudzysłów podwójny jest używany, gdy nie odwołujemy się do wartości obiektu, ale do samego obiektu. Szczególnie dotyczy to sytuacji, w których obiekt jeszcze nie istnieje (np. w przypadku funkcji AddColumns).

Uściślanie

Nazwy pól dodane za pomocą zakresu rekordów przesłaniają te same nazwy z innych miejsc w aplikacji. W takim przypadku dostęp do wartości znajdujących się poza zakresem rekordów można uzyskać za pomocą operatora @uściślania:

  • Aby uzyskać dostęp do wartości z zagnieżdżonych zakresów rekordów, zastosuj operator @ z nazwą używanej tabeli, korzystając ze wzorca:
    Tabela[@FieldName]
  • Aby uzyskać dostęp do wartości globalnych, takich jak źródła danych, kolekcje i zmienne kontekstowe, użyj wzorca [@NazwaObiektu] (bez oznaczenia tabeli).

Jeśli tabela, na której są wykonywane działania, stanowi wyrażenie — np. Filter(Table, ... ) — wówczas nie można użyć operatora uściślania. Tylko najbardziej wewnętrzny zakres rekordów może uzyskać dostęp do pól z tego wyrażenia tabeli, nie korzystając z operatora uściślania.

Załóżmy, że mamy kolekcję X:

Wartość X.

Można ją utworzyć za pomocą funkcji ClearCollect( X, [1, 2] ).

Druga kolekcja to Y:

Wartość Y.

Tworzymy ją za pomocą funkcji ClearCollect( Y, ["A", "B"] ).

Oprócz tego definiujemy zmienną kontekstową o nazwie Value, korzystając z formuły: UpdateContext( {Value: "!"} )

Zbierzmy wszystkie dane. W tym kontekście następująca formuła:

Ungroup(
    ForAll( X,
        ForAll( Y,
            Y[@Value] & Text( X[@Value] ) & [@Value]
        )
    ),
    "Value"
)

powoduje utworzenie tej tabeli:

Wartość XY.

Jak do tego dochodzi? Najbardziej zewnętrzna funkcja, ForAll, definiuje zakres rekordów dla kolekcji X, umożliwiając dostęp do pola Value każdego rekordu w ramach przetwarzania. Uzyskanie dostępu odbywa się przy użyciu ciągu Value lub X[@Value].

Najbardziej wewnętrzna funkcja ForAll definiuje inny zakres rekordów dla kolekcji Y. Ponieważ ta tabela również ma zdefiniowane pole Value, użycie pola Value w tym miejscu odnosi się do rekordu kolekcji Y (już nie do rekordu kolekcji X). Aby w tym miejscu uzyskać dostęp w kolekcji X do pola Value, musimy użyć dłuższej wersji z operatorem uściślania.

Ponieważ kolekcja Y to najbardziej wewnętrzny zakres rekordów, korzystanie z pól tej tabeli nie wymaga uściślania. Ten sam wynik zapewni użycie tej formuły:

Ungroup(
    ForAll( X,
        ForAll( Y,
            Value & Text( X[@Value] ) & [@Value]
        )
    ),
    "Value"
)

Wszystkie zakresy rekordów kolekcji ForAll zastępują zakres globalny. Zdefiniowana przez nas zmienna kontekstowa Value nie jest dostępna według nazwy bez użycia operatora uściślania. Aby uzyskać dostęp do tej wartości, należy użyć opcji [@Value].

Funkcja Ungroup spłaszcza wynik, ponieważ funkcje ForAll zwrócą zagnieżdżoną tabelę wyników.

Tabele jednokolumnowe

Aby wykonywać operacje na jednej kolumnie tabeli, użyj funkcji ShowColumns, tak jak w poniższym przykładzie:

ShowColumns( Products, "Product" )

Ta formuła powoduje utworzenie tabeli z jedną kolumną:

Jedna kolumna.

Aby uzyskać krótszą alternatywę, określ element Table.Column, która wyodrębnia tabelę jednokolumnową zawierającą tylko kolumnę z tabeli. Ta formuła daje na przykład taki sam skutek, jak użycie opcji ShowColumns.

Products.Product

Rekordy wbudowane

Rekordy można wyrazić przy użyciu nawiasów klamrowych zawierających wartości pól nazwanych. Na przykład pierwszy rekord w tabeli na początku tego tematu można wyrazić za pomocą następującej formuły:

{ Name: "Chocolate", Price: 3.95, 'Quantity on Hand': 12, 'Quantity on Order': 10 }

Można również osadzić formuły w innych formułach, jak w poniższym przykładzie:

{ Name: First(Products).Name, Price: First(Products).Price * 1.095 }

Rekordy można zagnieżdżać przez zagnieżdżenie nawiasów klamrowych, jak pokazano w poniższym przykładzie:

{ 'Quantity': { 'OnHand': ThisItem.QuantOnHand, 'OnOrder': ThisItem.QuantOnOrder } }

Jeśli nazwa kolumny zawiera znaki specjalne, takie jak spacja lub dwukropek, należy ją ująć w cudzysłów pojedynczy. Aby użyć cudzysłowu pojedynczego w nazwie kolumny, podwój go.

Wartość w kolumnie Price nie obejmuje symbolu waluty (np. znaku dolara). To formatowanie zostanie zastosowane po wyświetleniu wartości.

Tabele wbudowane

Tabelę można utworzyć, korzystając z funkcji Table i zestawu rekordów. Tabelę z początku tego tematu można wyrazić za pomocą następującej formuły:

Table( 
	{ Name: "Chocolate", Price: 3.95, 'Quantity on Hand': 12, 'Quantity on Order': 10 },
	{ Name: "Bread", Price: 4.95, 'Quantity on Hand': 34, 'Quantity on Order': 0 },
	{ Name: "Water", Price: 4.95, 'Quantity on Hand': 10, 'Quantity on Order': 0 } 
)

Tabele można także zagnieżdżać:

Table( 
	{ Name: "Chocolate", 
	  'Quantity History': Table( { Quarter: "Q1", OnHand: 10, OnOrder: 10 },
	                             { Quarter: "Q2", OnHand: 18, OnOrder: 0 } ) 
	}
)

Wbudowane tabele wartości

Tabele jednokolumnowe można tworzyć, określając wartości w nawiasach kwadratowych. Tabela wynikowa zawiera jedną kolumnę o nazwie Value.

Na przykład funkcja [ 1, 2, 3, 4 ] jest równoznaczna z Table( { Value: 1 }, { Value: 2 }, { Value: 3 }, { Value: 4 } ) i zwraca tę tabelę:

Tabela inline.