_SortGenerate

(    Mode           : Byte;
     RefDate        : Date;
     SepDate        : Date;
     Periods        : String;
     Rights         : Longint;
     PolRNStr       : String[10];

     PolName        : String[10];
     OnlyId         : String;
     Except         : Byte;

     ...

 dim Error          : String) : Byte

Tato funkce spouští universální generátor třídění zaměstnanců. Způsob práce a pojetí parametrů řídí parametr Mode.

Mode

Řídí způsob práce funkce a pojetí vstupních parametrů.

Společné parametry:

RefDate Referenční datum pro získávání historických hodnot.
SepDates Separační datum pro získávání historických hodnot.
Periods Seznam požadovaných mzdových období ve formě řetězce. Jedná se o seznam roků a měsíců oddělených oddělovači | nebo ; . Seznam musí obsahovat vždy celé páry: 'měsíc|rok'.
Rights Přístupová práva (skupiny) na zaměstnance. Jestliže zadáte 0, budou automaticky doplněna přístupová práva pro přihlášeného zaměstnance.
PolRNStr Název položky, ve které je uloženo režijní středisko pro rozpočítání nákladů (Př.: 'O0400').

Jestliže bude tento parametr prázdný, nebudou SQL příkazy vytvářeny s ohledem na rozpočítávání nákladů ani u projektů, zakázek a zdrojů.
... ...
Error Jestliže funkce vrací false, je zde textová informace o chybě.

Společné parametry - seznam třídicích kritérií:

Skupiny těchto položek se opakují do té doby, než bude v název položky '#'.

PolName Název položky ve tvaru 'O0400'. Položka musí existovat, nebo může být prázdná. V tom případě nebude třídění bráno v úvahu. Načítání třídicích kritérií končí ve chvíli, kdy bude nalezen název položky '#'.
OnlyId

Jestliže se jedná o relační položku (například relace na střediska), lze v tomto řetězci omezit množinu nalezených středisek. Formát je: identy oddělené oddělovači | nebo ; .

Jestliže jako první znak napíšete '#', následuje číslo skupiny systemu označení _DiaMark. Lze tak používat standardní system označování vět.

Except true = identy v parametru OnlyId budou z výsledného třídění vypuštěny
false = pouze věty s identy v parametru OnlyId budou do výsledného dotazu zahrnuty
'#' Toto jméno položky ukončí načítání třídicích kritérií.

Mode: sortVratSQL

      ...
 dim From           : StringZ;
 dim Where          : StringZ;
 dim OrderBy        : StringZ;
     ...

Vrací výsledný SQL příkaz, pro setřídění jednotlivých zaměstnanců, bez vykonání. Jestliže bude potřeba vytvořit pomocné tabulky, budou vytvořeny.

Aby bylo možno používat příkazy rovnou v programu 'Microsoft SQL Server Management Studio', dodá funkce před jména tabulek vlastníka ve tvaru 'XXXX.'. Pak lze jednoduše funkcí najdi / nahraď zaměnit tento řetězec za jiný.

Příklad:

dim nMes        : Integer;
dim nRok        : Integer;
dim dtRef       : Date;
dim dtSep       : Date;
dim sFrom       : StringZ;
dim sWhere      : StringZ;
dim sOrderBy    : StringZ;

Mes := _ActMonth;
Rok := _SysYear;

dtRef := _LastDate(nMes,nRok);
dtSep := _LastDate(nMes,nRok);

if(_SortGenerate(sortVratSQL, dtRef, dtSep, _Str(nMes) + "|" + _Str(nRok), 0 { Rights }, "O0400",
    "O0400", "", false,
    "O0407", "", false,
    "#",
    sFrom, sWhere, sOrderBy, sError))then

    printup(_PutToClipboard("select OSOBNI.O0007" + #13+#10 + 
                            "from "  + sFrom  + #13+#10 + 
                            "where " + sWhere + #13+#10 + 
                            "order by " + sOrderBy));
else
    _MsgBox(0, "Chyba třídění: " + sError, 0);	
endif

Příklad výsledku z clipboardu:

