Walidacja NIP, REGON i IBAN offline w Power Apps: jak zrobić to szybko i bez API
Praktyczny poradnik: walidacja NIP, REGON (9/14) i IBAN w 100% offline w Power Apps. Normalizacja danych, algorytmy w Power Fx, testy edge-case’ów i dobre komunikaty błędów.
Jakie elementy walidacji NIP, REGON i IBAN da się zrobić w 100% offline w Power Apps?
W 100% offline w Power Apps da się wykonać wyłącznie walidacje syntaktyczne i matematyczne, czyli takie, które nie wymagają odpytywania rejestrów ani usług sieciowych. Obejmują one sprawdzenie formatu, dopuszczalnych znaków, długości oraz poprawności cyfr kontrolnych (tam, gdzie istnieją). Nie da się natomiast offline potwierdzić, czy numer faktycznie istnieje w rejestrze, jest aktywny, przypisany do konkretnej firmy/osoby lub zgodny z nazwą/adresem — to wymaga źródła zewnętrznego.
- NIP: można sprawdzić, czy po usunięciu separatorów ma dokładnie 10 cyfr, zawiera tylko cyfry oraz czy zgadza się suma kontrolna (weryfikacja cyfry kontrolnej na podstawie wag). To pozwala odsiać większość błędów przepisywania, ale nie potwierdza istnienia NIP w bazach.
- REGON: można sprawdzić, czy to 9 lub 14 cyfr (zależnie od typu), czy zawiera tylko cyfry oraz czy zgadza się cyfra kontrolna dla danego wariantu. Podobnie jak przy NIP jest to kontrola poprawności zapisu, bez weryfikacji w rejestrze.
- IBAN: można sprawdzić długość właściwą dla kraju (dla Polski 28 znaków, w tym
PL+ 26 cyfr), dozwolone znaki (litery/cyfry), a przede wszystkim algorytm MOD 97 (standardowa walidacja IBAN oparta o przestawienie prefiksu i obliczenie reszty z dzielenia przez 97). Dodatkowo dla polskich rachunków można offline rozdzielić i sprawdzić, czy część odpowiada strukturze NRB (26 cyfr). To nadal nie potwierdza, że rachunek istnieje lub należy do wskazanego podmiotu.
2 - Jak poprawnie normalizować dane wejściowe użytkownika, żeby walidacja nie dawała fałszywych błędów?
Normalizacja to sprowadzenie wpisu użytkownika do przewidywalnej postaci (formatu), zanim uruchomisz reguły walidacji. W praktyce chodzi o usunięcie dozwolonych „ozdobników” (spacje, myślniki), ujednolicenie wielkości liter oraz odcięcie znaków niewidocznych. Bez tego poprawne dane wprowadzone w innym zapisie (np. IBAN ze spacjami) mogą zostać odrzucone jako błędne.
W Power Apps warto robić normalizację w stałej kolejności i dopiero na jej wyniku wykonywać sprawdzenia długości, znaków i algorytmów kontrolnych. Najczęściej potrzebujesz: Trim() (usuwa spacje z początku i końca), Substitute() (usuwa znaki formatowania, np. spacje i „-”), oraz Upper() dla identyfikatorów alfanumerycznych (IBAN). Dodatkowo usuń znaki „niewidzialne” typu tabulator i znak nowej linii, bo potrafią powodować „tajemnicze” błędy porównań.
- NIP/REGON: usuń spacje i myślniki, a następnie waliduj tylko cyfry (np. długość 10 dla NIP, 9 lub 14 dla REGON). Nie polegaj na tym, że użytkownik wpisze ciągły zapis.
- IBAN: usuń spacje i myślniki, zamień litery na wielkie (
Upper()), a potem waliduj strukturę (np. prefiks kraju) i długość dla danego kraju. Spacje w IBAN są powszechne i nie powinny powodować odrzucenia. - Białe znaki: oprócz
Trim()usuń z wnętrza tekstu tabulatory i znaki końca linii (Char(9),Char(10),Char(13)) przezSubstitute(), bo mogą wkleić się z maila/Excel i złamać walidację.
Dobra praktyka: przechowuj (lub przynajmniej waliduj) wartość znormalizowaną, a wersję „ładną” do prezentacji formatuj osobno. Dzięki temu walidacja działa na czystym, jednoznacznym wejściu, a użytkownik nadal może wpisywać dane w wygodny dla siebie sposób.
Jak zaimplementować walidację NIP w Power Fx krok po kroku?
Walidacja NIP w Power Fx polega na dwóch warstwach: kontroli formatu (czy jest 10 cyfr) oraz kontroli sumy kontrolnej (algorytm wag). Najwygodniej zrobić to jako formułę zwracającą wartość logiczną (true/false), którą potem podłączysz do komunikatu błędu lub warunku zapisu.
Najpierw znormalizuj wejście użytkownika, czyli usuń spacje i myślniki, tak aby dalej pracować na samych cyfrach. Następnie sprawdź, czy wynik ma dokładnie 10 znaków i czy wszystkie są cyframi. Dopiero wtedy oblicz sumę kontrolną: pomnóż pierwsze 9 cyfr przez wagi 6,5,7,2,3,4,5,6,7, zsumuj, weź resztę z dzielenia przez 11 i porównaj z 10. cyfrą. Jeśli reszta wynosi 10, NIP jest nieprawidłowy.
Poniższa formuła pokazuje kompletne podejście w Power Fx w postaci wyrażenia logicznego. W praktyce wstaw ją np. do właściwości TextInputNIP.BorderColor, LabelError.Visible albo do warunku w SubmitForm/Patch (w zależności od tego, gdzie chcesz blokować zapis):
With(
{
n: Substitute(Substitute(Trim(TextInputNIP.Text), "-", ""), " ", "")
},
If(
Len(n) <> 10 || !IsMatch(n, "^\\d{10}$"),
false,
With(
{
d1: Value(Mid(n,1,1)),
d2: Value(Mid(n,2,1)),
d3: Value(Mid(n,3,1)),
d4: Value(Mid(n,4,1)),
d5: Value(Mid(n,5,1)),
d6: Value(Mid(n,6,1)),
d7: Value(Mid(n,7,1)),
d8: Value(Mid(n,8,1)),
d9: Value(Mid(n,9,1)),
d10: Value(Mid(n,10,1))
},
With(
{
s: d1*6 + d2*5 + d3*7 + d4*2 + d5*3 + d6*4 + d7*5 + d8*6 + d9*7,
m: Mod(d1*6 + d2*5 + d3*7 + d4*2 + d5*3 + d6*4 + d7*5 + d8*6 + d9*7, 11)
},
m <> 10 && m = d10
)
)
)
)
Jeżeli chcesz sterować komunikatem błędu, najprościej odwrócić wynik tej walidacji. Przykładowo, widoczność etykiety z błędem ustaw na !<formuła_walidacji>, a treść komunikatu na stały tekst (np. „Nieprawidłowy NIP”) lub na warunek rozróżniający błąd formatu od błędu sumy kontrolnej, jeśli jest to potrzebne w Twoim interfejsie.
Jak zaimplementować walidację REGON (9 i 14 cyfr) w Power Fx krok po kroku?
Walidacja REGON polega na sprawdzeniu dwóch rzeczy: czy numer ma poprawną długość (9 albo 14 cyfr) oraz czy zgadza się cyfra kontrolna wyliczona z wag. W Power Fx najwygodniej zrobić to jako formułę zwracającą true/false (np. do właściwości Valid, DisplayMode albo komunikatu błędu).
Krok 1: Oczyść wejście i sprawdź format. Przyjmij tekst z kontrolki (np. TextInput_REGON.Text), usuń spacje i myślniki (Substitute) i sprawdź, czy po oczyszczeniu jest wyłącznie cyframi oraz ma długość 9 lub 14. W praktyce w Power Fx zwykle wystarcza połączenie Len() i testu „czy da się bezpiecznie przekonwertować na liczbę” (np. IsNumeric()), przy czym docelowo i tak pracuj na tekście i pojedynczych znakach.
Krok 2: Wylicz cyfrę kontrolną dla REGON-9. Dla 9 cyfr stosuje się wagi: 8, 9, 2, 3, 4, 5, 6, 7 dla pierwszych 8 cyfr, a wynik porównuje z 9. cyfrą. Obliczenie: s = d1*8 + d2*9 + d3*2 + d4*3 + d5*4 + d6*5 + d7*6 + d8*7, następnie m = Mod(s, 11), a cyfra kontrolna to If(m=10, 0, m). W Power Fx pobierasz d1..d8 jako Value(Mid(regon, i, 1)).
Krok 3: Wylicz cyfrę kontrolną dla REGON-14. Dla 14 cyfr stosuje się wagi: 2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8 dla pierwszych 13 cyfr, a wynik porównuje z 14. cyfrą. Obliczenie: s = d1*2 + d2*4 + d3*8 + d4*5 + d5*0 + d6*9 + d7*7 + d8*3 + d9*6 + d10*1 + d11*2 + d12*4 + d13*8, potem m = Mod(s, 11), a cyfra kontrolna to If(m=10, 0, m).
Krok 4: Złóż to w jedną formułę Power Fx. Najczytelniej zrobić to przez With(), aby nie powtarzać obliczeń, oraz przez rozgałęzienie po długości. Poniżej przykład kompletnej walidacji zwracającej true/false (podmień TextInput_REGON.Text na swoje źródło):
With(
{
r: Substitute(Substitute(TextInput_REGON.Text, " ", ""), "-", "")
},
If(
!IsNumeric(r) || !(Len(r)=9 || Len(r)=14),
false,
If(
Len(r)=9,
With(
{
s: Value(Mid(r,1,1))*8 + Value(Mid(r,2,1))*9 + Value(Mid(r,3,1))*2 +
Value(Mid(r,4,1))*3 + Value(Mid(r,5,1))*4 + Value(Mid(r,6,1))*5 +
Value(Mid(r,7,1))*6 + Value(Mid(r,8,1))*7,
k: Value(Mid(r,9,1))
},
k = If(Mod(s,11)=10, 0, Mod(s,11))
),
With(
{
s: Value(Mid(r,1,1))*2 + Value(Mid(r,2,1))*4 + Value(Mid(r,3,1))*8 +
Value(Mid(r,4,1))*5 + Value(Mid(r,5,1))*0 + Value(Mid(r,6,1))*9 +
Value(Mid(r,7,1))*7 + Value(Mid(r,8,1))*3 + Value(Mid(r,9,1))*6 +
Value(Mid(r,10,1))*1 + Value(Mid(r,11,1))*2 + Value(Mid(r,12,1))*4 +
Value(Mid(r,13,1))*8,
k: Value(Mid(r,14,1))
},
k = If(Mod(s,11)=10, 0, Mod(s,11))
)
)
)
)
Krok 5: Podłącz wynik do UI. Jeśli chcesz pokazać błąd, ustaw np. Label_Error.Visible na negację walidacji albo w BorderColor kontrolki wejściowej ustaw kolor warunkowo (np. czerwony, gdy formuła zwraca false). Kluczowe jest, aby ta sama logika była używana konsekwentnie w jednym miejscu (jedna formuła), żeby uniknąć rozjechania się reguł.
Jak zaimplementować walidację IBAN w Power Fx i co zrobić z prefiksem kraju oraz spacjami?
Walidację IBAN w Power Fx zacznij od normalizacji wejścia, bo użytkownicy często wklejają numer ze spacjami, a prefiks kraju może być zapisany w różnej wielkości liter. W praktyce najpierw usuń wszystkie spacje i ujednolić zapis do wielkich liter, np. Set(vIban, Upper(Substitute(Trim(TextInputIBAN.Text), " ", ""))). Dzięki temu dalsze kroki działają przewidywalnie niezależnie od formatu wpisanego przez użytkownika.
Prefiks kraju (pierwsze 2 znaki) jest integralną częścią IBAN i powinien pozostać w ciągu znaków — nie „odcinaj” go na stałe. W algorytmie IBAN te dwa znaki oraz dwie cyfry kontrolne są przenoszone na koniec ciągu (rotacja o 4 znaki), więc w Power Fx budujesz postać do obliczeń jako Mid(vIban, 5, Len(vIban)-4) & Left(vIban, 4). Dopiero w tej postaci litery z prefiksu kraju (i ewentualnie z części BBAN, jeśli dotyczy) zamienia się na wartości liczbowe A=10, B=11, …, Z=35, a następnie sprawdza się warunek modulo 97.
Kluczowe jest też rozróżnienie „formatowania” od „walidacji”: spacje są wyłącznie formatem prezentacji, więc usuwa się je przed walidacją i (opcjonalnie) można je dodać z powrotem tylko do wyświetlania. Prefiks kraju natomiast jest elementem walidowanym; jeśli go brakuje albo nie ma dwóch liter na początku po normalizacji, to nie jest to poprawny IBAN i walidacja powinna zwrócić błąd.
Jak pisać komunikaty błędów, żeby użytkownik poprawił dane szybko i bez frustracji?
Dobry komunikat walidacji ma prowadzić użytkownika do poprawy w jednym kroku: mówi co jest nie tak, gdzie i jak to naprawić. W praktyce oznacza to, że tekst powinien odnosić się do konkretnego pola (np. NIP/REGON/IBAN), wskazywać przyczynę odrzucenia (np. zła długość, niedozwolone znaki, nieprawidłowa suma kontrolna) oraz podać oczekiwany format w sposób możliwie prosty do zastosowania od razu.
Unikaj komunikatów ogólnych typu „Błędna wartość” lub „Walidacja nieudana”, bo nie sugerują następnego kroku i wymuszają zgadywanie. Zamiast tego dopasuj treść do typu błędu: przy błędach składni (długość, znaki) podaj wymagania wejścia, a przy błędach merytorycznych (np. niezgodna suma kontrolna) poinformuj, że numer wygląda na wpisany z literówką i warto go porównać z dokumentem źródłowym.
Komunikat powinien być krótki i neutralny, bez tonu „osądzającego” użytkownika. Dobrą praktyką jest też podpowiadanie poprawnej normalizacji danych wprost w tekście: że spacje i myślniki nie są potrzebne (jeśli tak jest w Twojej logice), że litery są niedozwolone, albo że prefix kraju w IBAN jest wymagany. Im mniej użytkownik musi pamiętać lub domyślać się zasad, tym szybciej poprawi dane i tym mniej powtórzeń walidacji wykona.
W Power Apps warto pokazywać błąd możliwie blisko pola (np. w etykiecie pod kontrolką), a komunikat formułować tak, by nie zależał od szczegółów implementacji (np. „regex” czy „algorytm”), tylko od efektu widocznego dla użytkownika. Jeśli walidujesz kilka warunków, komunikuj pierwszy błąd, który blokuje poprawność (np. najpierw długość i znaki, dopiero potem sumę kontrolną), aby użytkownik nie dostawał sprzecznych lub zmieniających się komunikatów po każdej drobnej poprawce.
Jak przetestować walidację na zestawie przypadków i wychwycić edge-case’y przed wdrożeniem?
Najpewniejsze podejście to przygotowanie kontrolowanego zestawu danych testowych i uruchamianie walidacji „hurtowo” w aplikacji, tak aby wynik był mierzony i porównywalny. W praktyce oznacza to tabelę przypadków (np. kolekcję w Power Apps), w której dla każdego rekordu trzymasz: typ identyfikatora (NIP/REGON/IBAN), wartość wejściową dokładnie taką, jaką poda użytkownik, oraz oczekiwany wynik (poprawny/niepoprawny) i ewentualnie oczekiwaną postać po normalizacji (np. bez spacji). Potem wykonujesz test: dla każdego rekordu przepuszczasz wartość przez tę samą funkcję walidacji, której używasz w formularzu, zapisujesz wynik (np. bool + kod powodu odrzucenia) i porównujesz z oczekiwaniem. Kluczowe jest, żeby logika testowa wywoływała dokładnie tę samą walidację co UI, a nie jej kopię — inaczej łatwo „przetestować” coś innego niż wdrażasz.
Edge-case’y wychwytuje się nie przez losowe próby, tylko przez systematyczne pokrycie wejść, które typowo psują walidację: różne formatowanie, znaki niewidoczne i graniczne długości. W offline’owej walidacji NIP/REGON/IBAN najczęstsze problemy wynikają z normalizacji (spacje, myślniki, tabulatory, znaki niełamiącej spacji), z błędnej obsługi wiodących zer, z tolerowania niepoprawnej długości, z niejawnej konwersji na liczbę (ucina zera i zmienia bardzo długie ciągi), oraz z niejednoznacznych komunikatów (walidacja zwraca „false”, ale nie wiadomo czy powodem był format, długość czy suma kontrolna). Dlatego w testach warto rozdzielić sprawdzenie na etapy: normalizacja → walidacja formatu (tylko dozwolone znaki) → walidacja długości → walidacja sumy kontrolnej; a w raporcie testowym zapisać, na którym etapie przypadek odpadł. To pozwala szybko odróżnić błąd w algorytmie od błędu w przygotowaniu danych wejściowych.
Żeby testy były powtarzalne i dały jasny sygnał „co się zepsuło”, utrzymuj zestaw przypadków jako stały artefakt (np. w kolekcji inicjalizowanej w OnStart lub w źródle danych używanym tylko w środowisku testowym). Po zmianie formuł walidacji uruchamiasz ten sam pakiet przypadków i porównujesz liczbę oraz listę niezgodności. Dodatkowo, przed wdrożeniem sprawdź zachowanie walidacji na danych „realistycznie brudnych”: wklejanych z maila/Excela, z końcowymi spacjami, z mieszanym formatowaniem oraz z wartościami skrajnymi (minimalna/maksymalna długość dla danego typu). Dzięki temu wychwycisz problemy, które nie wynikają z samej matematyki sum kontrolnych, tylko z tego, jak użytkownik faktycznie dostarcza dane w Power Apps.
Jak utrzymać reguły walidacji w czasie, gdy pojawiają się zmiany i wyjątki biznesowe?
Najważniejsze jest rozdzielenie „twardej” walidacji formalnej (wynikającej ze standardu/liczby kontrolnej) od reguł biznesowych (lokalnych wyjątków, dopuszczeń i blokad). Formalną walidację (np. poprawna suma kontrolna) traktuj jako stabilny rdzeń, a zmienne reguły biznesowe jako warstwę konfigurowalną, którą da się zmienić bez przepisywania formuł w wielu miejscach aplikacji.
W praktyce oznacza to centralizację logiki: zamiast powielać formuły walidacji w kontrolkach, trzymaj je w jednym miejscu (np. w dedykowanych formułach/zmiennych na poziomie ekranu lub w komponencie Power Apps) i zwracaj ustandaryzowany rezultat, np. {isValid:Boolean, reason:Text, severity:Text}. Dzięki temu każda zmiana reguły jest pojedynczą zmianą, a nie serią poprawek w wielu właściwościach (OnChange, Visible, DisplayMode, BorderColor itd.).
Wyjątki biznesowe utrzymuj jako dane, nie jako kod: lista dozwolonych/zakazanych wartości, progi, daty obowiązywania, reguły per jednostka/oddział. W Power Apps najczęściej realizuje się to przez tabelę konfiguracyjną w źródle danych (lub wbudowaną kolekcję ładowaną przy starcie), gdzie wpisy mają co najmniej identyfikator reguły, parametr, zakres obowiązywania i priorytet. Aplikacja w czasie walidacji odczytuje konfigurację i stosuje wyjątki zgodnie z priorytetem, zamiast mieć je „na sztywno” w formułach.
- Wersjonuj i dokumentuj reguły: przy każdej regule trzymaj datę obowiązywania, wersję oraz krótki opis „dlaczego”, aby uniknąć przypadkowego usuwania wyjątków.
- Priorytety i rozstrzyganie konfliktów: ustal prostą zasadę (np. wyjątek ma wyższy priorytet niż reguła ogólna; blokada ma wyższy priorytet niż dopuszczenie) i trzymaj ją konsekwentnie w jednym miejscu w logice.
- Testuj na zestawach przypadków brzegowych: utrzymuj listę przykładowych wartości (poprawnych, błędnych i „wyjątkowych”) i weryfikuj po zmianach, czy wynik walidacji nie zmienił się niezamierzenie.
- Jawne komunikaty: zwracaj powód odrzucenia/akceptacji (np. „błąd formalny” vs „wyjątek biznesowy”), aby użytkownik i właściciel procesu widzieli, co zadziałało i dlaczego.
Takie podejście minimalizuje koszt zmian: gdy pojawia się nowy wyjątek lub korekta reguły, edytujesz konfigurację albo pojedynczy fragment scentralizowanej logiki, a interfejs automatycznie korzysta z aktualnych zasad bez ryzyka niespójności między ekranami i kontrolkami.