QBS >> Q-Line 3000 Szybki Start >> Wydruki Chcę zapytać

Tworzenie programu c.d.

Czas ćwiczenia:
 45 min
Cel:
  Tworzenie programu
Kroki:
  Tworzenie wyliczeń za pomocą AUTFUN'ów

Pierwsze wyliczenia

Do tworzenia wyliczeń stosujemy wyrażenia AUTFUN. Dokładny opis zastosowania tych wyrażeń można znaleźć na naszych stronach, my w naszych ćwiczeniach zajmiemy się tylko podstawowymi funkcjami jakie są dostępne.

Pierwszym wyliczeniem jakie można zastosować jest zliczanie przepracowanych godzin. Informacja ta przechowywana jest w polu SUMA, będziemy ją wyliczać odejmując od pola DO(Do godziny) pole OD(Od godziny). Wzór na takie wyliczenia wygląda tak:

ID       LEN     TYPE     NAME            ;
SUMA     8       INT      "Liczba godzin" MASK=TIME ("hh:mm") AUTFUN=DO-OD VIS=SHOW;

Dodatkowo można ustawić to pole nie do edycji (parametr VIS=SHOW), oraz w masce wyświetlanie tylko godzin i minut (MASK=TIME ("hh:mm")). Ostatni atrybut można ustawić także dla pól OD i DO

ID       LEN     TYPE     NAME            ;
OD       8       INT      "Od godziny"    MASK=TIME ("hh:mm");
DO       8       INT      "Do godziny"    MASK=TIME ("hh:mm");
SUMA     8       INT      "Liczba godzin" MASK=TIME ("hh:mm") AUTFUN=DO-OD VIS=SHOW;

Kolejnym krokiem będzie podłączenie stworzonych tabel OPIS i DLA_KOGO. Da nam to możliwość dodawania opisów i zleceniodawców i wykorzystywania ich później. Aby to zrobić należy do pola OPIS dołączyć makro. Makra wywołuje się za pomocą polecenia EVH tak jak na poniższym przykładzie. Dokładniejszy opis makr znajdziecie Państwo w dalszej części ćwiczeń. Makro użyte w tym przypadku w polu OPIS wpisuje wybraną wartość z tabeli OPISYz pola OPIS_Z

ID       LEN     TYPE     NAME            ;
OPIS     50      STRING   "Zadanie"       ATTRIB=(SUFFLE) EVH=AllVoc(OPISY,OPIS_Z);

W ten sam sposób postępujemy z polem DLA_KOGO, ale w tym przypadku dane dęda pobierane z tabeli DLA_KOGO z pola KOD_OS

Po tych zmianach możemy korzystać z nowych możliwości programu. Następnym zadaniem będzie stworzenie AUTFUN'a automatycznie podającego nazwę miesiąca na podstawie podanej daty. Będzie to potrzebne przy określaniu zawężania. Aby stworzyć takie wyliczenia należy w polu pomocniczym MIES_SPR zastosować AUTFUN'a, który z podanej daty wyliczy numer miesiąca (w nawiasach należy podać nazwę pola z którego pobieramy datę w naszym przypadku jes to pole DATA). Pole to nie będzie nam potrzebne więc można je ukryć VIS=HIDE. Oprócz tego wyliczenia dobrze jest ustawić aby do pola DATA program wpisywał aktualną datę z możliwością późniejszej jej zmiany. Takie wyliczenie załatwia wyrażenie DEFVALUE=curr_date()

ID        LEN     TYPE     NAME      ;
DATA      8       INT      "Data"    MASK=DATE DEFVALUE=curr_date();
MIES_SPR  8       INT      -         AUTFUN=month(DATA) VIS=HIDE;

W ten sposób otrzymamy numer miesiąca na podstawie podanej daty. Ale nam zależało na nazwie miesiąca a nie na jego numerze. Ten problem można załatwić trochę bardziej zaawansowanym AUTFUN'em. Wyrażenie będzie sprawdzać numer miesiąca z pola MIES_SPR i w zależności od niego wipszę odpowiednią nazwę do pola MIES. Najlepiej pole to zaznaczyć jako nie do edycji VIS=SHOW, AUTFUN i tak przy dodawaniu rekordu sprawdzi warunek i wpisze odpowiednią wartość.