select OSOBNI.O0007
    from ((((XXXX.OSOBNI
        inner join XXXX.RN_MZDY rnm on (rnm.XUVAZEKID=OSOBNI.IDENT and rnm.XPERIOD=132055041) ) 
        inner join XXXX.RN_MZDY_CAST rnmc on (rnmc.XPARENTID=rnm.IDENT) ) 
        left outer join XXXX.CEN rn1 on (rn1.IDENT=rnmc.XTKCENID) ) 
        left outer join XXXX.RN_PROJEKTY rn2 on (rn2.IDENT=rnmc.XTKPROJEKTID) ) 
    where exists(select * from XXXX.RIGHTS R  where (OSOBNI.IDENT=R.XMANIDENT) and (R.XPERIOD=132055041) and 
        (R.XR0 = 1 or R.XR1 = 1 or R.XR2 = 1 or R.XR3 = 1)) 
    group by OSOBNI.IDENT,rn1.XNAME,rn1.IDENT,rn2.XNAZEV,rn2.IDENT,OSOBNI.O0007,OSOBNI.O0006 
    order by rn1.XNAME,rn2.XNAZEV,OSOBNI.O0007,OSOBNI.O0006

Mode: sortVratSQLSumRN

Mode:sortVratSQLSumRNZam

      ...
 dim From           : StringZ;
 dim Where          : StringZ;
 dim OrderBy        : StringZ;
 dim FPopis         : File;
     ...

Vrací výsledný SQL příkaz pro agregaci částí mzdy z rozpočítávání nákladů podle zadaných třídicích kritérií. Vracený dotaz je možné použít pro získávání nasčítaných částí mzdy.

Aby bylo možno používat příkazy rovnou v programu 'Microsoft SQL Server Management Studio', dodá funkce před jména tabulek vlastníka ve tvaru 'XXXX.'. Pak lze jednoduše funkcí najdi / nahraď zaměnit tento řetězec za jiný.

Do klauzule Where bude vždy dodán příkladný text 'rnmc.XPOLIDX=101 or rnmc.XPOLIDX=271', který nahradíte vlastním seznamem potřebných mzdových položek. Jestliže potřebujete všechny mzdové položky, nahraďte ho výrazem 'rnmc.XPOLIDX<>0'.

Ve streamu FPopis přichází informace popisující použité sloupce.

FPopis Data
0 Textový sloupec pro třídění (třeba název střediska Př.:'rn1.XNAME') pro SQLBind.
1 Skutečný typ třídicí položky (polString, polInteger, polLongint, ...)
2 Jestliže se jedná o relaci - typ databáze (dbtStr, ...) - jinak 0
3 Jestliže se jedná o relaci - ident sloupce relace (Př.:'rn1.IDENT') pro SQLBind. - jinak ''
    -- následuje druhé třídicí kriterium --  
10 Textový sloupec pro třídění (třeba název střediska Př.:'rn1.XNAME')
... ...

Mode sortVratSQLSumRNZam vytvoří SQL tak, aby byli rozděleni zaměstnanci.

Příklad:

Ukazuje součet mzdové položky M0281 podle třidicích kritérií O0400 (Nákladová střediska) a O0407 (Projekty)

