www.afin.net

 

Artykuł AFIN.NET

 Język zapytań księgowych AFIN.NET © AFIN 1997-2008 

Wojciech Gardziński, 2008.04

 

Najprostszy, a zarazem najbardziej efektywny sposób definiowania dowolnych raportów finansowych

 

Summary:

AFIN.NET Financial Query Language is the easiest way to define financial reports.

Very complicated financial queries are replaced with very simply logic of accountat’s thinking way „Get an account summary for (any combination of fields and account numbers using wildcards)”. The sample at the end of this article.

 

 

Księgowy punkt widzenia

 

Z punktu widzenia księgowego, tworzącego raporty, informatyka pełni wyłącznie rolę usługową. Problemy księgowe nie mogą być zwielokrotnione jakąkolwiek uciążliwością, wynikającą z komplikacji problemów informatycznych. Księgowy porusza się w pewnym wąskim (mówimy tu wyłącznie o potrzebach informatyczno-raportowych) zakresie pojęć, ale muszą być one dla niego proste, jednoznaczne i – tu napotykamy na problemy informatyczne – NATYCHMIASTOWO wykonywalne. Komplikacja zapytań raportowych nie polega w tym obszarze na różnorodności pojęć, ale na komplikacji wewnętrznej – merytorycznej.

Księgowy mówi: „Potrzebuję saldo po stronie winien konta 101 (nazwijmy to przykładem A), „obroty winien kont: 400, 411 dla MPKów: 123 i 124”  (przykład B) oraz  „wartość majątku trwałego bez gruntów, czyli saldo winien konta 010 pomniejszone o 010.1 minus saldo ma konta 070, pomniejszone o 070.1 (przykład C)

 

Aby uzyskać te informacje, księgowy zwykle bierze do ręki standardowy wydruk swojego programu finansowo-księgowego (FK) – Zestawienie obrotów i sald (ZOiS) – zwany  potocznie obrotówką, odnajduje tam żądane informacje, sumuje wartości na kalkulatorze i wpisuje wartość do raportu. I wcale nie jest to proste:

Zacznijmy od przykładu A: Należy odszukać właściwe konto – obrotówka ma czasami kilkadziesiąt stron – i wybrać odpowiednią kolumnę danych. ZOiS zwykle składa się z następujących kolumn:

 

Konto

nazwa

Bilans otwarcia

Obroty miesięczne

Obroty narastające od początku roku

Saldo

Wn

Ma

Wn

Ma

Wn

Ma

Wn

Ma

010

MT gr.0

0,00

0,00

0,00

0,00

0,00

0,00

0,00

0,00

011

MT gr.1

0,00

0,00

0,00

0,00

0,00

0,00

0,00

0,00

101

Gotówka

0,00

0,00

0,00

0,00

0,00

0,00

0,00

0,00

 

Konta zwykle drukowane są jako analityka, więc tworzą bardzo długą listę. Zwykle są odpowiednio podsumowane, zdarza się jednak, że nie – wtedy pozostaje sumowanie ręczne poszczególnych wartości analityk lub, wtedy już zwykle tylko na ekran, wykonanie zestawienia w wybranym stopniem szczegółowości danych lub wybranymi kontami. Załóżmy jednak, dla uproszczenia, że takie podsumowania są dostępne.

 

Konto

saldo wn

saldo ma

010.1

10,00

0

010.2

20,00

0

010.3

30,00

0

010.4

40,00

0

010

100,00

0

 

 

 

Informatyczny punkt widzenia

 

Informatyk, aby wykonać powyższe zadanie, musi zlokalizować dane – konkretnie tabelę lub zestaw tabel, które zawierają potrzebne wartości. Niektóre systemy FK (te, którym nieobce jest pojęcie „raport”) posiadają w swojej bazie gotową tabelę ZOiS, uaktualnianą po każdym księgowaniu – raporty robią się wtedy dużo szybciej. Zapytanie, o którym mowa w najprostszym przykładzie, wygląda tak: SELECT SUM(sw) FROM tabela200701 WHERE konto=’101’ . Księgowy by tego nie napisał. A co dopiero przykłady bardziej skomplikowane:

Gdy dane przechowywane są w hurtowni danych, w tzw. kostce OLAP, zapytanie jest jeszcze bardziej skomplikowane, bo taki jest język zapytań MDX – jest on znany wyłącznie przez specjalistów.

 