ID            LEN     TYPE     NAME            ;
MIES          15      STRING   "Miesiąc"       AUTFUN=MIES_SPR=1?("STYCZEŃ"):
                                                     (MIES_SPR=2?("LUTY"):
                                                     (MIES_SPR=3?("MARZEC"):
                                                     (MIES_SPR=4?("KWIECIEŃ"):
                                                     (MIES_SPR=5?("MAJ"):
                                                     (MIES_SPR=6?("CZERWIEC"):
                                                     (MIES_SPR=7?("LIPIEC"):
                                                     (MIES_SPR=8?("SIERPIEŃ"):
                                                     (MIES_SPR=9?("WRZESIEŃ"):
                                                     (MIES_SPR=10?("PAŹDZIERNIK"):
                                                     (MIES_SPR=11?("LISTOPAD"):
                                                     (MIES_SPR=12?("GRUDZIEŃ"):("")))))))))))) VIS=SHOW;

Jeżeli ktoś wcześniej spotkał się z programowaniem to zauważy, że działa to na zasadzie pętli IF. Podstawowa składnia wyrażenia jest bardzo prosta.
AUTFUN=warunek do sprawdzenia?(wykonaj to polecenie) : (w przeciwnym wypadku to polecenie).
Po uruchomieniu programu (powinno odbyć się to bez kłopotów) przy dodawaniu nowych zadań widać, że wszystkie założenia zostały zrealizowane i z czystym sumieniem można rozpocząć kolejny etap ćwiczeń.

Zawężanie

W przypadku gdy do programu zostanie wprowadzona duża ilość zadań przydatna staje się możliwość zawężania czyli pokazywania tylko zadań z danego zakresu np: tylko z konkretnego miesiąca, dla konkretnej osoby itp.

Jeżeli chcemy stworzyć taki formularz należy do pliku struct.qcon dodać jeszcze jedną tabele o nazwie GODZINKI_DESKTOP_EDIT w której będziemy wyświetlać nasz spis godzin wraz z zawężaniem. Na początku stworzymy tabelę o prostej strukturze i będziemy ją stopniowo rozszerzać

TAB GODZINKI_DESKTOP_EDIT extends GODZINKI;
    TITLE="Edycja przepracowanych godzin"
    LAYOUT=(DATA)
{;}

Dodajmy do tabeli pola

Oprócz definicji pól musimy określić sposób wyświetlania tych pól

LAYOUT=HPAN(
              TCP(LISTA)
                 GRP( "Zawężanie"
                    VPAN(
                      TCP(FLT_MIES) CONST("          ")
                      TCP(FLT_KTO)  CONST("          ")
                      TCP(FLT_CO)   CONST("          ")
                      TCP(SUMA_G)
                         )
                      )
                 )      

Po całej operacji fragment pliku struct.qcon dotyczący tabeli GODZINKI_DESKTOP_EDIT powinien wyglądać tak:

TAB GODZINKI_DESKTOP_EDIT  extends GODZINKI;
    TITLE="Edycja przepracowanych godzin"
    LAYOUT=HPAN(
              TCP(LISTA)
                 GRP( "Zawężanie"
                    VPAN(
                      TCP(FLT_MIES) CONST("          ")
                      TCP(FLT_KTO)  CONST("          ")
                      TCP(FLT_CO)   CONST("          ")
                      TCP(SUMA_G)
                         )
                      )
                 )      
{
ID        LEN    TYPE     MASK          EVH;
LISTA     0      STRING   BROWSER       KlientListMar(GODZINKI_BRO);
FLT_MIES  15     STRING   -             Voc(MIESIACE,MIES_O) ATTRIB=(CAPITAL SUFFLE) NAME="Za który miesiąc";
FLT_KTO   3      STRING   -             Voc(DLA_KOGO,KOD_OS) ATTRIB=(CAPITAL SUFFLE) NAME="Dla kogo robione";
FLT_CO    10     STRING   -             Voc(OPISY,OPIS_Z) ATTRIB=(CAPITAL SUFFLE) NAME="Co robione";
SUMA_G    8      INT      TIME("hhh:mm") - NAME="Suma" BASEFUN=SUM( LISTA, SUMA ) VIS=SHOW;
}

Po tych zmianach należy zmienić wpis w definicji menu. Wywołanie GODZINKI_BRO na wywołanie tabeli GODZINKI_DESKTOP_EDIT. Ponieważ nowa tabela jest tak naprawdę rekordem edycyjnym to wywołanie także ulegnie zmianie z BROWSER na RECEDIT. Wpis taki powinien wyglądać tak:

ID        ACTION                             NAME                    ;
GODZ      RECEDIT TAB=GODZINKI_DESKTOP_EDIT; "Przeglądanie godzin"   ;