procedure Test1
    dim nMes, nRok              : Integer;
    dim dtRef, dtSep            : Date;
    dim sFrom, sWhere, sOrderBy : StringZ;
    dim sError, S, sCol         : String;
    dim Set                     : Word;
    dim sL1, sL2, sL3           : StringZ;
    dim nIdxPol, nIdx           : Integer;
    dim rSum                    : Real;
    dim FPopis                  : File;
    dim nDBT1, nDBT2, nDBT3     : Longint;
    dim nRel1, nRel2, nRel3     : Longint;

    nMes := _ActMonth; nRok := _SysYear;
    dtRef := _LastDate(nMes,nRok); dtSep := _LastDate(nMes,nRok);

    SRewrite(FPopis, "", true);
    if(_SortGenerate(sortVratSQLSumRN, dtRef, dtSep, _Str(nMes) + "|" + _Str(nRok), 0 { Rights }, "O0400",
            "O0400", "", false,
            "O0407", "", false,
            "#",
            sFrom, sWhere, sOrderBy, FPopis, sError))then
				
        SQLOpen(SQLDB_SYSHANDLE, Set);
	{ Bind sloupců podle popisu ve streamu FPopis }    
        nIdx := 0;
        while(_SGetTyp(FPopis, nIdx) <> 0)do
            if(nIdx = 0)then
                nDBT1 := _SGet(FPopis, nIdx+2);
                call PridejDBSloupec(_SGet(FPopis, nIdx+0), sL1, nDBT1, _SGet(FPopis, nIdx+3), nRel1);
            else
                if(nIdx = 10)then
                    nDBT2 := _SGet(FPopis, nIdx+2);
                    call PridejDBSloupec(_SGet(FPopis, nIdx+0), sL2, nDBT2, _SGet(FPopis, nIdx+3), nRel2);
                else
                    if(nIdx = 20)then
                        nDBT3 := _SGet(FPopis, nIdx+2);
                        call PridejDBSloupec(_SGet(FPopis, nIdx+0), sL3, nDBT3, _SGet(FPopis, nIdx+3), nRel3);
                    endif
                endif
            endif
            _Inc(nIdx, 10);
        endwhile
        SQLBind(Set, "rnmc.XPOLIDX",		SQL_INTEGER, 	nIdxPol);
        SQLBind(Set, "sum(rnmc.XCASTKA)",	SQL_DOUBLE, 	rSum);
        { Do klauzule Where doplníme pouze položku M0281 }
        nIdx := _Pos("rnmc.XPOLIDX=101 or rnmc.XPOLIDX=271", sWhere);
        if(nIdx <> 0)then
            Delete(sWhere, nIdx, _Len("rnmc.XPOLIDX=101 or rnmc.XPOLIDX=271"));
            Insert("rnmc.XPOLIDX=281", sWhere, nIdx);
        endif		
        { Z klauzule FROM vyházej vlastníka tabulek 'XXXX.' }
        call SmazSubString("XXXX.", sFrom);
        { Z klauzule WHERE vyházej vlastníka tabulek 'XXXX.' }
        call SmazSubString("XXXX.", sWhere);
        { Zpracuj agregace na SQL serveru }
        SQLSelect(Set, sFrom, sWhere, sOrderBy);
		
        if(_SQLFirst(Set))then
            repeat
                Trace(sL1, ", ", sL2, ", ", sL3, ", IdxPol:", nIdxPol, ", Sum:", rSum);
            until _SQLNext(Set) = false;
        endif

        SQLClose(Set);

    endif
	
    return;
	
    procedure PridejDBSloupec(    sCol      : String;
                              dim sLX       : StringZ;
                                  nDBType   : Integer;
                                  sColRel   : String;
                              dim nRelX     : Longint)
							  
        SQLBind(Set, sCol, SQL_VARCHAR, sLX);
        if(nDBType <> 0)then
            SQLBind(Set, sColRel, SQL_INTEGER, nRelX);
        endif
    endproc { PridejDBSloupec }

    procedure SmazSubString(    sSub : String;
                            dim sRes : StringZ)
        dim nIdx : Integer;
        repeat
            nIdx := _Pos(sSub, sRes);
            if(nIdx <> 0)then
                Delete(sRes, nIdx, _Len(sSub));
            endif		
        until nIdx = 0;
    endproc { SmazSubString }

endproc { Test1 }

Mode: sortDoStreamu_1

      ...
 dim FDta           : File;
 dim FRel           : File;
     ...

Plní výsledný stream FDta daty z třídění.

Index streamu FDta Data
000000...99999 Identy úvazků
100000...199999 Období - Perioda v binárním tvaru 'RRRRMMDD'
200000...299999 Data třídění 1
300000...399999 Data třídění 2
... ...

Dále plní výsledný stream FRel relacemi z třídění, jestliže relace existují. Jestliže relace neexistuje, stejně bude uložena nula.

Index streamu FRel Data
000000...99999 Ident relace pro třídění 1.
100000...199999 Ident relace pro třídění 2.
200000...299999 Ident relace pro třídění 3.
300000...399999 Ident relace pro třídění 4.
... ...

Mode: sortDoStreamu_2

      ...
 dim FDta           : File;
 dim FRel           : File;
     ...

Plní výsledný stream FDta daty z třídění. Jedná se o speciální formát záznamů tak, jak ho používala původní makra. Věty jdou za sebou 1..x .

