Zaregistrované eventy se volají v pořadí, v jakém byly registrovány. Nejprve se provedou systémové, potom uživatelské.
Volání ve tvaru main(DSI)
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.
Volá se po zavření tabulky.
Proběhne po smazání řádku, v momentu po smazání už je kurzor na jiném řádku. Stav databáze je browse.
Po úpravě záznamu v databázi. Tabulka je ve stavu browse.
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.
Volá se po otevření tabulky.
Po uložení údaje do tabulky. Stav databáze je browse.
Při posunu na další řádek.
Před zrušením operace - stav databáze může být v editu, insertu, browse.
Před zavřením dabulky
Před smazáním řádku.
Před editací řádku.
Před vkládáním řádku, ještě jsem na původním řádku.
Před otevřením tabulky
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
Před posunem na další řádek.
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
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.
Volá se v BeforePost v případě, že došlo ke změně zadaného fieldu.
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.
-- 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
Provede se před zkopírováním záznamu tabulky.
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
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
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
Zde se realizuje cenová politika. Zaregistrovane funkce se volaji retezove. Pokud vrati nil neni hodnota vracena predchozi registovanou funkci ovlivnena.
Postup zjisteni ceny:
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
Zde se realizuje cenová politika. Funguje podobne jako GetCena, jen nedostava posledni parametr (Params)
fce(SourceDSI, destDSI) return cena
Zde se realizuje cenová politika. Funguje podobne jako GetCena, jen nedostava posledni parametr (Params)
fce(SourceDSI, destDSI) return cena
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
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
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
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
* není žádný parametr funkce
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
parametry: middle
Zaregistruje se ve volání WindowsManager:ShowFormSP(Form, {ExternalInsertLua=function_name})
Volání: function_name(Form, DSI)
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
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]
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
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