Obsah
Obecné informace
Pořadí volání
Zaregistrované eventy se volají v pořadí, v jakém byly registrovány. Nejprve se provedou systémové, potom uživatelské.
Eventy DataSetItem
Seznam
Volání ve tvaru main(DSI)
Popis
AfterCancel
vola se po operaci Cancel (napr. tlacitko X na db navigatoru, nebo kl. Esc) event je zavolan ve chvili, kdy je jiz radek uveden do puvodniho stavu.
AfterClose
Volá se po zavření tabulky.
AfterDelete
Proběhne po smazání řádku, v momentu po smazání už je kurzor na jiném řádku. Stav databáze je browse.
AfterEdit
Po úpravě záznamu v databázi. Tabulka je ve stavu browse.
AfterInsert
Po vložení záznamu do databáze. Tabulka je ve stavu browse. Nepřidávat zde žádné položky do detailů. Provede-li uživatel Cancel, zůstanou jako syrotci.
AfterOpen
Volá se po otevření tabulky.
AfterPost
Po uložení údaje do tabulky. Stav databáze je browse.
AfterScroll
Při posunu na další řádek.
BeforeCancel
Před zrušením operace - stav databáze může být v editu, insertu, browse.
BeforeClose
Před zavřením dabulky
BeforeDelete
Před smazáním řádku.
BeforeEdit
Před editací řádku.
BeforeInsert
Před vkládáním řádku, ještě jsem na původním řádku.
BeforeOpen
Před otevřením tabulky
BeforePost
Před zapsáním řádku do tabulky.
Ukázka kontroly editace hodnoty pouze vybranými uživateli. Pomocí řádkových práv lze zamezit editaci pouze celého řádku, tuto funkcionalitu lze také zajistit pomocí sloupcových práv k tabulce.
Výpis souboru user/lua/prost/v_prost_vykony.lua:
--nastaveni kodovani retezcu ve skriptu a lokalni funkce enc pro prekodovani local encoding="windows-1250" local function enc(Str) return tEnc(Str, encoding) end --vytvori tabulku pro uzivatelske funkce datasetu v_prost_vykony.lua cf.CreateTable("v_prost_vykony") -- registruje Event pro middle PROSTREDKY, dataset prost_vykony na funkci v_prost_vykony.BeforePost ClientSession:AddLUAEvent("PROSTREDKY.prost_vykony.BeforePost", "v_prost_vykony.BeforePost") --tato funkce se aktivuje pred zapsanim zmen v datasetu prost_vykony --a zamezi zmeny mnozstvi ve vykonech pro uzivatele, kteri nemaji priznak --ISAdmin (v tabulce uzivatelu) function v_prost_vykony.BeforePost(DSI) -- kontrola pouze pro uzivatele, kteri nemaji priznak ISAdmin if ClientSession:IsLoggedAdmin() == false then -- pokud se lisi nova a stara hodnota v sloupci mnozstvi, zobrazi se dialog -- cf.tonumber zajisti, ze pokud je v mnozstvi NULL prevede se na 0 if cf.tonumber(DSI:FieldByName("mn")) ~= cf.tonumber(DSI:OldFieldByName("mn")) then --pro prekodovani je zkracena syntaxe volani funkce enc"text" tzn. enc("test") dlg.message(enc"Nelze měnit množství") --pokud se z funkce BeforePost vrati false nebude zapis zmeny dokoncen return false end end end
BeforeScroll
Před posunem na další řádek.
OnCalcFields
Tento event musí zajistit výpočty Calculated fieldů. Volá se 1x pro každý řádek v gridu.
ClientSession:AddLUAEvent("POHYBY_TAB.sklad_prijemky.OnCalcFields", "v_sklad_prijemky.OnCalcFields") function v_sklad_prijemky.OnCalcFields(DSI) DSI:SetFieldByName("v_CenaCelksDPH", cf.tonumber(DSI:FieldByName("CenaCelk"))*1.19) end
OnNewRecord
Vola se ještě před eventy *Insert. Co se nastavi v ramci tohoto eventu, jeste neni brano jako zmena a v pripade ze neni explicitne radek postnut radek zmizi.
ChangeField
Volá se v BeforePost v případě, že došlo ke změně zadaného fieldu.
CanDelete
Vola se pred BeforeDelete nez se maze zaznam i s detailem.
Priklad pouziti: mam event BeforeDelete v rozpocty_rnakl, ktery se vola vzdy kdyz se maze polozka nakl.rekapitulace. Kdyz ale mazu cely rozpocet, nechci aby se BeforeDelete v rnakl volal. Pak si ho tedy v CanDelete v rozpocty_rozpocty odregistruju. A v AfterDelete v rozpocty_rozpocty zase zaregistruju.
UserDefined
- Druh - pro vložení druhu do tabulky
- Counter - pro nastavení IDFieldu dle počítadla , druh je již nastaven
-- nastaveni druhu faktury; event se zavola pri Appendu a hned se odregistruje ClientSession:AddLUAEvent("faktury.faktury_faktury.Druh.UserDefined", "faktury_faktury.NastaveniDruhuDokladu") function faktury_faktury.NastaveniDruhuDokladu(DSI) DSI:SetFieldByName("idfdruh", idfdruh) ClientSession:DeleteLUAEvent("faktury.faktury_faktury.Druh.UserDefined", "faktury_faktury.NastaveniDruhuDokladu" ) end
-- nastavení počítadla výdejky; event se zavola pri Appendu a hned se odregistruje ClientSession:AddLUAEvent("vydejky_tab.sklad_prijemky.Counter.UserDefined", "v_sklad_sklady.CounterUserDefine") function v_sklad_sklady.CounterUserDefine(DSI) DSI:SetFieldByName("idprijemka",ClientSession:GetCounter(res.idpocitadlo)) ClientSession:DeleteLUAEvent("vydejky_tab.sklad_prijemky.Counter.UserDefined", "v_sklad_sklady.CounterUserDefine") end
BeforeCopy
Provede se před zkopírováním záznamu tabulky.
AfterCopy
Provede se po zkopírování záznamu tabulky.
Příklad: zapsání aktuálního data a času do poznámky.
ClientSession:AddLUAEvent("SKLKARTY.sklad_karty.AfterCopy","v_sklad_karty.NowDoPoznamky") function v_sklad_karty.NowDoPoznamky(DSI) DSI:SetFieldByName("Poznamka",cf.Now()) end
ChangeFieldValue
Event se zavola pri opusteni dane bunky nebo pri ENTERu v případě, že došlo ke změně zadaného fieldu. Databáze je v editu nebo insertu.
ClientSession:AddLUAEvent("prostredky.prost_vykony.IDZakaz.ChangeFieldValue", "v_prost_vykony.IDZakazChangeFieldValue") ClientSession:AddLUAEvent("vykprot.prost_vykony.IDZakaz.ChangeFieldValue", "v_prost_vykony.IDZakazChangeFieldValue") function v_prost_vykony.IDZakazChangeFieldValue(DSI, FieldName) local idzakaz = cf.tostring(DSI:FieldByName("idzakaz")) local sql = [[select * from zakazky_zakazky where idzakaz = ']]..idzakaz..[[' ]] local md=ClientSession:CreateMidFromXML(sql) local ds=md:FindDataSetItem("") ds:LocateRange("","") if cf.tonumber(ds:RecordCount()) == 0 and idzakaz ~= "" then cf.ShowMsg(enc"Neexistující zakázka !!!\nNelze zapsat.") DSI:SetFieldByName("idzakaz", DSI:OldFieldByName("idzakaz")) elseif ds:FieldByName("stav") == "U" and idzakaz ~= "" then cf.ShowMsg(enc"Ukončená zakázka !!!\nNelze zapsat.") DSI:SetFieldByName("idzakaz", DSI:OldFieldByName("idzakaz")) end md=md:Free() end
ChangeIndexes
ChangeRange
BeforePostMasterChange
PrintRow
Při zobrazování řádků v gridu. Zde se realizuje vlastní obarvování.
ClientSession:AddLUAEvent("CENIK.rozpocty_cenik.PrintRow", "v_rozpocty_cenik.PrintRow") function v_rozpocty_cenik.PrintRow(DSI) --viz. colors.lua (cerveny font na bilem pozadi tucne) return {FontColor=clRed, FontStyle=FontStyleBold, BrushColor=clWhite} end
Barva fontů
GetCena
Zde se realizuje cenová politika. Zaregistrovane funkce se volaji retezove. Pokud vrati nil neni hodnota vracena predchozi registovanou funkci ovlivnena.
Postup zjisteni ceny:
- nejprve se zavola GetCenikCena (ta bere defaultne sloupec Cena z tabulky a pak vola retezove GetCenikCena eventy)
- zavola retezove v poradi registrace fce GetCena
- pokud GetCena vraci nil, neni hodnota ceny zmenena
- tj. posledni funkce GetCena ktera vrati hodnotu je pouzita
fce(SourceDSI, destDSI, tParm) return cena tParm = { IDPartner=val, CenikCena=val, Mnozstvi=val}
Ukázka cenové politiky při tvorbě výdejky. Pokud se vydáva ze skladu '01' pak se vkladá Cena1; sklad '07' = Cena2; sklad '13' = Cena3; ostatní sklady = Cena
--registrace eventu ClientSession:AddLUAEvent("SKLKARTY.sklad_karty.GetCena", "CenovaPolitikaKarty") function CenovaPolitikaKarty( DSI, DestDSI, Params) --nastaveni DataSetu z hlavicky vydejky pro zjisteni cisla skladu local SkladDS=DestDSI:OwnerMiddleDB():FindDataSetItem("sklad_prijemky") --kontrola jestli se opravdu tvori vydejka; karty se mohou vkladat do rozpoctu - pak konec if not SkladDS then return end --nastaveni cisla skladu local idsklad=SkladDS:FieldByName("idsklad") --podminky pro vyber ceny na zaklade cisla skladu if idsklad=="01" then return DSI:FieldByName("Cena1") end if idsklad=="07" then return DSI:FieldByName("Cena2") end if idsklad=="13" then return DSI:FieldByName("Cena3") end return Params.CenikCena end
GetCenikCena
Zde se realizuje cenová politika. Funguje podobne jako GetCena, jen nedostava posledni parametr (Params)
fce(SourceDSI, destDSI) return cena
GetNaklady
Zde se realizuje cenová politika. Funguje podobne jako GetCena, jen nedostava posledni parametr (Params)
fce(SourceDSI, destDSI) return cena
ShowLookupField
Se volá ve chvíli kdy uživatel zmáčke tlačítko se třemi tečkami. Návratový kód funkce je vložen do Fieldu, nil je ignorován.
ClientSession:AddLUAEvent("REZERV.sklad_rezobjva.IDObjed.ShowLookupField", "v_sklad_rezobjva.ShowLookupField") function v_sklad_rezobjva.ShowLookupField(DSI, FieldName) local polozkyDS = DSI:OwnerMiddleDB():FindDataSetItem("sklad_rezerv") local IDSkladKarta = polozkyDS:FieldByName("IDSkladKarta") local ID = polozkyDS:FieldByName("ID") local IDRezerv = polozkyDS:FieldByName("IDRezerv") local tabulka = '' if DSI:FieldByName("v_zdroj")=='O' then tabulka = "sklad_objpol" elseif DSI:FieldByName("v_zdroj")=='R' then tabulka = "sklad_rezerv" end local sql = [[select * from ]]..tabulka..[[ where IDSkladKarta = ']]..IDSkladKarta..[[' AND IDRezerv != ']]..IDRezerv..[[']] if DEBUG_DETAIL and DEBUG_DETAIL>1 then DEBUG_WRITE({sql=sql}) end local srcMD=ClientSession:CreateMidFromXML(sql) local sqlDS = srcMD:FindDataSetItem("") sqlDS:LocateRange("","") local form=WindowsManager:CreateDetailMidDBForm(srcMD) local outSP=WindowsManager:ShowFormSP(form, {Modal=true}) form=form:Free() if outSP.MRCode==2 then srcMD=srcMD:Free() return end if DEBUG_DETAIL then DEBUG_WRITE({OutSP=outSP}) end DSI:Edit() DSI:SetFieldByName("IDobjed",sqlDS:FieldByName("IDRezerv")) DSI:SetFieldByName("IDO",sqlDS:FieldByName("ID")) DSI:Post() srcMD:Free() end
SetFilter
Registruje se k pouze k DSI a volá se pro všechny Middle, kde se tabulka vyskytuje. Funkce dostává DSI, MDName a vrací wherestring, který se připojuje pomocí and k stávajícímu filtru.
ClientSession:AddLUAEvent("sklad_karty.SetFilter", "v_sklad_karty.SetFilter") function v_sklad_karty.SetFilterUser(DSI, MDName) --umozni zobrazeni karet z druhu "adm" pouze Adminum if not ClientSession:ISLoggedAdmin() then return [[COALESCE(IDDruh,'') != 'adm']] end end
AfterPasteClipboard
Volá se na konci kopírovaní CTRL+V, záznam je postnutý. Pokud se kopíruje více záznamů volá se jen jednou na konci, DSI na je posledním kopírovaném.
ClientSession:AddLUAEvent("rozpocty.rozpocty_rozpocty.AfterPasteClipboard", "rozpocty_rozpocty.AfterPasteClipboard") function rozpocty_rozpocty.AfterPasteClipboard(DSI) if DSI:OwnerMiddleDB():FindDataSetItem("rozpocty_rkap"):GetState()==STATE_BROWSE then DSI:OwnerMiddleDB():FindDataSetItem("rozpocty_rkap"):Refresh() --refresh kap. aby se doplnily OnCalc fiedly, ktere se pri kopirovani nepocitaji end end
AfterCopyDetails
Volá se po zkopírovaní všech slave tabulek, pro každý jednotlivý RootDSI záznam, RootDSI je postnuté.
ClientSession:AddLUAEvent("ROZPOCTY.rozpocty_rozpocty.AfterCopyDetails","rozpocty_rozpocty.AfterCopyDetails") function rozpocty_rozpocty.AfterCopyDetails(DSI) print("AfterCopyDetails", DSI:FieldByName("IDRozp"), DSI:GetState()) end
Ukázky postupu volání eventů
Insert
- ChangeFieldValue pro nastavovné sloupce (ID apod.)
- Druh.UserDefined
- Counter.UserDefined
Eventy Middle
Seznam
Popis
BeforeActivate
* není žádný parametr funkce
AfterActivate
BeforePassivate
AfterPassivate
DataToDenik
Event se spouští při Postu hlavičky v deníku, pokud jsou prázdné položky zaúčtování. Funkce pak dostává zdrojové Middle a ID (číslo zdrojového dokladu). Funkce pak vrátí Middle, které obsahuje jeden ResultDSI s rozúčtováním (datamodel odpovídá položkám rozúčtování, ale sloupec s částkou se jmenuje CenaCelkem). Pokud nemá položka v ResultDSI vyplněnu cenu, tak se do rozúčtování nevloží.
ClientSession:AddLUAEvent("majetek.DataToDenik", "majetek_majetek.DataToDenik") function majetek_majetek.DataToDenik(Middle, ID) if DEBUG_DETAIL then DEBUG_WRITE({ ID=ID }) end local IDMajetek, ID = cf.nextWord(";", ID) local M = ClientSession:CreateMidFromXML(string.format( [[select o.MDUcet, o.DalUcet, p.Cena as CenaCelkem, '' as IDZakaz, '' as IDStred from common_operace o, majetek_polozky p where o.IDOperace=p.IDOperace and p.IDMajetek='%s' and p.IDMpolP=%d]], IDMajetek, ID)) M:FindDataSetItem(""):LocateRange("", "") return M end
BeforePrint
parametry: middle
Eventy Forem
ExternalInsertLua
Zaregistruje se ve volání WindowsManager:ShowFormSP(Form, {ExternalInsertLua=function_name})
Volání: function_name(Form, DSI)
- Form je forma ze které se vkládá
- DSI je DatasetItem ze kterého vkládá
PageControlChanging
Volá se po přepnutí "ucha" ve formě.
Volání: function_name(Form, DSI, OldDSI)
OldDSI je DatasetItem "ucha" ze kterého se přepíná. V prvním volání je OldDSI=nil, při přepínání z "ucha" nastavení také. Pokud se prepina na nastaveni je DSI nil.
Event se registruje na Name formy z Formregistru, ktery se shoduje s name master tabulky.
ClientSession:AddLUAEvent("faktury_faktury.PageControlChanging", "faktury_faktury.PageControlChanging") function faktury_faktury.PageControlChanging(Form, DSI, OldDSI) --pokud se prepina do seznamu faktur z jineho ucha s DSI je Recalc if OldDSI and DSI and DSI:GetPrimaryIndex() == DSI:OwnerMiddleDB():FindDataSetItem(""):GetPrimaryIndex() then faktury_faktury.Recalculate(DSI) end end
CloseQuery
Volá se při zavření okna. Vrati-li funkce false, okno nebude zavřeno.
Volání: function_name(Form, DSI, Button)
Button = [MR_OK|MR_CANCEL]
CanShow
- ClientSession:AddLUAEvent("form_name.CanShow", FuncName)
- FuncName(Form, DSI) return ErrMsg:string|nil
ClientSession:AddLUAEvent("partneri_partneri.CanShow", "partneri_partneri.CanShow") function partneri_partneri.CanShow(Form, DSI) Form:MergeLocalMenuFromXML(Form:GetMiddleDB():FindDataSetItem(""), partneri_partneri.GetRychleAkceXMLMenu("partneri_partneri_RychleAkceClick", "RychleAkce")) end ClientSession:AddLUAEvent("SKUPINY.CanShow", "common_skupiny.SkupinyCanShow") function common_skupiny.SkupinyCanShow(Form, DSI) if not ClientSession:IsLoggedAdmin() then return enc"K tomuto modulu má přístup pouze administrátor" end end
Ukazka spousteni registrovanych eventu v LUA
local MD=ClientSession:ActivateMid("Faktury") local DSI=MD:FindDataSetItem("") DSI:LocateRange("","") for Event, Val in pairs(DSI:GetInfo("none").Events) do if string.find(Event, "%.PrintRow$") then for i, v in ipairs(Val) do print(assert(loadstring(string.format("return %s(...)", v.Function)))(DSI)) end end end