Novinky pro vývojáře únor - říjen 2012

vydání: 20121109 - verze: 14

Volání funkcí knihoven v prostředí .Net pro Vario

Z Varia lze volat funkce v prostředí .NET pomocí rozšíření .NET. Původně bylo rozšíření pro .NET realizováno knihovnou VarioRunNET. Ta je již zastaralá. Nově je volání realizováno knihovnou Altus.Common.Interop, která nahrazuje knihovnu VarioRunNET. Aktuální vydání Varia podporuje oba způsoby volání knihoven pro prostředí .NET. Do budoucna budeme preferovat novou knihovnu Altus.Common.Interop.

Knihovna Altus.Common.Interop

Na webu http://www.altusvario.cz/download/ je možno stáhnout instalační program (Rozšíření NET), který nainstaluje knihovnu Altus.Common.Interop.dll. Tato knihovna se registruje jako standardní COM object a umožňuje volání funkcí knihoven, napsaných v .NET.

Knihovna poskytuje následující metody:

void SetCallContext(string context)
void SetCallContextData(string name, object value)
object GetCallContextData(string name)
string AssemblyFileVersion(string dllPath)
object Run(string DLLPath, string className, string methodName, ref object[] pars)
void RunAsync(string DLLPath, string className, string methodName, ref object[] pars, IAsyncCallbackListener listener)
object RunRemote(string DLLPath, string className, string methodName, ref object[] pars, string ServerURL)
void RunRemoteAsync(string DLLPath, string className, string methodName, ref object[] pars, string ServerURL, IAsyncCallbackListener listener)

a zpřístupňuje rozhraní
interface IAsyncCallbackListener

Knihovna Altus.Common.Interop je kompilovaná s .NET FRAMEWORKEM 4.0 a umožňuje volat knihovny kompilované v této, nebo nižší verzi.

Nejzajímavější a nejvíce používaná je funkce Run:

object Run(string DLLPath, string className, string methodName, ref object[] pars)Tato funkce umožní spustit kód z obyčejné dll knihovny (class library) napsané v .NET.
Výhodou tohoto řešení je možnost využití vlastností a technologických vychytávek jazyků .NET (jako je C# a VB.NET), v aplikacích VBA (jako je třeba MS Access), VB6, nebo v jakékoliv aplikaci, která umožňuje volání COM objektů.

Tato funkce přijímá následující parametry:
string DLLPath - cesta a název dll knihovny, ve které chceme volat metodu.
string ClassName - namespace a název třídy, ve kterém se metoda nachází
string MethodName - název metody kterou voláme
ref object[] pars - seznam parametrů, které volaná metoda vyžaduje

Metoda Run vrací návratovou hodnotu volané metody.

Praktický příklad

Nainstalujeme knihovnu Altus.Common.Interop.

V příkladu použijeme naší knihovnu Altus.Common.Capi.dll, v praxi byste si napsali vlastní dll knihovnu.
Ve jmenném prostoru (namespace) Altus.Common.Capi je třída VBA a ta obsahuje následující funkci:string Hash(string data, string hashAlgorithn, string enconding) Tato funkce přijímá data, jejichž hash požadujeme. Dále přijímá požadovaný algoritmus, který bude použit na vytvoření HASHe. V našem případě jsou povoleny hodnoty {"cpSHA1";"cpSHA256"}. Poslední parametr je jazyková konverze. Zde jsou povoleny tyto hodnoty {"cp1250";"cpUTF8";"cpUnicode"}.
Poznámka: pokud nechcete řešit konverzi, upravíte si funkci tak, aby přijímala pole bytů (Byte[]).
Knihovna Altus.Common.Capi.dll je umístěna ve složce C:\Program files\Common files\Altus\Vario\12\. Vlastní knihovnu byste umístili do analogické složky (místo ..\Altus\.. bude vaše firma).
Spustíme MS Access (je též možno testovat v jakékoliv MS Office aplikaci), přidáme referenci na Altus.Common.Interop a vytvoříme proceduru Test().

Sub Test()
Dim text As String
Dim hash As String
Dim dll As String
Dim className As String
Dim ACI As Altus_Common_Interop.IApplication

text = "Ahoj Vario"
dll = "C:\Program files\Common files\Altus\Vario\12\Altus.Common.Capi.dll"
className = "Altus.Common.Capi.VBA"
Set ACI = New Altus_Common_Interop.Application
hash = ACI.Run(dll, className, "Hash", ArrayEx(text, "cpSHA1", "cpUTF8"))
End Sub

Private Function ArrayEx(ParamArray Args() As Variant) As Variant()
ArrayEx = Args
End Function

Pro volání metod knihovny Vario.Common.Interop, je knihovně VarioLib.dll vytvořena třída NETInterop.
Tato třída umožní vytvořit instanci objektu Altus.Common.Interop a volat jeho metody jednou řádkou.
Zatím umí pouze jedinou metodu Run(...), ale volání výše uvedeného příkladu je výrazně jednodušší:

Sub Test2()
Dim text As String
Dim hash As String
Dim dll As String
Dim className As String

text = "Ahoj Vario"
dll = "C:\Program files\Common files\Altus\Vario\12\Altus.Common.Capi.dll"
className = "Altus.Common.Capi.VBA"
hash = Vario.NETInterop.Run(dll, className, "Hash", text, "cpSHA1", "cpUTF8")
End Sub


Vario používá knihovny napsané v .NET pro následující úlohy:

  • Altus.Common.Capi.dll - Zajišťuje kryptografické funkce jako je podepisování a šifrování.
  • Altus.Common.ISDS.dll - Zajišťuje komunikaci s datovými schránkami.
  • Altus-Common.CreditCheck - Zajištuje komunikaci s webovými službami společnosti Credit Check, které podávají informace o kredibilitě firem.

Další metody a funkce knihovny Altus.Common.Interop

void SetCallContextData(string name, object value)Nastaví globální proměnné, které je možno pojmenovat. (Podobně jako Dictionary, nebo ParametrDotazu(), které znají programátoři Varia.)

object GetCallContextData(string name)Vrací obsah globální proměnné.

void SetCallContext(string context)Vstup context je očekáván v xml formátu a v podstatě hromadně načte data do globálních proměnných.
Názvy elementů jsou názvy proměnných a hodnoty jsou hodnoty.

string AssemblyFileVersion(string dllPath)Vrací verzi dll souboru kompilovaného v .NET.

void RunAsync(string DLLPath, string className, string methodName, ref object[] pars, IAsyncCallbackListener listener)

Asynchronní volání metody Run().

object RunRemote(string DLLPath, string className, string methodName, ref object[] pars, string ServerURL)Vzdálené volání metodou Run().
Volaná metoda se nachází v knihovně na jiném počítači.

void RunRemoteAsync(string DLLPath, string className, string methodName, ref object[] pars, string ServerURL, IAsyncCallbackListener listener)Vzdálené asynchronní volání metodou Run().

Pro použití asynchronního volání je potřeba vytvořit vlastní třídu a v ní implementovat rozhrani IAsyncCallbackListener.
Na toto rozhraní (jeho implementaci) se předá řízení vykonávání kódu po dokončení asynchronní operace.

Altus Vario Integration Services

Druhou možností volání funkcí jsou webové služby, které poskytuje server Altus Vario Integration Services.

Instalace je k dispozici na stránce stažení. Produkt naistalujete a nastavíte podle dokumentace Instalace a nastavení

Příklad volání webových služeb Altus Vario Integration Services:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace ConsoleApplication3

{

    class Program

    {

        //<client>

        //    <endpoint address="http://MyServer/Altus.COM.V12.WindowsService/MojeFirma/Altus.COM.V12.BasicServices.Produkty"

        //        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IProdukty"

        //        contract="ProduktyService.IProdukty" name="BasicHttpBinding_IProdukty" />

        //    <endpoint address="http://MyServer/Altus.COM.V12.WindowsService/MojeFirma/Altus.COM.V12.BasicServices.Kontakty"

        //        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IKontakty"

        //        contract="KontaktyService.IKontakty" name="BasicHttpBinding_IKontakty" />

        //    <endpoint address="http://MyServer/Altus.COM.V12.WindowsService/MojeFirma/Altus.COM.V12.BasicServices.Doklady"

        //        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDoklady"

        //        contract="DokladyService.IDoklady" name="BasicHttpBinding_IDoklady" />

        //</client>

 

        static void Main(string[] args)

        {

            ProduktySample();

            KontaktySample();

            DokladySample();

        }

 

        private static void DokladySample()

        {

            var service = new DokladyService.DokladyClient();

 

            var zakazka = new DokladyService.DokladContract()

            {

                Kniha = "Zakázky",

                TypZaznamu = "ZZ",

                NazevZaznamu = "Zakázka",

                Rok = 2012,

                Firma = "1. Experimentální společnost",

                rowguid = Guid.NewGuid(),

                CelkemBezDPH = 100,

                CelkemVcetneDPH = 120

            };

 

            var polozky = new List<DokladyService.DokladPolozkaContract>();

            polozky.Add(new DokladyService.DokladPolozkaContract()

            {

                Sklad = "Hlavní sklad",

                Produkt = "Autoatlas mini",

                Varianta = "-",

                Jednotky = "ks",

                MnozstviJednotek = 10,

                NazevSazbyDPH = "Základní",

                CelkemDPH = 20,

                CenaCelkemVcetneDPH = 120,

                CenaCelkemBezDPH = 100,

                rowguid = Guid.NewGuid()

            }

            );

 

            var skupinyPolozky = new List<DokladyService.DokladPolozkaSkupinyContract>();

 

            skupinyPolozky.Add(new DokladyService.DokladPolozkaSkupinyContract()

            {

                Mnozstvi = 10,

                rowguid = Guid.NewGuid(),

                Souvislosti = new DokladyService.DokladPolozkaSkupinySouvislostContract[] { }

            });

 

            polozky[0].Skupiny = skupinyPolozky.ToArray();

 

            zakazka.Polozky = polozky.ToArray();

            var zakazkaRG = service.VlozitNovyDoklad(zakazka);

            zakazka = service.NacistDokladRG(zakazkaRG);

 

            //rezervovat poloľky

            foreach (var p in zakazka.Polozky)

            {

                service.RezervovatPolozkuDokladu(p.rowguid);

            }

            zakazka = service.NacistDokladRG(zakazkaRG);

 

        }

 

        private static void KontaktySample()

        {

            var service = new KontaktyService.KontaktyClient();

 

            var pocetKontaktu = service.NacistPocetVsechKontaktu();

            Console.WriteLine("V systému je {0} kontaktů.", pocetKontaktu);

 

            // přidat kontakt

            var novy = new KontaktyService.KontaktContract();

            novy.Kniha = "Adresář";

            novy.TypKontaktu = "Organizace";

            novy.Firma = "1. Experimentální společnost";

            novy.NazevFirmy = "1. Experimentální společnost, a.s.";

            novy.Odberatel = true;

            novy.FakturacniAdresa = new KontaktyService.AdresaContract();

            novy.FakturacniAdresa.Ulice = "Pravotočivá 23";

            novy.FakturacniAdresa.Obec = "Praha 5";

            novy.FakturacniAdresa.PSC = "150 00";

            novy.FakturacniAdresa.ISOZeme = "CZ";

            novy.Telefon = "+420 158 998 765";

 

            var novyRG = service.VlozitKontakt(novy);

            novy = service.NacistKontaktPodleId(novyRG);

 

            //někdy později ho chci upravit

            novy.DorucovaciAdresa = new KontaktyService.AdresaContract();

            novy.DorucovaciAdresa.Ulice = "Přímoběžná 42";

            novy.DorucovaciAdresa.Obec = "Praha 7";

            novy.DorucovaciAdresa.PSC = "170 00";

            novy.DorucovaciAdresa.ISOZeme = "CZ";

 

            service.AktualizovatKontakt(novy);

 

            Console.ReadLine();

        }

 

        private static void ProduktySample()

        {

            try

            {

                var service = new ProduktyService.ProduktyClient();

 

                var pocetProduktu = service.NacistPocetVsechProduktu();

                Console.WriteLine("V systému je {0} produktů.", pocetProduktu);

 

                var produkt = service.NacistJedenProdukt("eKompas GPS", "-");

                Console.WriteLine("Produkt {0} má vlastnost [Internet] nastavenou na hodnotu {1}.", produkt.Produkt, produkt.Internet);

 

                produkt.Internet = "www.mb.sk";

                service.AktualizovatExistujiciProdukt(produkt);

 

                Console.ReadLine();

            }

            catch (System.ServiceModel.FaultException<ProduktyService.ExceptionContract> err)

            {

 

            }

        }

    }

}

Kompletní popis metod naleznete v souboru nápovědy Altus.COM.V12.Documentation.chm, který je obsahem instalace produktu.

Nové události ve třídě VarioEvents

Třída VarioEvents byla rozšířena o 3 události.

Public Event PriZmeneFirmyVDokladu(FormularDoklad As Object)

Volá se po zadání identifikátoru firmy, nebo IČ v detailu dokladu.

Public Event PriVyskladneniPoklesMnozstvi(ByVal Produkt As String, ByVal Varianta As String, ByVal Sklad As String, ByVal JakeMnozsvi As avVyskladneniPokles, ByRef Cancel As Boolean)

Událost se volá před zobrazením upozornění na pokles pod minimální množství ve skladu. Parametr Cancel umožňuje potlačit zobrazení dialogového okna s upozorněním.

Public Event PriVyskladneniPodRabatem(ByVal Produkt As String, ByVal Sklad As String, ByVal Doklady As String, ByRef Cancel As Boolean)

Událost se volá před zobrazením upozornění na vyskladnění pod rabatem. Parametr Cancel umožňuje potlačit zobrazení dialogového okna s upozorněním.

Zobrazení s předávacím dotazem a více databází

Ve vydání 20121101 byla publikována úprava překladu předávacích dotazů pro zobrazení, která umožňuje do předávacího dotazu dosadit název "číslované" databáze.

Do výrazu dotazu se uvede název databáze v hranatých závorkách. Místo čísla databáze se uvede #### nebo 5#### pro archiv.

Například:

FROM ... [DExp####].dbo.tabulka

Do sekce PASSTHROUGH_DATABASE se na prvním místě uvede databáze, nad kterou má být dotaz spuštěn a za tuto databázi se uvedou všechny databáze, které se mají nahradit ve výrazu dotazu. Databáze se oddělují znakem |. 

Například

;PASSTHROUGH_DATABASE=[Data####]|[DExp####]

Příklad dotazu

PASSTHROUGH=SELECT * FROM Doklady UNION SELECT SELECT * FROM [Data5###]..Doklady;
PASSTHROUGH_DATABASE=[Data####]|[Data5###]

Vrácení číselné řady po odstranění záznamů

V modulu mToolbary (Vario.mda) je nová procedura, která zajišťuje vrácení číselné řady po odstranění záznamů. Proceduru lze volat z funkce SmazatZaznamy, která zajišťuje odstraňování záznamů uživatelské agendy.

Deklarace

Public Sub SnizitCiselnouRaduProOdstraneneZaznamy(ByVal OdstraneneZaznamy As Collection)

Příklad volání

Dim SnizitCiselnouRaduProOdstraneneZaznamyZaznamy As New Collection
For Each Zaznam In OdstraneneZaznamy
    ....
    SnizitCiselnouRaduProOdstraneneZaznamyZaznamy.Add _
          Array(ZaznamPK, ZaznamTypZaznamu, ZaznamRok, ZaznamDatum, ZaznamKniha, ZaznamZaznam), ZaznamPK
Next Zaznam
SnizitCiselnouRaduProOdstraneneZaznamy SnizitCiselnouRaduProOdstraneneZaznamyZaznamy

Kde

  • ZaznamPK: primární klíč záznamu
  • ZaznamTypZaznamu: typ záznamu (pokud agenda používá typy záznamů)
  • ZaznamRok: u ročních agend rok, ze kterého byl záznam odstraněn
  • ZaznamDatum: datum vzniku záznamu
  • ZaznamKniha: kniha záznamu
  • ZaznamZaznam: název typu záznamu

Vystavení upomínek programem

V aplikaci Vydane_doklady.mda je nová funkce toDVUpominky(NazevNastaveni), která spustí vystavení upomínek podle uloženého nastavení.

Po vystavení upomínek zůstane otevřený dialog Pruvodce_vystavenim_upominek. Z tohoto dialogu je možno pomocí veřejné vlastnosti DatumVystaveni získat datum a čas, který je možno použít ve funkci OdeslaniUpomínek v parametru filtr (Datum_aktualizace = ...).

V případě, že by upomínky vystavoval automat bez uživatelské obsluhy, je potřeba před voláním funkce toDVUpominky nastavit vlastnost Vario.SilentMode na hodnotu True.

SDK - vzor událostního doplňku

Do vzorového doplňku Vzor_Udalostni_doplnek.mda byla přidána třída TestClassLib, která demonstruje zachycování událostí třídy VarioLib.Vario.

Událost PoOdstraneniPolozkyDokladu

Událost PoOdstraneniPolozkyDokladu se volala před opětným načtením položek, což mohlo působit potíže při pokusu o přístup k formuláři položek, který obsahoval odstraněné položky. Od vydání 20120321 se událost vyvolá až po obnovení (requery) formuláře položek.

Funkce oVystavitVratku odstraněna

Z Vario.mda byla odstraněna zastaralá funkce mSklad.toVystavitVratku (vydání 20120314).

Tiskový formulář pro konkrétní firmu (data)

V doplňku SDK je možno v detailu tiskového formuláře určit název firmy, pro kterou je určen tiskový formulář. V případě, že zadáte firmu tiskového formuláře, bude se tiskový formulář nabízet pouze v datech zadané firmy.

Poznámka: tohoto nastavení lze využít například pro tisk faktury, kde je napevno uvedena adresa nebo logo firmy. Připomínáme, že ve Variu 12 lze logo na fakturu nastavit uživatelsky. Lze také nastavit adresy naší firmy na doklad včetně adres poboček (adresa pobočky je určena přiřazením knihy dokladu pobočce).

Metoda ZkopirovatPolozku

Metoda nekopírovala záporné položky ze zakázek na vydané dobropisy (resp. z objednávek na přijaté dobropisy). Použití končilo chybou "Nelze kopírovat PDP mezi různými PV". V tomto vydání je kopírování záporných položek ze zakázek na dobropisy povoleno.

Funkce VystavitDobropis - Možnost ovlivnit zpracování vyrovnání

Do funkce VystavitDobropis (Vario.mda) byl přidán volitelný parametr ZpracovatVyrovnani s výchozí hodnotou True, který ovlivňuje, zda se má zpracovat vyrovnání. V některých zakázkových řešeních je zpracování vyrovnání nežádoucí a tímto parametrem jej lze vynechat.