W WAPRO Mag można dodawać tzw. pola dodatkowe w kontekście różnych ekranów, np. formularze edycyjne a następnie wyświetlać je albo na listach głównych albo w dedykowanym formularzu.
Dla przykładu można dodać pole dodatkowe do dokumentu handlowego i umieścić je potem na liście głównej dokumentów handlowych. Pola dodatkowe dostępne są w wariantach Prestiż i Prestiż Plus.
Pola dodatkowe mogą być różnego typu np wpisywane jako tekst, data, liczba, hiperłącze lub też pola dodatkowe typu wyliczanego jako funkcja skalarna SQL.
Jeśli pole dodatkowe typu funkcja (bo tym się zajmę w tym wpisie) są wyjątkowym polem, które ze względów wydajnościowych nie są obliczane na listach głównych. Wartość pola obliczana jest tylko w momencie uruchomienia formularza pól dodatkowych jeśli następuje wywołanie w kontekście jednego rekordu.
Dodanie pola wyliczanego do głównej listy miałoby opłakane skutki wydajnościowe z tego też powodu system ich nie bierze pod uwagę.
Po kolei co robimy?
Najpierw należy uruchomić edytor SQL np. SQL Server Management Studio i napisać sobie funkcję jaka nas interesuje. Funkcja musi być skalarna, czyli taka, która zawsze zwraca pojedynczą wartość.
Poniżej prezentuje przykładową funkcję, która oblicza wartość netto dokumentu handlowego pomnożona przez 2 dla wskazanego id konkretnego dokumentu handlowego.
if OBJECT_ID('MAGEXT_PodajWartoscPrognoza') is not null
drop function MAGEXT_PodajWartoscPrognoza
go
CREATE FUNCTION dbo.MAGEXT_PodajWartoscPrognoza
(
@id_dokumentu_handlowego int
)
RETURNS int
AS
BEGIN
DECLARE @Result int
SELECT @Result = WARTOSC_NETTO * 2
from DOKUMENT_HANDLOWY with (nolock) where id_dokumentu_handlowego = @id_dokumentu_handlowego
RETURN @Result
END
GO
Wywołanie takiej funkcji w SQL to
select dbo.MAGEXT_PodajWartoscPrognoza(130)
gdzie w nawiasach okrągłych przekazujemy id, które nas interesuje tu jest to id 130 dokumentu handlowego.
Drugi etap to zdefiniowanie pola dodatkowego w magu. Wybieramy Administrator > Definicje > Pola dodatkowe > Dokument handlowy > Po prawej stronie edytujemy wskazane pole.
Na pierwszym ekranie edycji pola oznaczamy typ i nazwę pola na liście oraz określamy rodzaj pola jako pole wyliczane funkcją.
Na drugiej zakładce podajemy nazwę funkcji i określamy czy funkcja oczekuje parametru wejściowego.
Po zapisaniu danych można otworzyć dokumenty handlowe i w przypadku np. edycji dokumentu po wywołaniu okna pól dodatkowych będzie widać wynik. Na liście dokumentów wartość prezentuje wartość domyślną czyli tu 0 bo tak jak wspomniałem wcześniej na listach funkcje nie są wyliczane.
Oczywiście ten przykład był trywialny do zobrazowania sposobu użycia, jednak funkcje skalarne pozwalają na bardziej rozbudowaną logikę, można ją połączyć z tabelami dodatkowymi gdzie np. użytkownik otrzymuje dodatkowe wartości uwzględniane w prognozach lub zapisywane są w nich dedykowane uprawnienia do bardzo specyficznych danych.
Witam,
potrzebuję wypełniać automatycznie pola dodatkowe na dokumentach różnego typu – pola te mają być skojarzone z kontrahentem wybranym do dokumentu.
Myślałem o zastosowaniu wypełnienia pola dodatkowego przez funkcję SQL jednak jest ona uruchamiana od razu przy tworzeniu dokumentu natomiast moje dane będą dostępne dopiero przy wyborze kontrahenta.
Próbowałem wpisywać dane bezpośrednio do bazy przez gniazdo rozszerzeń uruchamiane po wyborze kontrahenta jednak muszę widzieć automatycznie zaciągnięte dane w polach dodatkowych – może istnieć potrzeba ich zmiany, dodatkowo pola są wymagane więc trzeba je uzupełnić i wtedy nadpisują się wartości wbite do bazy.
Czy jest możliwość zwrócenia wartości wyliczonej przez funkcję SQL uruchamianą przez gniazdo rozszerzeń do pola dodatkowego? Czy może powiązać funkcję SQL z pola dodatkowego z triggerem? (badającym czy zmieniony został id_kontrahenta przy danym id_dok_magazynowego)
Dziękuję za pomoc.
Funkcja SQL nie służy do zapisywania danych a do ich wyświetlania. Jej celem jest zwrócenie danych w jakiejś postaci do formularza w momencie jego wyświetlenia (formularza pól dodatkowych). Zapisywanie danych może się odbywać jedynie przez gniazdo lub przez trigger. Nie polecam triggerów bo nie będzie Pan w stanie zapanować nad tym co się dzieje w bazie i w jakim momencie.
Dziękuję za odpowiedź, spróbuję sformułować pytanie inaczej.
Mamy pole dodatkowe, załóżmy że ma wyświetlać się w nim nazwa kontrahenta.
Przy tworzeniu dokumentu magazynowego chcę żeby po wyborze kontrahenta na dokument od razu był on widoczny po otworzeniu pól dodatkowych (wiem że przekazywanym parametrem będzie id obiektu i że przy odpowiedniej funkcji oczekiwana wartość będzie widoczna przy np. podglądzie zapisanego już dokumentu – cała zagadka polega na tym żeby wyświetlić wartość „w locie”, przy tworzeniu dokumentu).
Chcemy ładować wartości domyślne do pól dodatkowych z możliwością podmiany. Przez lata te pola były uzupełniane ręcznie więc żeby uświadczyć pracownika że wartości pobrane automatyczne są poprawne musimy je wyświetlić w odpowiednich polach przy tworzeniu dokumentu, do podglądu (lub w razie potrzeby edycji)
Teraz już wiem o co biega – pomysł fajny ale są dwa ALE 🙂
po pierwsze faktycznie jest tak obecnie, że w przypadku dokumentów pola inicjowane są wcześniej zanim powstanie nagłówek w bazie (pola są po wyświetleniu formularza, a nagłówek dopiero po dodaniu kontrahenta na dokument). W konsekwencji id obiektu przychodzi do funkcji dopiero po zapisaniu i ponownej edycji dokumentu. Dla kontrahenta/towaru zadziała tak jak Pan chce. Przeanalizujemy możliwość zmiany tej kolejności ale musimy wybadać jakie to ma konsekwencje.
Drugie ALE to konieczność sensownego oprogramowania tego w funkcji bo ona czyta stan z bazy więc jeśli będzie zaproponowana wartość domyślna a użytkownik ją zmieni to i tak przy standardowym podejściu ponowne wyświetlenie tego spowoduje nadpisanie wartości.
Czyli funkcja musiałaby wiedzieć że ok mam taką wartość domyślną X ale teraz mam w polu już Y i nie jest puste i w tym przypadku zamiast wartość domyślną to zwracać dane z tego pola.
Inna opcja to gniazdo nadpisujące tą wartość z tego pola do innego lub do tabeli.
Drugie ALE jest całkowicie do opanowania i przemyślane :). Jednak przez logikę w działaniu programu na ten moment do niego niestety nie dojdę.
W takim razie czekam na ew. zmiany w którejś kolejnej wersji.
Jeszcze w trakcie dyskusji przyszła nam na szybko na teraz możliwość rozwiązania tego na gniazdach. Po pierwsze można zrobić gniazdo po wybraniu kontrahenta tak aby procedurą zrobić już update na tabeli dokument_handlowy w poleXX wartością z tej funkcji. Inna opcja to wywołanie procedury, która zwróci w zmiennej @DokHanPole1|10 wartość od razu do formularza.
Panie Krzysztofie – opcja pierwsza czyli gniazdo rozszerzenia po wybraniu kontrahenta i wpisanie wartości DO BAZY jest proste i było rozważane lecz nie jest możliwe do wykorzystania ze względu na konieczność wglądu w zaciągniętą wartość
Opcja druga czyli zwrócenie pobranej przez procedurę w gnieździe rozszerzenia wartości do tworzonego formularza (na widok, jawne wyświetlenie) to jest właśnie problem którego ugryźć nie potrafię.
Rozumiem że zwrócenie w zmienną @DokHanPole1|10 o czym Pan mówi przekaże wartość już do procedury dodającej dokument (w konsekwencji do bazy = opcja 1), a nie wpisze tego w odpowiednie pole dodatkowe na formularzu.
Jeśli na formularzu po wybraniu kontrahenta wybierze Pan gniazdo Po i oprogramuje je tak aby zwróciło do zmiennej @DokHanPole1 wartość to wywołanie tego formularza będzie miało tą wartość. Zmienna opisuje aktualny stan tego co ma być w formularzu. jeśli potem użytkownik tego nie zmieni to wartość trafi do bazy.
W pierwszym przypadku opisywanym przeze mnie też tak to zadziała, jeśli po wybraniu kontrahenta procedura zrobi update na tabeli to wybranie potem formularza pól zaczyta tą wartość z tabeli i użytkownik będzie mógł to zmienić.
Proszę sobie to sprawdzić na boku.
Panie Krzysztofie, ma Pan racje, wszystko działa wg oczekiwań, niepotrzebnie głowiłem się z wymuszenie zwrócenia zmiennej do formularza, wystarczyło przypisać jej wartość.
Dziękuję!
Dzień dobry, czy jest możliwość aby funkcja SQL obliczała w polu dodatkowym dokumentu (zamówienie) wynik równania na które składają się wartość zamówienia wg cen sprzedaży, wartość zamówienia wg cen zakupu oraz wartość pobraną z innego pola dodatkowego? Chciałbym aby możliwe było oszacowanie zysku z danego zamówienia z uwzględnieniem kosztu transportu wpisanego w polu dodatkowym.
Pozdrawiam,
Funkcja może zwracać wszystko co sobie programista w niej wymyśli – pytanie tylko na ile będzie to wydajne:) na pewno będzie to zwracane jako jedna wartość bo tak działa funkcja skalarna. Należy też pamiętać, że funkcja zwraca dane tylko w formularzu pól a nie na listach.