Jak pogodzić potrzeby księgowych z możliwościami programistów? Powszechna opinia to: Zakup odpowiedniego systemu! W tym gotowych raportów. Termin wdrożenia – rok.

 

I tu, paradoksalnie, napotykamy na problem największy – to, co dla księgowych łatwe, dla informatyków trudne i odwrotnie, a najgorsze jest to, że potrzeby raportowe księgowych są… DYNAMICZNE! Stale dochodzą nowe konta, ciągle trzeba przedefiniowywać zapytania. Samo ich stworzenie to problem. Metoda prób i błędów jest tu powszechnie stosowana. I księgowy, tak właściwie, nigdy nie ma pewności, czy uwzględnił wszystkie konta w danej pozycji raportu. Dopiero, gdy zgodzi się suma, jest pewny, że raport może ujrzeć światło dzienne.

Informatycy, tzn. dostawcy systemów raportowych, wysyłają więc do księgowych konsultantów, którzy mają pomóc w zdefiniowaniu raportów. Kosztuje to klienta dużo, a efekt jest dyskusyjny, gdyż cała wiedza pozostaje dalej w głowie księgowego. Iteracje poprawek nie mają końca i odwoływanie się do zapisanej w umowie specyfikacji również.

 

 

Jak to usprawnić?

 

Uprośćmy nomenklaturę dla nazw kolumn:

 

Standardowa nazwa

Uproszczenie

Konto

konto

Nazwa

nazwa

Bilans otwarcia po stronie Wn

bw

Bilans otwarcia po stronie Ma

bm

Obroty miesięczne po stronie Wn

mw

Obroty miesięczne po stronie Ma

mm

Obroty narastające od początku roku po stronie Wn

ow

Obroty narastające od początku roku po stronie Ma

om

Saldo po stronie Wn

sw

Saldo po stronie Ma

sm

 

Poznajmy zapytania wieloznaczne

Od czasów DOS-a w zapytaniach bazodanowych stosuje się tzw. symbole wieloznaczne (tzw. „wildcard”-y):

? (pytajnik) – zastępuje pojedynczy, dowolny znak

* (gwiazdka) – zastępuje dowolny ciąg dowolnych znaków

W języku SQL są to odpowiednio znaki ”%” (=”*”) i ”_” (=”?”), ale księgowi i tak znają system „*?”, gdyż jest często stosowany, nawet w raportach systemów FK.

 

 

Uprośćmy sposób zapisu zapytania

 

Nie: „podaj saldo winien konta 101”, tylko w skrócie: „sw/101” (pole, ukośnik, konto)

(Znaku „/” nie stosuje się zwykle w zapisie konta. Gdy jednak tak jest – można to ominąć, stosując inny znak w zapytaniu.)

I tak, nasze przykłady, wyglądałyby tak:

A)    sw/101

B)    sw/400???123+sw/400???124+sw/411???123+sw/411???124

C)     sw/010-sw/010.1-sm/070+sm/070.1 ,
inaczej: sw/010-sw/010.1-(sm/070-sm/070.1)

 

Proste? Tak, ale komplikacja księgowości wymaga niekiedy zastosowania zapytań o bardzo znacznej ilości znaków (np. ok.1000)

 

 

Uprośćmy więc zapytanie jeszcze bardziej.

 

Jeżeli operacje wykonywane są na jednym polu, a w większości zapytań tak jest, można zapisać to tak:

A)    sw/101 (tu bez uproszczenia)

B)    sw/400???123>400???124>411???123>411???124

C)    sw/010<010.1-sm/070<070.1
(Można to odczytać np. tak: ”Saldo winien konta 010 pomniejszone o analitykę 010.1 minus saldo ma konta 070, pomniejszonego o analitykę 070.1.)

 

Zastosowane znaki „>” i „<” oznaczają odpowiednio ”+” i ”-”, ale wyłącznie w odniesieniu do operacji wewnątrz bloku zapytania dla jednego pola:

sw/1>2<3 jest równoznaczne: sw/1+sw/2-sw/3 .

 

 

Wykonanie raportu

 

Adresaci raportów życzą sobie, aby raporty posiadały następujące cechy:

 

Normalnie skoroszyty Excela cechy te posiadają, co więcej, każdy umie je obsłużyć (otworzyć, wydrukować, zamknąć)

 

 

Rozwiązanie, czyli co oferuje AFIN.NET?

  1. Otwórz AFIN.NET
  2. Uruchom kreatora funkcji DANE()
  3. Wybierz zmienną FK1.cub
  4. Wpisz funkcję z argumentami przykładowymi
  5. Gotowe

 

 