Konstrukce záznamu je:

  | 24 | 24 | 24 | 34 | 4 |     | 24 | 24 | 24 | 34 | 4 | 4 |
 +-------Key(110)--------+     +-----------114-------------+
 +------------------------224+4=228------------------------+

 dim Jmeno  : String;
 dim MesRok : String;
 Jmeno := _RightSP(O[oJmeno], 34);
 MesRok	:= _StrPut(_SysYear, _ActMonth);
 PomS := _RightSP(lsKeyCS + _StrToCSW(_UpperS(Jmeno)) + MesRok, 114) + Key + Jmeno + MesRok + _LIToKey(O[dbIdent]);

Konstrukce streamu FRel je stejná jako u sortDoStreamu_1.

Poznámky:

Podívejte se na: Ostatní

Příklad:

call TestSortGenerate;
exit

procedure TestSortGenerate
    dim sError      : String;
    dim dtRef       : Date;
    dim dtSep	    : Date;
    dim sFrom       : StringZ;
    dim sWhere      : StringZ;
    dim sOrderBy    : StringZ;
    dim	FDta        : File;
    dim	FRel        : File;
    dim Tag         : Byte;
    dim Mes, Rok    : Integer;
	
    Mes := _ActMonth;
    Rok := _SysYear;
    dtRef := _LastDate(Mes,Rok);
    dtSep := _LastDate(Mes,Rok);

    SRewrite(FDta,"",true);
    SRewrite(FRel,"",true);
    if(_DiaMark(dbtO, 400, Tag) = cmOK)then
        if(_SortGenerate(   1, dtRef, dtSep, _Str(Mes) + "|" + _Str(Rok), 0 { Rights }, "O0400",
                            "O0400", "#" + _Str(Tag), false,    { Nákladové středisko   }
                            "O0407", "", false,                 { Projekt               }
                            "",      "", false,                 { prázdné třídění       }
                            "#",
                            FDta, FRel,
                            sError) = true)
        then
            call ZobrazStream_1(FDta, FRel);
        else
            _MsgBox(0, "Chyba třídění: " + sError, 0);	
        endif
    endif
endproc

procedure ZobrazStream_1(dim FDta : File; dim FRel : File)
    dim UvazekId: Longint;
    dim Perioda : Longint;
    dim Idx     : Longint;
    dim sRec    : String;
    dim RelId1  : Longint;
    dim RelId2  : Longint;
    dim RelId3  : Longint;
    dim Data1   : String;
    dim Data2   : String;
    dim Data3   : String;
    dim T       : Text;
	
    TRewrite(T, "Test_SortGenerate.CSV");
    TWriteLn(T, "Jmeno;TK1;TK2;TK3");

    if(_SFirst(FDta, Idx))then
        repeat
            UvazekId    := _SGet(FDta,	Idx + 000000);
            Perioda     := _SGet(FDta,	Idx + 100000);
            if(_SGetTyp(FDta,Idx + 200000) <> 0)then Data1  := _SGet(FDta, Idx + 200000); endif
            if(_SGetTyp(FDta,Idx + 300000) <> 0)then Data2  := _SGet(FDta, Idx + 300000); endif
            if(_SGetTyp(FDta,Idx + 400000) <> 0)then Data3  := _SGet(FDta, Idx + 400000); endif
            if(_SGetTyp(FRel,Idx + 000000) <> 0)then RelId1 := _SGet(FRel, Idx + 000000); endif
            if(_SGetTyp(FRel,Idx + 100000) <> 0)then RelId2 := _SGet(FRel, Idx + 100000); endif
            if(_SGetTyp(FRel,Idx + 200000) <> 0)then RelId3 := _SGet(FRel, Idx + 200000); endif
				
            if(_FindRecId(dbtO, UvazekId))then
                TWriteLn(T, O[oJmeno],";",Data1,";",Data2,";",Data3);
            endif
        until _SNext(FDta, Idx) = false or Idx > 100000;
    endif
endproc

procedure ZobrazStream_2(dim F : File)
    dim Idx     : Longint;
    dim sRec    : String;

    if(_SFirst(F, Idx))then
        repeat
            sRec := _SGet(F, Idx);
            Trace(sRec);
        until _SNext(F, Idx) = false;
    endif
    SClose(F);
endproc