Kolejnym krokiem będzie podłączenie makr które wykorzystujemy w programie

Makra

Aby program widział plik z makrami należy w pliku qline.txt dopisać linję wskazującą ten plik. Standardowo plik ten znajduje się w katalogu "qcon" i nazwany jest makra.qcon. Po zmianach plik powinen wyglądać np: tak (nowy wpis zaznaczony jest na czerwono)

record
{

    Sep = record
    {
        Host = "seplib" ;
        Port = 2507;
    };


    Application = record
    {

        Modules = recordarray
        {
              MODULE,                 QCON,                        TRIGGER_SET;//,    TRANSLATION_FILE;
              "LARRANGER",            null,                        "qline.labelsarranger.LabelsArrangerTrigger";
              "QTENBERG",             "qtenberg/qtenberg.qcon",    "qline.qtenberg.QtTrigger";
              "QLINE",                null,                        "qline.export.ExportTrigger";
              "QLINE",                null,                        "qline.misc.TextImporterTrigger";
              "QLINE",                null,                        "qline.qlicense.LicenseTrigger";
              "QLINE",                null,                        "qline.misc.ColorMaskSelectorTrigger";
              "QLINE",                null,                        "qline.tools.TriggerNarrowBrowser";
              "QLINE",                null,                        "qline.backup.triggers.BackupTrigger";
              "QLINE",                null,                        "qline.misc.GroupStatisticsTrigger";
             //------------------------------------------------------------------------------------------------
              "QGODZINKA",          "qcon/struct.qcon",          null;
              "QGODZINKA",          "qcon/makra.qcon",           null;
        };
        Title = "Q-Godzinka 3000";
        BackgroundImage="pic/Qbslogo.jpg";
        DateEditFormat="YYYY.MM.DD";
        DefaultHtmlViewer = "explorer";
        BrowserColumns = "true";
    };
}

Gdy plik z makram jest juz podłączony możemy rozpocząć jego edycję. Plik makra.qcon znajduje się w katalogu "qcon" w katalogu głównym programu. Można edytować go w ten sam sposób jak plik struct.qcon (czyli dowolnym edytorem tekstowym). Po otworzeniu pliku widać wiele innych makr standardowo wykorzystywanych w programach serii Q-Line 3000. W naszym ćwiczeniu musimy stworzyć makro o nazwie KlientListMar, które będzie zawężać nasz spis po wskazanych polach. Przy wpisywaniu należy pamiętać o kolejności wprowadzanych pól, w przeciwnym wypadku zawężanie może działać nie tak jak byśmy tego chcieli. Definicje naszego makra podajemy poniżej. Wpis najlepiej dodać na samym końcu pliku (przy wpisywaniu proszę uważać na znaczniki określające makra {})

BSS KlientBrowserMar(Base baz )
{
  BASE( baz )
  SETKEY NOEMPTYKEY ("LINK", "MIES", "DLA_KOGO", "OPIS", "ID" ) // nazwy pól po których zawężamy
  SEARCH NOEMPTYVAL (value(parentRec, "ID"), value(parentRec, "FLT_MIES"), value(parentRec, "FLT_KTO"), value(parentRec, "FLT_CO"))
}

EVH KlientListMar(Base b)
{
  OWN_TRANS(false)
  RELATION( Reaction("ID", "FLT_MIES", "FLT_KTO", "FLT_CO", "ID")) // nazwy pól które wykorzystują zawężanie
  BROWSER(KlientBrowserMar(b))
  DELREL(HistDel(b,"ID","LINK"))
}

Wpisane makro można stosować w prawie każdym programie serii Q-Line 3000 do różnych zawężeń (zmieniając wykorzystywane pola). Po wpisaniu tej definicji zapisujemy zmiany i uruchamiamy program. Jeżeli wszystkie czynności wykonaliśmy poprawnie to program nie powinien sprawiać kłopotów podczas uruchamiania.

Niezbędne dodatki

Podczas użytkowania programu zauważyliście na pewno, że podczas stosowania zawężenia program zamyka się w sposób nieprawidłowy. Gdy zajrzymy do pliku out.txt zobaczymy tam wpis