AFIN.NET oferuje dostęp do dowolnych danych zewnętrznych poprzez funkcję excelową. Skomplikowane zapytania księgowe, omówione powyżej, można wpisywać on-line w arkuszu.
            * Stopień komplikacji księgowej – dowolny
            * Dostęp do informacji – natychmiastowy
            * Konieczność znajomości informatycznych języków zapytań – brak

 

Oczywiście, pod, z pozoru, prostą funkcją, kryje się bardzo skomplikowany algorytm, przetwarzający zapytania na język SQL lub MDX w zależności od typu źródła danych.

I tak (dane dla okresu 2007.01 – w zapytaniu musi być uwzględniony również okres) zapytania księgowe przetwarzane są na:

 

Przykład A:

Język zapytania

Tekst zapytania, kierowany do bazy danych

Język zapytań AFIN.NET

”sw/101” ; ”2007” ;”01”

SQL

SELECT SUM(sw) FROM tabela200701 WHERE konto='101'

MDX

WITH MEMBER [Measures].[wynik] AS '0+SUM({[ko1].[1]}*{[ko2].[0]}*{[ko3].[1]},[Measures].[Suma   sw])' SELECT {[Measures].[wynik]} ON 0 FROM OCWCube WHERE ([rok].[2007],[mc].[01])

 

Przykład B:

Język zapytania

Tekst zapytania, kierowany do bazy danych

Język zapytań AFIN.NET

”sw/400???123>400???124>411???123>411???124” ;

2007” ;”01”

SQL

SELECT SUM(pole) FROM (SELECT 1 AS nrw, +1*SUM(sw) AS pole FROM tabela200701 WHERE konto LIKE '400___123%' UNION SELECT 2 AS nrw, +1*SUM(sw) AS pole FROM tabela 200701 WHERE konto LIKE '400___124%' UNION SELECT 3 AS nrw, +1*SUM(sw) AS pole FROM tabela200701 WHERE konto LIKE '411___123%' UNION SELECT 4 AS nrw, +1*SUM(sw) AS pole FROM tabela200701 WHERE konto LIKE '411___124%')

MDX

WITH MEMBER [Measures].[wynik] AS '0+SUM({[ko1].[4]}*{[ko2].[0]}*{[ko3].[0]}*{[ko7].[1]}*{[ko8].[2]}*{[ko9].[3]},[Measures].[Suma   sw])+SUM({[ko1].[4]}*{[ko2].[0]}*{[ko3].[0]}*{[ko7].[1]}*{[ko8].[2]}*{[ko9].[4]},[Measures].[Suma   sw])+SUM({[ko1].[4]}*{[ko2].[1]}*{[ko3].[1]}*{[ko7].[1]}*{[ko8].[2]}*{[ko9].[3]},[Measures].[Suma   sw])+SUM({[ko1].[4]}*{[ko2].[1]}*{[ko3].[1]}*{[ko7].[1]}*{[ko8].[2]}*{[ko9].[4]},[Measures].[Suma   sw])' SELECT {[Measures].[wynik]} ON 0 FROM OCWCube WHERE ([rok].[2007],[mc].[01])

 

Przykładu C („sw/010-sw/010.1-sm/070+sm/070.1”), rozpisanego na SQL i MDX, już nie podajemy, gdyż zajął by kolejną stronę.

 

I pomyśleć, że zapytania księgowe mogą być np. takie (przykład RZECZYWISTY!):

„sw/??.701.?.*<??.701.0.*>??.702.?.*<??.702.0.*>??.703.?.*<??.703.0.*>??.704.?.*<??.704.0.*>??.706.?.*<??.706.0.*>??.707.?.*<??.707.9>??.708.?.*<??.708.9.0*>02.708>??.730.?.*<??.730.0.*>??.740<??.740.0>06.740.0.??<06.740.0.00”

 

Dla AFIN.NET nie jest to problem.

Co więcej, my, jego twórcy, zdajemy sobie sprawę z konieczności zapisania tychże zapytań dla innych systemów raportowych.

Wystarczy, w funkcji AFINA, umieścić (jako ostatni!) dodatkowy argument „:” (dwukropek) i zapytanie w języku AFIN.NET AUTOMATYCZNIE TŁUMACZY SIĘ na zapytanie w SQL lub MDX. Stąd wystarczy je wykopiować do dowolnego innego systemu i uruchomić dany raport.