Menu główne
java.lang.Error: Missing order for TAB: MIESIACE fields: class qline.basics.FinalArray 1: MIES_O
	at qline.basics.Basic.error(Basic.java:24)
	at qline.browser.BrowserWindow.setEntryRec(BrowserWindow.java:1544)
	at qline.relations.RelationControl.runBrowser(RelationControl.java:338)
	at qline.recordedit.RecordEditTabDefBlock.runBrowser(RecordEditTabDefBlock.java:278)
	at qline.recordedit.RecordEditBrowserManager.runBrowser(RecordEditBrowserManager.java:198)
	at java.lang.reflect.Method.invoke(Native Method)
	at qline.basics.LangReflect.invoke(LangReflect.java:46)
	at qline.basics.MethodProc.run(MethodProc.java:24)
	at qline.basics.ProcList.run(ProcList.java:13)
    .......

Ten out oznacza brak uporządkowania o nazwie MIES_O w tabeli MIESIACE, ale podczas pracy z programem mogą wystąpić inne błędy dotyczące uporządkowań. W takim przypadku należy stworzyć takie uporządkowanie. W tabelach MIESIACE, DLA_KOGO i OPISY będzie potrzebne tylko jedno uporządkowanie należy je dodać w sekcji ORDERS i tak na przykład dla tabeli MIESIACE taki wpis będzie wyglądał tak

TAB MIESIACE
    TITLE="Miesiące"
    BASE=MIESIACE
    BASETYPE=DEFAULT
    RECEDIT=MIESIACE_EDIT
    BROWSER_ACTIONS=+MODIFY_SET+VIEW+SELECTION_SET
    ORDERS=
    {
     ID          FIELDS            LABEL              ;
     ID          ( ID )            "Id"         VIS=HIDE UNIQUE=YES;
     MIES_O      (MIES_O ID)       "Miesiące"   VIS=HIDE;
    }
{
ID      LEN     TYPE     NAME   ;
ID      8       INT      ""     VIS=HIDE;
MIES_O 15      STRING   "Miesiące";
}

Dla pozostałych dwóch tabel należy wykonać podobne upożądkowanie. Inaczej sprawa wygląda jeżeli chodzi o tabele GODZINKI, ponieważ zawężamy tą tabelę po trzech polach należy wpisać wszystkie możliwe kombinacje dostępne na tych polach. Poniżej podajemy kombinacje tych pól (jeżeli będzie brakować któregoś z uporządkowań to proszę dopisać go do pliku)

ORDERS=
        {
        ID           FIELDS                LABEL VIS ;
        ID           ( ID )                  -   HIDE;
        MIES         (MIES ID)               -   HIDE;
        MIESDLAK     (MIES DLA_KOGO ID)      -   HIDE;
        MIESDLAKOPIS (MIES DLA_KOGO OPIS ID) -   HIDE;
        MIESOPIS     (MIES OPIS)             -   HIDE;
        DLA_KOGO     (DLA_KOGO ID)           -   HIDE;  
        DLAKOPIS     (DLA_KOGO OPIS ID)      -   HIDE;
        DLAKMIES     (DLA_KOGO MIIES ID)     -   HIDE;
        DLAKOPISMIES (DLA_KOGO OPIS MIES ID) -   HIDE;
        OPIS         (OPIS ID)               -   HIDE;
        }

Kolejna radą którą można zastosować jest zablokowanie możliwości dodawania miesięcy. Ponieważ program zawęża ściśle po określonych nazwach miesięcy, w tabeli MIESIACE będzie tylko 12 wpisów i edycja ich mogła by źle wpłynąć na prace programu należy je zablokować. Przed zablokowaniem należy uruchomić program i wprowadzić potrzebne miesiące. Następnie zamykamy program i rozpoczynamy edycję pliku struct.qcon. Znajdujemy wpis konfigurujący tabele MIESIACE, a w nim paramety BROWSER_ACTIONS. Istniejący wpis zamieniamy na
BROWSER_ACTIONS=-MODIFY_SET+VIEW-SELECTION_SET. Spowoduje to zablokowanie możliwości dodawania i modyfikowania istniejących wpisów. Więcej o możliwościach parametru BROWSER_ACTIONS można przeczytać na naszych stronach w odpowiednim suplemencie technicznym.

Koniec

Mam nadzieję że opis powstawania programu Q-Godzinka 3000 był dla Państwa jasny i nie sprawił wiele kłopotów podczas tworzenia programu. Informacje zawarte w tym opisie mogą znależć zastosowanie przy tworzeniu innych programów serii Q-Line 3000. W przypadku wystąpienia problemów prosimy o kontakt z naszą firmą, postaramy się pomóc Państwu przy tworzeniu programów za pomocą naszych rozwiązań.

Powrót