A CSENGŐ

Vannak, akik előtted olvassák ezt a hírt.
Iratkozzon fel a legújabb cikkekért.
Email
Név
Vezetéknév
Hogy szeretnéd olvasni a Harangszót
Nincs spam

Kérdés: Külső natív api összetevő a C++ for Linuxban (Ubuntu x64) 1С 8.3 rendszeren


VK-t írok, nem tudok csatlakozni az 1s-hez ubuntu-n. Még az 1s exapl sem kapcsolódik. Szóval egy kérdés ezzel kapcsolatban:

1) Megpróbálom csatlakoztatni a VK-t a cikkben szereplő VNCOMPS példából

(a link a legvégén található: "Másolás").
Belsőleg a NativeApi projektnek van makefile. Ezzel felépítem a .so könyvtárat az Ununtun.
De a "Csatlakoztassa a külső alkatrészt" 1 felszáll.
Hasonlóképpen, ha a "build.sh" használatával építek (a projekt gyökerében).

Magában a makefile-ben lecserélem a zászlót m32-ről m64-re, mert 1c és maga az x64 rendszer. (m32 paraméterrel úgysem veszi fel)
Íme egy példa a VK hívására az 1C 8.3-ból:
ConnectionDone = Csatlakoztasson egy külső alkatrészt("/home/alexeyubuntux64-20 gb/Documents/VNCOMP83/example/NativeAPI/AddInNative.so", "AddInNative", ExternalComponentType.Native); Csak ebben a témában van egy cikk.
De amennyire én látom, ezeket a pontokat már figyelembe vették és kijavították a VNCOMPS példában.

De ami azt illeti, üzlet az összeállítás paramétereiben. Az MB 32 bites külső komponens normál esetben a 32 bites 1c-hez kapcsolódik, de az Ubuntu x64 1c enterprise83 8.3.5-1486 amd64-en telepítettem. És fel akarom vinni neki VK-t.

Van valakinek ötlete, hogyan lehetne megoldani ezt a problémát?
A VNCOMPS példának működnie kell, de az összeállítási paramétereket javítani kell, vagy maga a platform, amelyen tesztelek, nem megfelelő.

Válasz:Érdekes módon lehet Java-ban külső komponenst írni?

Kérdés: A külső komponens (natív) nincs csatlakoztatva


Példa összeállítása ITS-sel, 64 és 32 bites rendszerekhez.

Én így kapcsolódom:
ConnectionResult = ConnectExternalComponent(CDLLPath, "Comp", ExternalComponentType.Native); Az egyik PC csatlakozik, a másik nem. OS között van különbség. Ahol megy a kapcsolat, ott van Win7, ahol nincs Win10. Ugyanakkor a szabványos összetevők működnek olyan PC-n, ahol az én összetevőm nem működik.

Különböző platformokon tesztelve (8.3.4.482, 8.3.6.2100, 8.3.11.2700, 8.3.12.1412).

Hogyan lehet megérteni, hogy miért nem kapcsolódik?

Válasz: vc_redist nem felejtette el?

Kérdés: 1C8 és egy külső komponens Native típussal


Jó napot.
Van egy BP 3.0.50.12 konfiguráció, és a Scales-Soft cég mérlegelési szándéka az UniServerAuto segítségével.
A fejlesztők összeállították a natív összetevőt a Windows 32 és 64 rendszerhez, és a maifest fájllal együtt archívumba helyezték. Van egy példa az 1C-re is, hogyan lehet súlyt számítani. Ebben a bináris adatokkal ellátott elrendezés segítségével ez az archívum van feltüntetve, ahogy én értem. A példában minden rendben van: az alkatrész be van szerelve, bekötve, majd létrejön a kapcsolat és leolvassák a súlyt.
De amint elkezdi átvinni magát 1C-ra, a súly nem kerül leolvasásra. Úgy tűnik, minden egyszerűen le van írva, de nem értem, hol van a gereblye.
Akinek lesz egy kis ideje - segítsen, nézze meg fél szemmel, talán a felszínen van a megoldás, de én valahol rossz helyen járok és valamit rosszul csinálok. Még soha nem dolgoztam natív technológiával...

A mellékletben pedig az én feldolgozó szövegem

Válasz:

Nos, van egy hírem...
Most kezdtem el lépésről lépésre nézni, hogy mikor kezd el kudarcot vallani. Ehhez létrehoztam egy üres adatbázist és feldolgozást a paranccsal. A szállító példájával analóg módon átvittem az elrendezést egy új konf-ra - ez másodszorra működik. Azok. Első alkalommal nem, másodszor igen. Ebből fakadt az a gondolat, hogy a feldolgozás során továbbra is szükséges lenne a komponens és az objektum összekapcsolását különböző eljárások szerint elkülöníteni.
Aztán layout kapcsolattal átvittem az adatbázisomba - működik. Fuh, ez már jó .... De szeretném anélkül, hogy módosítanám a konfigurációt, úgyhogy menjünk tovább

Megpróbálok egy elrendezést hozzáadni a feldolgozáshoz. A mérete azonnal 10 kb-ról 3 mb-ra nő, és jelentős lassulás észlelhető - nem fér bele. Elkezdek ásni egy komponens csatlakoztatása felé a dll-en keresztül. Azok. lényegében ugyanaz, mint ahol elkezdted. De van egy "DE": a felhasználó mappájában a dll neve alapján keresve észrevettem, hogy ez a dll ott van, ahol (ahogy én értem) az 1C-ben regisztrált dll-ek hozzáadva vannak:
C:\Users\USER\AppData\Roaming\1C\1cv8\ExtCompT
ennek megfelelően nem szükséges a dll teljes elérési útját használni, egyszerűen beírhatja a nevét:
ConnectExternalComponent("Add1CUniServerAuto32.dll", "UniServerAuto", ExternalComponentType.Native);

Megpróbálok... káromkodni a regisztrációnál, de visszaadja a mérlegelés eredményét. Kiderült, hogy a dll már regisztrálva van, ami azt jelenti, hogy csak csatlakoztatnia kell. Kiveszem és minden működik.
Összefoglalom:
1. A mérlegelés feldolgozásánál a Megnyitáskor eljárásban egy külső komponens csatlakoztatását és az objektumhoz való csatlakozást adtam hozzá.
2. A dll elérési útját nem én írtam, csak a nevét adtam meg.

Most ülök és azon gondolkodom, hogy mikor települt a dll 1C-ben? Szoftvertelepítéskor? Aligha... Ennek a dll-nek a fejlesztői konfigurációja futtatásakor hol van beállítva az űrlap megnyitásakor? Nem tudom, de közel áll hozzám... Mit gondolsz?
Másodszor, új helyen, amikor ugyanazt a terminált kell telepíteni, mit kell tenni, hogy minden működjön? Telepítse teljesen a szoftvert, futtassa a szállító konfigurációját, hogy ellenőrizze a munkát, és akkor (elméletileg) működnie kell a feldolgozásomnak? Valami kicsit bonyolult... Vagy miután telepítettem a szoftvert a feldolgozásomba, egyszer telepítsem az ExternalComponentet?

Szeretném hallani a véleményeteket erről...

Kérdés: Külső komponens.dll


Jó napot mindenkinek.
Kérdés.
dll összetevő, amely jól működik az 1C 7.7-ben
1s-ben a 8.1 egyáltalán nem akar elindulni...
Megpróbálta beilleszteni a C:\Program Files\1cv81\bin\cache1c.dll fájlba
Megpróbáltam regisztrálni a regsvr32 "C:\Program Files\1cv81\bin\cache1c.dll" segítségével
Probléma nélkül regisztrálva.
Amikor megpróbálom elérni, hibaüzenetet kapok:

Hiba a külső komponens betöltésekor! cache1c.dll
Eljárás Execute ButtonClick(Button) Kísérlet a külső komponens( "C:\Program Files\1cv81\bin\cache1c.dll"); Kivétel jelentés( "Hiba a külső komponens betöltésekor!"+ "cache1c.dll"); A kísérlet vége; Kísérlet // Összetevő objektum beszerzése. // m = Új ("cache1c.GTMcmd" ); m = Új COMObject("cache1c.GTMcmd" ); Kivétel jelentés(); A kísérlet vége; Vége eljárás

Válasz: A lehetetlenségig banális...
A hívások között szüneteket kell fenntartani (ezredmásodperc)...
Procedure ButtonExecuteClick(Button) Attempt // Szerezze be az összetevő objektumot. m = Új COMObject("cache1c.GTMcmd" ); Kivétel jelentés( "Nem sikerült létrehozni a külső komponens objektumot"); A kísérlet vége; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Connect(); m.pause(100); ...... stb
1s 7,7-re - ez nem szükséges, kiderül, hogy a keringés gyorsabb.

Kérdés: Egy külső komponens munkája az 1C szerverrel ...


Jó napot,

Van egy C ++ nyelven írt külső komponens, amelynek feladata, hogy információkat fogadjon egy külső adatbázisból, és visszaadja a lekérdezés eredményét értéktáblázat formájában az 1C-ben.
Az aktuális pillanatban értéktáblázat létrehozásához az IDispatch* pBackConnection interfészt használjuk, amelyet az Init() függvény paramétereként kap. Továbbá az 1C függvények segítségével egyszerűen létrehozok egy értéktáblázatot, kitöltöm és visszaküldöm a CallAsFunc második paraméterére (...).
A problémák az 1C vékonykliensekre való átállással kezdődtek. Szerver oldalon a külső komponens nem igazán indul el. Futtathatja a kliens oldalon, de az egész úgy néz ki, mint a mankó, és kiesik az általános "kliens-szerver" logikából az 1C-ben. Például az ügyfél nem érti, mi az értéktáblázat, problémák a "globális" változókkal, munkamenetekkel stb.
A NativeAPI e tekintetben még csonkoltabb.
A tamburával táncolás oda vezetett, hogy el tudtam indítani egy külső komponenst az 1C szerver alatt, DE a munka addig megy, amíg meg nem próbálják hívni az Invoke-ot a pBackConnectionen. A 8.2-es szerver 64 bites verziója addig próbál valamit csinálni, amíg le nem esik egy időtúllépéskor, a 32 bites verzió (a VK természetesen 32 bites is) azonnal leesik.
Feltételezem, hogy az 1C szerver nem szolgálja ki ezt a működési módot.
Ennek megfelelően kérdések merülnek fel, hogy ez ideiglenes, vagy az 1C logikája ennek a munkarendszernek a megszüntetésére korlátozódik? Ha lehetetlen ilyen módon létrehozni az 1C (értéktáblázat) belső struktúráit, akkor elvileg van-e leírás arról, hogy mi az értéktábla rendszerszinten, hogy megpróbáljuk létrehozni C +-ban +, töltse ki, majd csak 1C-t csúsztassa vissza visszatérési paraméterként? Szeretnék legalább egy irányt kapni, hogy merre kell ásni.

Köszönöm.

Válasz:

Egyet írsz és mást értesz.
Az 1C környezetben a különböző munkamenetekben látható változók deklarálása most sem lehetetlen, és korábban sem. Egy másik munkamenet fizikailag más folyamat.
A Session egy adatbázis-kapcsolati munkamenet, azaz. felhasználói munkamenet. Vagy beletesz valamit a sajátból és ebből a koncepcióból?

Egy munkameneten belül lehetett és most is lehetséges olyan változókat deklarálni a session modulban, amelyek a munkameneten belül különböző helyekről élnek és láthatók... valójában 4 db van belőlük.
- Session modul;
- Rendszeres alkalmazás modul;
- Felügyelt alkalmazás modul;
- Külső csatlakozó modul.

És természetesen emlékeznie kell a kontextusra. A kiszolgálókontextus nem érhető el közvetlenül a kliens oldalon, és fordítva.

Általában az 1C architektúra előírja, hogy az adatcsere folytatódik:
- paraméterek/eljárások/függvények visszaadásai révén;
- az ún. session paraméterekkel (nem lehetnek objektumok, valójában a palettán látható).

A táblázat az űrlapon... és bármilyen objektumtáblázathoz kapcsolódik (például feldolgozások)? vagy nem. Ha igen, akkor a szerveren (&AtServer) is elérhető és ott szerkeszthető....

És igen, a ValueTable nem érhető el UV-ben a kliens oldalon. Nos, az 1C így döntött.

Na gyere! Itt működik az Excel, működik az FSO és egy csomó minden más, de itt nem működik. Fogja meg a hibát és elemezze....

Kísérlet
...
a tetteid
...
Kivétel
str = DescriptionError();
A kísérlet vége;

A modern hardverképességek mellett ez egyáltalán nem érv.

Pusztán a személyes véleményed. Semmi köze a valósághoz. Semmiképpen sem. Még egyszer megismétlem, az 1C remekül működik COM-mal. In-proc és out-proc esetén egyaránt.

Adja meg a feltöltött kódot, és alkalmazza a VK-hoz.

Egyébként VK... a te esetedben COM vagy Native API?
Ha COM, akkor regsvr32-n keresztül regisztrálod... akkor hogyan "oldod meg" a bitmélység problémát?

Kérdés: Külső komponens beszerelése


Kérem, mondja meg, hogyan telepíthet egy külső összetevőt. A következő kód végrehajtásakor hibaüzenet jelenik meg. Keresse meg a NameDecl.dll fájlt az elrendezésben

SetExternalComponent("GeneralLayout.Layout") kísérlet; Kivétel EndTry ;
Hiba: A beépülő modul telepítése nem sikerült!

Válasz: ()
A ConnectExternalComponent("GeneralLayout.Layout", "NameDecl", ExternalComponentType.Native) FALSE értéket ad vissza,
New("AddIn.NameDecl.CNameDecl", Undefined) = (()): Típus nincs megadva (AddIn.NameDecl.NameDecl)

Kérdés: A natív dll nem csatlakozik az 1s 8.1-hez (fptrwin32_fz54_9_11_0_5549.dll)


Szia.
Az 1C frissítette a dll fájlt az online pénztárgépekhez atol az fdd 1.05-höz (az fptrwin32_fz54_9_11_0_5549.dll karbantartási folyamat része).
Van egy régi 1C 8.1-em. A 8.2-vel ellentétben nem támogatja a külső berendezésekkel végzett munkát ugyanúgy, mint a 8.2, ezért először regisztrálnia kell a dll-t a Windowsban, és csak azután csatlakoztatnia kell az 1C-hez?

ProgID = "AddIn.IntegrationComponent.ATOL_KKT_1C83_V9"; LoadExternalComponent("C:\fptrwin32_fz54_9_11_0_5549.dll"); ConnectExternalComponent(ProgID); Illesztőprogram = Új(ProgID);

Azonban a régi feldolgozást a "technology" com-ban írták, és az új natív. Ennek megfelelően a regisztráció során a regsvr32 hibát ad:
A modul betöltődött, de a DllRegisterServer belépési pont nem található. És azt javasolja, hogy ellenőrizze, hogy ez a fájl a megfelelő dll vagy OCX fájl-e.
Ki szembesült hasonló helyzettel, hogyan került ki? Úgy tudom, hasonló probléma lesz a 7.7-ben.
8.2 kód:

Layout = GetLayout("IntegrationComponent"); Cím = PlaceInTempStorage(Layout); ConnectExternalComponent(Cím, "IntegrationComponent", ExternalComponentType.Native); Illesztőprogram = New("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9");

1C 8.2:
Csatlakoztassa a külső komponenst (<Местоположение>, <Имя>, <Тип>)
1C 8.1:
Csatlakoztassa a külső komponenst (<Идентификатор объекта>)
Lehetőségek:
<Идентификатор объекта>(kívánt)
Típus: String. A külső komponens objektum programazonosítója (Programmatic Identifier). Meg kell egyeznie a rendszer regisztrációs adatbázisában (Registry) szereplő adatokkal.
Leírás:
Külső komponensobjektumokat csatlakoztat az 1C:Enterprise-hez.
Nem érhető el az 1C:Enterprise szerveren. Nem használják a külső csatlakozómodulban.
Jegyzet:
A külső összetevők kompatibilisek az 1C:Enterprise 7.7 összetevőkkel.
Példa:
Kísérlet
ConnectExternalComponent("AddinObject.Scanner");
alert("Vonalkód-leolvasó komponens betöltve");
Kivétel
alert("A vonalkód-leolvasó komponens nincs betöltve");
Kísérletek vége

Lehet valahogy ezt a dll-t 8.1-hez kötni vagy sem?

Köszönöm!

Válasz:

Nemrég nekem is volt ilyen problémám. Nem lehetett konvertálni az 1s későbbi verziójára. dll, amellyel ez a konfiguráció működik, egyszerűen leállt, és az 1c hiba miatt kiesett.
A problémát a következő módon oldották meg:
Létrehoztam egy üres 8.3-as adatbázist, amiben feldolgoztam a komponens inicializálását, majd 8.1-ről COM kapcsolaton keresztül elértem a korábban létrehozott adatbázist és ott inicializáltam a komponenst. Aztán már 8.1-ben meghívtam ennek a komponensnek a metódusait.
Természetesen ez egy mankó, de még nem találtam más kiutat (

8.3 kódpélda:
Rem Driver Export;
Funkció ConnectionComponentsCCP() Export
Kísérlet

Layout = GetLayout("IntegrationComponent");
Cím = PlaceInTempStorage(Layout);
ConnectExternalComponent(Cím, "IntegrationComponent", ExternalComponentType.Native);
Illesztőprogram = New("AddIn.IntegrationComponent.SMDrvFR1C20");
eredmény = igaz;​

Kivétel

eredmény = hamis;​

A kísérlet vége;
Eredmény visszaküldése
EndFunctions

Kódpélda 8.1

Funkció CreateDriverObject(Driver) Export

eredmény = igaz;

Kísérlet

ConnectionString="Fájl="""Adatbázis elérési útja""";
ComObject= Új COMObject("V83.ComConnector");
Connect = ComObject.Connect(ConnectionString);

Feldolgozás = Connect.Processing.ConnectingExternalComponent.Create();
ConnectionResult = Processing.ConnectingKKT Components();
Ha az eredmény összekapcsolódik, akkor
Illesztőprogram = Processing.Driver;
EndIf;

Kivétel
Aki csinált már ilyet, vagy tapasztalt hasonló problémát, kérem magyarázza el. egyszerű példa maga az elv. Úgy tűnik, hogy a külső alkatrészek csatlakoztatásával minden világos.

// Példa az értéktáblázat kitöltésére TK.Clear(); Request = Új kérés; Query.Text = "KIVÁLASZT | Nómenklatúra Link HOGYAN Nómenklatúra | Directory.Nomenclature AS Nomenclature"; QueryResult = Query.Execute(); Mintavétel = QueryResult.Select(); While Sampling.Next() Loop Str = TK.Add(); FillPropertyValues(Pr, Sampling); EndCycle;
Ezzel a példával meg tudnád magyarázni, hogy a kód melyik részét szokták kivenni? Logikus lenne a kéréssel ellátott alkatrészt kivenni, de akkor hogyan tudjuk a külső komponensről a platformot megkerülve elérni az adatbázist a külső komponensről? A szöveg értelmetlen. Vagy vegyük ki a táblázatos rész formáját. Kérjük, ossza meg ezzel kapcsolatos tapasztalatait.

Válasz:És hogy az "összeférhetetlen" szó mindig a "rossz" szót jelenti? Igen, úgy tűnik számomra, hogy ha a stílusomat „1C: A természetben létező legrosszabb programozás ezen a szkriptmotoron (irodalmi nyelvre lefordítva)” nevezem! és akkor biztosan lesz, aki meg akarja nézni ezt a fenevadat. És úgy néz ki, mint egy klasszikus: "Nem olvastam Pasternakot, de teljesen nem értek vele egyet!" :)

Kérdés: Külső összetevő csatlakoztatása az 1s 8.3.6-ban és a Win8-ban


A vk_rs232.dll ExternalComponentet csatlakoztatni kell a saját maga által írt konfigurációhoz. Mint regsvr32.exe-n keresztül regisztrálva. "Úgy tűnik", mert olyan üzenetet kaptam, hogy "az összetevő regisztrálva van, de valami nem stimmel a tűzfallal." Az üzenet első felére támaszkodva 1s alatt írom le a kódot
AfterConnection = Új értesítésleírás("AfterConnectionVK",Ez az űrlap); StartExternalComponentInstallation(,"C:\Controller\vk_rs232.dll"); StartConnectingExternalComponent(AfterConnecting,"C:\Controller\vk_rs232.dll","DLL_Scales");
és azt a hibát kapom
"A külső összetevő telepítése sikertelen! Lehet, hogy az Ön által használt ügyfélalkalmazás összetevője hiányzik!".

És most nem értem
1. Lehet, hogy az összetevő nincs bejegyezve a registry-be – hogyan tudom ott ellenőrizni?
2. Lehet, hogy a "verziója" nem működik Win8 alatt, bár nálam 32 bites.
3. Talán maga az 1s túl új, pl. ennek megfelelően nem működik ezzel a dll-vel?
4. Nos, ez banális – valamit rosszul írok.

Válasz:És mindez a következő problémához vezetett. A VneshComp telepítve van, most csatlakoztatnia kell. És itt van mindkét lehetőség.
ConnectExternalComponent("C:\Controller\vk_rs232.dll","Scales")
ConnectExternalComponent("GeneralLayout.Layout","Scales")

Szintaxis opció: Név és hely szerint

Szintaxis:

Csatlakoztassa a külső komponenst (<Местоположение>, <Имя>, <Тип>)
Lehetőségek:

<Местоположение>(kívánt)

Típus: String.
A külső komponens helye.
A helyszín használható:
a külső összetevő fájljának elérési útja a fájlrendszerben (a webes kliensben nem érhető el), nem ZIP-archívum;
teljes név bináris adatokat vagy ZIP archívumot tároló elrendezés;
A külső összetevő URL-címe bináris adatok vagy ZIP-archívum formájában, a GetNaviLink-hez hasonlóan.
<Имя>(kívánt)

Típus: String.
A csatlakoztatható külső komponens szimbolikus neve.
A névnek követnie kell a beépített nyelv elnevezési konvencióit.
<Тип>(választható)

Típus: ExternalComponent Type.
A csatlakoztatandó külső komponens típusa.
Nem használható, ha az összetevő ZIP-archívumban van csomagolva.
A módszerváltozat leírása:

Native és COM technológiával készült alkatrészeket csatlakoztat.
Az összetevő tárolható információs bázisban vagy konfigurációs elrendezésben bináris adatként vagy ZIP archívumban.
A "Vékony kliens" és a "Web kliens" indítási módokhoz az összetevőt előzőleg telepíteni kell a Külső összetevő telepítése módszerrel.
Szintaxis opció: ID szerint

Szintaxis:

Csatlakoztassa a külső komponenst (<ИдентификаторОбъекта>)
Lehetőségek:

<ИдентификаторОбъекта>(kívánt)

Típus: String.
Külső komponens objektum azonosító az MS Windows rendszerleíró adatbázisának ProgID (Programmatic Identifier) ​​formájában (például: "AddIn.Scanner").
Meg kell egyeznie a rendszer regisztrációs adatbázisában (Registry) szereplő adatokkal.
A módszerváltozat leírása:

Az összetevőt COM technológiával kell megvalósítani, és regisztrálni kell az MS Windows rendszerleíró adatbázisában.
Ezek az összetevők kompatibilisek az 1C:Enterprise 7.7 összetevőkkel.
Figyelem! A módszer változata nem működik a szerveren és a külső kapcsolaton.
Visszatérési érték:

Típus: Boolean.
Igaz - a kapcsolat sikeres volt.
Leírás:

Külső komponenst csatlakoztat az 1C:Enterprise-hez.
A külső összetevők tárolhatók az információs bázisban vagy a konfigurációs elrendezésekben ZIP-archívumként vagy bináris adatként, vagy fájlrendszerfájlként.
Ha vékony kliensen és webes kliensen dolgozik, az összetevőt előre telepíteni kell.

Elérhetőség:

Vékony kliens, webkliens, szerver, külső kapcsolat.
Jegyzet:

A külső összetevők Native API vagy COM technológiával implementálhatók. A COM technológiával készült alkatrészek kompatibilisek az 1C:Enterprise 7.7 komponensekkel.
A webes kliens csak az információs bázisban lévő olyan összetevőkkel tud dolgozni, amelyek archívumba vannak csomagolva.
A vékony kliens az információs bázisban lévő, archívumba csomagolt összetevőkkel és a fájlrendszerben található összetevőkkel tud dolgozni.
A vastag kliens az összetevők összes tárolási lehetőségével képes dolgozni. Ebben az esetben, ha a komponens telepítése az InstallExternalComponent metódussal történik, akkor a telepített komponens kerül felhasználásra, ha pedig nincs telepítve, akkor a komponens fogadása a csatlakozáskor történik meg.
A szerver minden komponenssel együtt tud működni. Az összetevő gyorsítótárban van a szerver munkamenethez.
Példa:

Ha ConnectExternalComponent("AddinObject.Scanner") Akkor
alert("Vonalkód-leolvasó komponens betöltve");
Másképp
alert("A vonalkód-leolvasó komponens nincs betöltve");
EndIf;

  • oktatóanyag

Bevezetés

Ez a cikk képet ad arról, hogyan működnek a külső összetevők az 1C:Enterprise rendszerben.
Megjelenik a Windows operációs rendszer alatt futó 1C:Enterprise 8.2-es verziójú rendszer külső összetevőjének fejlesztési folyamata a munka fájlverziójával. Ezt a lehetőséget a legtöbb kisvállalkozások számára tervezett megoldás használja. A VC C++ programozási nyelven kerül megvalósításra.

Külső összetevők "1C: Enterprise"

Az "1C: Enterprise" egy bővíthető rendszer. A bővítéshez funkcionalitás rendszer külső komponenseket (VC) használ. A fejlesztő szemszögéből a VC egy külső objektum, amelynek tulajdonságai és metódusai vannak, és eseményeket is generálhat az 1C:Enterprise rendszer általi feldolgozáshoz.
A külső komponensek olyan feladatok megoldására használhatók, amelyeket az 1C: Enterprise-ba épített programozási nyelv segítségével nehéz vagy akár lehetetlen megvalósítani. Ez az osztály különösen azokat a feladatokat foglalja magában, amelyek alacsony szintű interakciót igényelnek az operációs rendszerrel, például bizonyos hardverekkel való munkavégzés érdekében.
Az 1C:Enterprise rendszer két technológiát használ a külső összetevők létrehozására:
  • natív API használatával
  • COM technológia segítségével
Tekintettel a két fenti technológia közötti korlátozásokra, a különbség jelentéktelen, ezért megfontoljuk a VK fejlesztését a Native API használatával. A megvalósított fejlesztések szükség esetén alkalmazhatók a VC COM technológiával történő fejlesztésére, illetve kisebb módosításokkal az 1C: Enterprise rendszerben történő felhasználásra is, a fájl üzemmódtól eltérő működési lehetőségekkel.
VK szerkezet
Az 1C:Enterprise rendszer külső összetevője DLL-könyvtárként jelenik meg. A könyvtár kódja az IComponentBase származtatott osztályt írja le. A létrehozandó osztályban meg kell határozni a külső komponens funkcióinak megvalósításáért felelős metódusokat. A felülírt módszereket később, az anyag bemutatása során részletesebben ismertetjük.

A demo VK elindítása

Egy feladat:
  1. Szerelje össze az ITS-előfizetéshez mellékelt külső komponenst, amelyet úgy terveztek, hogy bemutassa a külső komponens mechanizmusának főbb képességeit az 1C-ben
  2. Csatlakoztassa a bemutató komponenst az 1C konfigurációhoz
  3. Győződjön meg arról, hogy a deklarált függvények megfelelően működnek
Összeállítás
A bemutató VC az ITS előfizetési lemezén található a "/VNCOMP82/example/NativeAPI" könyvtárban.
A demó VK összeállításához a Microsoft Visual Studio 2008-at fogjuk használni. A termék más verziói nem támogatják a használt Visual Studio projektformátumot.


Nyissa meg az AddInNative projektet. A projektbeállításokban összekapcsoljuk a könyvtárat a projekt felépítéséhez szükséges fejlécfájlokkal. Alapértelmezés szerint az ITS-lemezen találhatók a könyvtárban /VNCOMP82/include.
Az összeállítás eredménye egy fájl /bind/AddInNative.dll. Ez a lefordított könyvtár az 1C konfigurációhoz való csatlakozáshoz.
A VK csatlakoztatása az 1C konfigurációhoz
Hozzunk létre egy üres konfigurációt 1C.
A következő a felügyelt alkalmazásmodul kódja.
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...\bind\AddInNative.dll", "DemoVK", ExternalComponentType.Native); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); Vége eljárás
Ha az 1C konfiguráció indításakor nem jelentett hiba, akkor a VK sikeresen csatlakoztatva lett.
A fenti kód végrehajtása eredményeként egy objektum jelenik meg a konfiguráció globális láthatóságában DemoComp Olyan tulajdonságokkal és módszerekkel, amelyek a külső komponenskódban vannak definiálva.
A beágyazott funkciók bemutatása
Nézzük meg a demó VK teljesítményét. Ehhez próbáljunk meg beállítani és beolvasni néhány tulajdonságot, meghívni néhány VK metódust, valamint fogadni és feldolgozni egy VK üzenetet.
Az ITS lemezen található dokumentáció a demo VC következő funkcióit tartalmazza:
  1. Összetevő objektum állapotkezelés
    Mód: Bekapcsol, Kikapcsol
    Tulajdonságok: Beleértve
  2. Időzítő vezérlés
    Az összetevő minden másodpercben üzenetet küld az 1C: Enterprise rendszernek paraméterekkel Összetevő, időzítőés egy rendszeróra számláló karakterlánc.
    Mód: StartTimer, StopTimer
    Tulajdonságok: Van egy időzítő
  3. Módszer ShowInStatusLine, amely az állapotsorban megjeleníti a metódusnak paraméterként átadott szöveget
  4. Módszer Kép feltöltése. Betölt egy képet a megadott fájlból, és bináris adatként továbbítja az 1C:Enterprise rendszerbe.
Győződjön meg arról, hogy ezek a funkciók működnek. Ehhez a következő kódot hajtjuk végre:
var DemoComp; SystemStart() Procedure ConnectExternalComponent(...); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Disable(); Notify(DemoComp. Enabled); DemoComp.Enable(); Notify(DemoComp. Enabled); DemoComp.StartTimer(); EndProcedure ProcedureKülsőEseménykezelő(Forrás, Esemény, Adat) Jelentés(Forrás + " " + Esemény + " " + Adat); Vége eljárás
A konfiguráció futtatásának eredménye a képen látható


A metódushívások eredményei az „Üzenetek” panelen jelennek meg DemoComp.Disable()és Demo.Comp.Enable(). A következő sorok ugyanazon a panelen a VK-tól kapott üzenetek feldolgozásának eredményeit tartalmazzák - Forrás, Eseményés Adat illetőleg.

Tetszőleges külső összetevő neve

Feladat: Módosítsa a külső komponens nevét tetszőlegesre.
Az előző rész az azonosítót használta AddInNativeExtension, amelynek jelentését nem magyarázták el. Ebben az esetben AddInNativeExtension a kiterjesztés neve.
A VC kód meghatároz egy metódust RegisterExtensionAs, amely visszaadja a nevet az 1C: Enterprise rendszernek, amely szükséges a VC későbbi regisztrációjához a rendszerben. Ajánlatos olyan azonosítót megadni, amely bizonyos mértékig felfedi a külső komponens lényegét.
Itt található a módszer teljes kódja RegisterExtensionAs megváltoztatott kiterjesztéssel:
bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) ( wchar_t *wsExtension = L"SomeName"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* cél = 0; if (m-m_Memória_memória) ((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, wsExtension, iActualSize); return true; ) return false; )
A fenti példában a VK név a következőre módosult Valami Név. Ezután a VK csatlakoztatásakor új nevet kell megadnia:
DemoComp = New("AddIn.DemoVK.SomeName");

A VK ingatlanok listájának bővítése

Egy feladat:
  1. Tanulmányozza a VC tulajdonságok megvalósítását
  2. Adjon hozzá egy karakterlánc típusú olvasási-írási tulajdonságot
  3. Adjon hozzá egy olvasási/írási karakterlánc típusú tulajdonságot, amely tárolja a tulajdonság legutóbbi beállításának adattípusát. A tulajdonság értékének beállításakor semmilyen művelet nem történik

A létrehozandó komponens tulajdonságainak meghatározásához a fejlesztőnek a következő módszereket kell megvalósítania az AddInNative.cpp könyvtár kódjában:
GetNprops
A bővítmény tulajdonságainak számát adja vissza, ha nincsenek tulajdonságok, 0
FindProp
Annak a tulajdonságnak a sorszámát adja vissza, amelynek nevét a paraméterekben átadtuk
GetPropName
A tulajdonság nevét sorszámmal és az átadott nyelvazonosítóval adja vissza
GetPropVal
Az ingatlan értékét adja vissza a megadott sorszámmal
SetPropVal
A tulajdonság értékét a megadott sorszámmal állítja be
IsPropReadable
A tulajdonság olvashatósági jelzőjét adja vissza a megadott sorszámmal
IsPropWritable
A tulajdonság írhatósági jelzőjét adja vissza a megadott sorszámmal


Fontolja meg a fenti osztálymetódusok megvalósítását CAddInNative.
A demo VC 2 tulajdonságot határoz meg: Beleértveés Van egy időzítő (Engedélyezveés IsTimerPresent).
A könyvtárkód globális hatókörében két tömb van meghatározva:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent"); static wchar_t *g_PropNamesRu = (L"Engedélyezve", L"Van egy időzítő");
amelyek az ingatlanok orosz és angol nevét tárolják. A fejlécfájlban AddInNative.h egy felsorolás van meghatározva:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Mindig utolsó );
ePropIsEnabledés ePropIsTimerPresent 0 és 1 értékkel rendelkező tulajdonságok sorszámát értelmes azonosítókkal helyettesítik. Az ePropLast, amelynek értéke 2, a tulajdonságok számának lekérésére szolgál (a GetNProps módszerrel). Ezek a nevek csak az összetevő kódjában használatosak, kívülről nem érhetők el.
A FindProp és a GetPropName metódusok tömbökben keresnek g_PropNamesés g_PropNames.
A mezők értékének tárolására a könyvtármodulban a CAddInNative osztály rendelkezik olyan tulajdonságokkal, amelyek tárolják az összetevő tulajdonságainak értékét. Mód GetPropValés SetPropVal rendre visszaadja és beállítja ezeknek a tulajdonságoknak az értékét.
Mód IsPropReadableés IsPropWritableés vissza igaz vagy hamis, a tulajdonság átadott sorszámától függően az alkalmazási logika szerint.
Egyéni tulajdonság hozzáadása:

  1. Adja hozzá a tömbökhöz hozzáadandó tulajdonság nevét g_PropNamesés g_PropNames(fájl AddInNative.cpp)
  2. A felsoroláshoz kellékek(fájl AddInNative.h) előtt ePropLast adjon hozzá egy nevet, amely egyértelműen azonosítja a hozzáadandó tulajdonságot
  3. Memória rendszerezése a tulajdonságértékek tárolására (hozzon létre olyan komponens modulmezőket, amelyek tárolják a megfelelő értékeket)
  4. Módosítsa a módszereket GetPropValés SetPropVal az előző lépésben lefoglalt memóriával való interakcióhoz
  5. Az alkalmazási logikának megfelelően módosítsa a metódusokat IsPropReadableés IsPropWritable
Az 1., 2., 5. tétel nem szorul magyarázatra. E lépések végrehajtásának részletei a cikk mellékletében találhatók.
Nevezzük el a teszttulajdonságokat Tesztés Típusellenőrzés illetőleg. Ezután az (1) bekezdés eredményeképpen a következőket kapjuk:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"); static wchar_t *g_PropNamesRu = (L"Enabled", L"HasTimer", L"Test", L"CheckType");
Felsorolás kellékekígy fog kinézni:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Mindig utolsó );
A kód jelentős egyszerűsítése érdekében STL C++-t fogunk használni. Különösen a húrokkal való munkához WCHAR, csatlakoztassa a könyvtárat wstring.
Egy metódus értékének tárolása Teszt, határozza meg az osztályban CAddInNative hatálya alá tartozó privát mezőben:
string teszt1;
A karakterlánc-paraméterek 1C:Enterprise és egy külső összetevő közötti átviteléhez az 1C:Enterprise memóriakezelőt kell használni. Nézzük meg közelebbről a munkáját. A memória lefoglalásához és felszabadításához használja a funkciókat AllocMemoryés Szabad memória, a fájlban meghatározott Memóriakezelő.h. Ha egy karakterlánc paramétert kell átadni az 1C: Enterprise rendszernek, akkor a külső komponensnek memóriát kell lefoglalnia a függvény meghívásával. AllocMemory. A prototípusa így néz ki:
virtual bool ADDIN_API AllocMemory (void** pMemory, előjel nélküli hosszú ulCountByte) = 0;
ahol pMemória- annak a mutatónak a címe, amelybe a lefoglalt memória címe kerül,
ulCountByte- a lefoglalt memóriaterület mérete.
Példa a memória lefoglalására egy karakterlánchoz:
WCHAR_T *t1 = NULL, *teszt = L"TEST_STRING"; int iActualSize = wcslen(teszt1)+1; m_iMemory->AllocMemory((void**)&t1, iActualSize * sizeof(WCHAR_T)); ::convToShortWchar(&t1, teszt1, iActualSize);
A karakterlánc-adattípusokkal való munka kényelme érdekében leírjuk a függvényt wstring_to_p. Paraméterként egy wstring karakterláncot vesz igénybe. A függvény eredménye egy kitöltött szerkezet tVáltozat. Funkció kód:
bool CAddInNative::wstring_to_p(std::wstring str, tVariant* val) ( char* t1; TV_VT(val) = VTYPE_PWSTR; m_iMemory->AllocMemory((void**)&t1, (str.length()+1) * memcpy(t1, str.c_str(), (str.length()+1) * sizeof(WCHAR_T)); val -> pstrVal = t1; val -> strLen = str.length(); vissza igaz;)
Ezután a metódus switch utasításának megfelelő esetrésze GetPropVal a következő formában lesz:
eset ePropTest1: wstring_to_p(teszt1, pvarPropVal); szünet;
módszer SetPropVal:
case ePropTest1: if (TV_VT(varPropVal) != VTYPE_PWSTR) return false; teszt1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); szünet;
A második tulajdonság megvalósításához osztálymezőt definiálunk CaddInNative
uint8_t last_type;
amelyben az utoljára átadott érték típusát fogjuk tárolni. Ehhez adja hozzá a következő parancsot a CaddInNative::SetPropVal metódushoz:
utolsó_típus = TV_VT(varPropVal);
Most, amikor a második tulajdonság értékének leolvasását kéri, visszaadjuk az értéket utolsó_típus, amelyet a megadott feladat megkövetel.
Ellenőrizzük a végrehajtott változtatások teljesítményét.
Ehhez bemutatjuk megjelenés 1C konfiguráció a nézethez:
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.CheckType = 1; Report(String(DemoComp.TypeCheck)); DemoComp.Test = "Vasya"; Report(String(DemoComp.Test)); DemoComp.Test = "Petya"; Report(String(DemoComp.Test)); Report(String(DemoComp.TypeCheck)); Vége eljárás
Az indítás eredményeként üzenetsorozatot kapunk:
3
Vasya
Petya
22

A második és harmadik üzenet az előző lépésben beállított tulajdonság beolvasásának eredménye. Az első és a második üzenet az utolsó tulajdonságkészlet típuskódját tartalmazza. A 3 egy egész értéknek, a 22 - egy karakterlánc értéknek felel meg. A típusok és kódjaik egyezése a fájlban található típusok.h, amely az ITS lemezen található.

A módszerek listájának bővítése

Egy feladat:
  1. Bővítse ki a külső összetevő funkcionalitását a következő funkciókkal:
  2. Ismerje meg a külső összetevők módszereinek megvalósítását
  3. Módszer-függvény hozzáadása Funkció1, amely két karakterláncot ("Parameter1" és "Parameter2") vesz paraméterként. Ennek eredményeként az űrlap egy karakterlánca jelenik meg: „Check. Paraméter1, Paraméter2"
  4. Ellenőrizze, hogy a végrehajtott változtatások működnek-e.

A létrehozandó komponens metódusainak meghatározásához a fejlesztőnek a következő módszereket kell megvalósítania az AddInNative könyvtár kódjában:
GetNMethods, FindMethod, GetMethodName
Úgy tervezték, hogy megkapja a módszerek számát, keresse meg a módszer számát és nevét. Hasonló a tulajdonságokra vonatkozó megfelelő metódusokhoz
GetNParams
A metódusparaméterek számát adja vissza a megadott sorszámmal; ha nincs ezzel a számmal rendelkező metódus vagy nincsenek paraméterei, 0-t ad vissza
GetParamDefValue
A megadott metódus megadott paraméterének alapértelmezett értékét adja vissza
HasRetVal
Egy jelzőt ad vissza, amely a megadott visszatérési értékű ordinális metódussal rendelkezik: igaz a visszatérési értékű és metódusokhoz hamis másképp
CallAsProc
hamis, futásidejű hiba történik, és az 1C: Enterprise modul végrehajtása leáll. A paraméterek tömbjének memóriáját az 1C: Enterprise lefoglalja és felszabadítja.
CallAsFunc
Végrehajtja a metódust a megadott sorszámmal. Ha a metódus visszatér hamis, futásidejű hiba történik, és az 1C: Enterprise modul végrehajtása leáll. A paraméterek tömbjének memóriáját az 1C: Enterprise foglalja le. Ha a visszatérési érték string vagy bináris adat típusú, akkor az összetevő memóriát foglal le a függvényhez AllocMemory memóriakezelő, adatokat ír oda, és ezt a címet a struktúra megfelelő mezőjében tárolja. 1С: A vállalkozás felszabadítja ezt a memóriát hívással Szabad memória.
A módszerek teljes leírása, beleértve a paraméterek listáját, az ITS lemezen található dokumentációban található részletesen.
Fontolja meg a fent leírt módszerek végrehajtását.
A komponens kódjában két tömb van definiálva:
static wchar_t *g_MethodNames = (L"Engedélyezés", L"Letiltás", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"); static wchar_t *g_MethodNamesRu = (L"Engedélyezés", L"Letiltás", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage");
és enum:
enum Methods ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Mindig utolsó );
Funkciókban használatosak GetNMethods, FindMethodés GetMethodName, a tulajdonságok leírásához hasonlóan.
Mód GetNParams, GetParamDefValue, HasRetVal Az implementációs kapcsoló az átadott paraméterek és az alkalmazáslogika függvényében adja vissza a szükséges értéket. Módszer HasRetVal kódjában csak olyan módszerek listája található, amelyek eredményt adhatnak vissza. Számukra ez visszatér igaz. Minden acél módszernél visszatér hamis.
Mód CallAsProcés CallAsFunc közvetlenül futtatható metóduskódot tartalmaznak.
Olyan metódus hozzáadásához, amely csak függvényként hívható meg, a következő módosításokat kell végrehajtania a külső összetevő forráskódjában:
  1. Adja hozzá a metódus nevét a tömbökhöz g_MethodNamesés g_MethodNames(fájl AddInNative.cpp)
  2. Adjon hozzá egy értelmes metódusazonosítót a Methods névsorhoz (fájl AddInNative.h)
  3. Módosítsa a funkciókódot GetNParams programlogika szerint
  4. Ha szükséges, módosítsa a metódus kódját GetParamDefValue ha a metódus paramétereinek alapértelmezett értékeit szeretné használni.
  5. Változtassa meg a függvényt HasRetVal
  6. Módosítsa a függvények logikáját CallAsProc vagy CallAsFunc, a metódus közvetlenül végrehajtható kódjának odahelyezésével
Hozzunk tömböket g_MethodNamesés g_MethodNames, valamint a felsorolás mód a kilátáshoz:
static wchar_t *g_MethodNames = (L"Engedélyezés", L"Letiltás", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Teszt"); static wchar_t *g_MethodNamesRu = (L"Engedélyezés", L"Letiltás", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage", L"Teszt");

Enum Methods ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Mindig utolsó );
Szerkesszük a függvényt GetNpropsígy a "Teszt" metódus paramétereinek számát adja vissza:
long CAddInNative::GetNParams(const long lMethodNum) ( switch(lMethodNum) ( case eMethShowInStatusLine: return 1; case eMethLoadPicture: return 1; case eMethTest: return 2; alapértelmezett: return 0; ) return 0; )
Változtassunk a függvényen:
bool caddinnative :: getParamdefValue (const long lmethodnum, const long lparamnum, tvarianT *pvarparamdefvalue) (tv_vt (pvarparamdefValue) = vtype_impty; Switch (lmethodnum) (esetek megemlíthető esetek: Case emeThhow: Case emeThhow: Case emethop: Case emeThhop: Case emethhop: Case emeThop: Case emethhop: Case emethop: Case emethop: Esethop: Case EMETHOP: Case EMETHOP. : case / Alapértelmezés szerint nincsenek paraméterértékek; alapértelmezett: return false; ) return false; )
A hozzáadott vonalnak köszönhetően
eset eMethTest:
egy vagy több argumentum hiányában a megfelelő paraméterek értéke üres ( VTYPE_EMPTY). Ha egy paraméterhez alapértelmezett értékre van szüksége, akkor azt meg kell adnia a szakaszban eMethTest funkciókapcsoló utasítás CAddInNative::GetParamDefValue.
Mivel a "Teszt" módszer visszaadhat egy értéket, módosítania kell a függvénykódot HasRetVal:
bool CAddInNative::HasRetVal(const long lMethodNum) ( switch(lMethodNum) ( case eMethLoadPicture: case eMethTest: return true; alapértelmezett: return false; ) return false; )
És add hozzá a metódus végrehajtható kódját a függvényhez CallAsFunc:
bool CAddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) ( ... std::wstring s1, s2; switch(lMethodNum) ( case eMethLoadT eset: eMethLoadP; if (!lSizeArray || !paParams) false értéket ad vissza; s1 = (paParams) -> pwstrVal; s2 = (paParams+1) -> pwstrVal; wstring_to_p(std::wstring(s1+s2), pvarRetValue); ret = igaz ; break; ) return ret;)
Fordítsuk le a komponenst, és vigyük be a konfigurációs kódot az űrlapba:
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = New("AddIn.DemoVK.SomeName"); sáv = DemoComp.Test("Szia, ", "Világ!"); Értesít(transz); Vége eljárás
A konfiguráció elindítása után egy üzenetet kapunk: „Hello, World!”, amely azt jelzi, hogy a módszer sikeresen működött.

Időzítő

Egy feladat:
  1. Tanulmányozza az időzítő megvalósítását a demo VK-ban
  2. Módosítsa a "StartTimer" metódust úgy, hogy hozzáadja a paraméterekhez az időzítő intervallumának (ezredmásodpercben) átadásának lehetőségét.
  3. Ellenőrizze, hogy a végrehajtott változtatások működnek-e.

A WinAPI-ban az idővel való munkavégzés érdekében használhatja az üzenetet WM_TIMER. Ez az üzenet az időzítő létrehozásakor megadott időintervallumban kerül elküldésre a programnak.
Időzítő létrehozásához használja a funkciót SetTimer:
UINT SetTimer(HWND hWnd, // ablak fogantyúja UINT nIDevent, // időzítő azonosítója (szám) UINT nElapse, // késleltetés TIMERPROC lpTimerFunc); // függvénymutató
Az operációs rendszer üzenetet küld WM_TIMER az argumentumban megadott intervallumú programhoz nEltelt(ezredmásodpercben). Az utolsó paraméterben megadhat egy funkciót, amely az időzítő minden egyes indításakor végrehajtódik. A függvény fejlécének így kell kinéznie (a név bármi lehet):
void __stdcall TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Fontolja meg az időzítő megvalósítását a demo VK-ban.
Mivel a Windows operációs rendszer családhoz külső komponens kifejlesztésén gondolkodunk, nem vesszük figyelembe az időzítő megvalósítását más rendszerekben. operációs rendszer. Különösen GNU/Linux OS esetén a megvalósítás különbözik a függvény szintaxisában SetTimerés TimerProc.
A metódus meghívása a végrehajtható kódban történik SetTimer, amelyre a függvényt továbbítják MyTimerProc:
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
A létrehozott időzítő azonosítója egy változóba kerül m_uiTimer hogy később kikapcsolhassa.
Funkció MyTimerProc alábbiak szerint:
VOID CALLBACK MyTimerProc(HWND hwnd, // az időzítő üzenetek ablakának fogantyúja UINT uMsg, // WM_TIMER üzenet UINT idEvent, // időzítő azonosító DWORD dwTime // aktuális rendszeridő) ( if (!pAsyncEvent) return; wchar_t "ComponentNative", *what = L"Timer"; wchar_t *wstime = new wchar_t; if (wstime) ( wmemset(wstime, 0, TIME_LEN); ::_ultow(dwTime, wstime, 10); pAsyncEvent->ExternalEvent(who , what, wstime); wstime törlése; ) )
A függvény lényege, hogy a metódus hívásra kerül Külső esemény, amely üzenetet küld az 1C: Enterprise rendszernek.
A módszer funkcionalitásának bővítése StartTimer tegyük a következőket:
A módszer kódjának módosítása GetNParams hogy a módszerhez való eMethStartTimer visszaadott értéke 1:
case eMethStartTimer: return 1;
Itt van a módszer kódja CallAsProc a kilátáshoz:
case eMethStartTimer: if (!lSizeArray || TV_VT(paParams) != VTYPE_I4 || TV_I4(paParams)<= 0) return false; pAsyncEvent = m_iConnect; #ifndef __linux__ m_uiTimer = ::SetTimer(NULL,0,TV_I4(paParams),(TIMERPROC)MyTimerProc); #else // код для GNU/Linux #endif break;
Most nézzük meg a funkcionalitást. Ehhez a konfiguráció felügyelt alkalmazásának moduljába írjuk a kódot:
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.StartTimer(2000); Vége eljárás
A konfiguráció elindítása után a program 2 másodperces időközönként üzeneteket kap, amelyek jelzik az időzítő helyes működését.

Interakció az 1C: Enterprise rendszerrel

A külső összetevő és az 1C:Enterprise rendszer közötti interakcióhoz a fájlban leírt IAddInDefBase osztály metódusai AddInDefBase.h. Felsoroljuk a leggyakrabban használtakat:
Hibaüzenet generálása
virtual bool ADDIN_API AddError (aláíratlan rövid wcode, const WCHAR_T* forrás, const WCHAR_T* leírás, hosszú kód)
wcode, kód- hibakódok (a hibakódok listája leírással az ITS lemezen található)
forrás- hibaforrás
descr- hiba leírása
Üzenet küldése az 1C: Enterprise rendszernek
virtual bool ADDIN_API ExternalEvent(WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;
wszForrás- üzenet forrása
wszÜzenet- Üzenet szövege
wszData- továbbított adatok
Az üzenet elfogása a HandlingExternalEvent eljárással történik
Külső komponens regisztrációja az 1C:Enterprise rendszerben
virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszProfileName- alkatrész neve.
Ezek a módszerek elegendőek a VK és az 1C teljes kölcsönhatásához. Ahhoz, hogy egy külső komponens adatokat fogadjon az 1C:Enterprise rendszerből és fordítva, a külső komponens speciális üzenetet küld, amelyet viszont az 1C rendszer elfog, és szükség esetén meghívja a külső komponens metódusait a küldésre. visszamenőleges adatok.

tVáltozatos adattípus

Egy külső komponens és az 1C:Enterprise rendszer közötti adatcsere során a tVariant adattípust használjuk. Ennek leírása a type.h fájlban található, amely az ITS lemezen található:
struct _tvariant (_Anonymous_union Union (int8_t i8val; int16_t Shortval; int32_t lVal; int valVal; alá nem jelölt int uintval; int64_t llVal; uint8_t ui8val; uint16_t ushortVal; uint32_t ulval; uint64_t ullVval; intvval; bVal; char chVal; wchar_t wchVal; DÁTUM /byte-ok száma ) __VARIANT_NAME_3/*str*/; _ANONYMOUS_STRUCT struct ( WCHAR_T* pwstrVal; uint32_t wstrLen; //szimbólum száma ) __VARIANT_NAME_4/*wstr*/; ) __VARIANT_NAME_E egy tömbhöz /b-tenziónév3_1s; in pvarVal TYPEVAR vt; );
Típusú tVáltozat egy olyan szerkezet, amely a következőket tartalmazza:
  • közvetlenül adattárolásra szánt keverék (unió).
  • adattípus azonosító
Általában a típusú változókkal való munkavégzés tVáltozat a következő algoritmus szerint történik:
  1. A változóban pillanatnyilag tárolt adatok típusának meghatározása
  2. Hozzáférés a keverék megfelelő mezőjéhez, az adatokhoz való közvetlen hozzáférés érdekében
Típushasználat tVáltozat nagyban leegyszerűsíti az 1C: Enterprise rendszer és egy külső komponens interakcióját

Alkalmazás

Az "examples" könyvtár példákat tartalmaz a cikkhez
examples/1 - futtassa a bemutató komponenst
examples/2 - tulajdonságlista-kiterjesztés bemutató
példák/3 - a metóduslista kiterjesztésének bemutatása
Minden könyvtár tartalmaz egy VS 2008 projektet és egy előre elkészített 1C konfigurációt.

A programozóknak gyakran problémái vannak a külső komponensek (például kereskedelmi berendezés-illesztőprogramok) csatlakoztatásával, amikor a felhasználók úgy dolgoznak az 1C-vel, hogy a terminálon keresztül csatlakoznak a szerverhez.

Ugyanakkor a felhasználók látják például a cikk közleményében bemutatott képet.

Ha helyi számítógépről dolgozik, akkor nincs probléma a külső összetevők csatlakoztatásával.

Mihez kapcsolódik? Ennek az az oka, hogy amikor a felhasználók a terminálkiszolgálón keresztül dolgoznak, kevesebb joguk van, mint amikor a helyi számítógépen dolgoznak.

Ez könnyen ellenőrizhető, ha rendszergazdai jogokkal rendelkező fiókkal jelentkezik be a terminálkiszolgálóra.

Ennek az eltérésnek az az oka, hogy az 1C nem tud külső komponenst regisztrálni a registry-ben, amikor a felhasználó normál jogokkal dolgozik a terminálban, mert egy normál felhasználónak nincs írási jogosultsága a rendszerleíró adatbázishoz HKEY_CLASSES_ROOT.

A terminál külső komponenseinek csatlakoztatásával foglalkozó publikációkban számos módszert kínálnak ennek a problémának a megoldására.

Például ezek:

1. Futtassa először az 1C-t rendszergazdai jogokkal.

Ez a lehetőség nem mindig működik. Az alábbiakban elmagyarázom, miért.

2. Adja meg a terminál közönséges felhasználóinak a rendszerleíró adatbázisba való írási jogot HKEY_CLASSES_ROOT.

Nem kellően "haladó" felhasználók ezt nem tehetik meg, különben problémák adódhatnak.

3. Különféle "kütyük" segítségével regisztrálja a VK-t egy teljes jogú felhasználó nevében.

Enni sem jó.

Tehát mi a legjobb módja annak, hogy kilábaljunk ebből a helyzetből?

Megoldásomat ajánlom erre a problémára. Véleményem szerint - egyszerű és szép, korábban nem kínálták az infostarton.

Ennek a problémának a vizsgálata során azon tűnődtem, hogy az 1C miért próbálja meg regisztrálni a VK-t egy új úton? Hiszen már regisztrálva van a rendszerben.

A dolog úgy alakult, hogy a tipikus 1C konfigurációkban (például "Trade Management") a globális kontextus metódusának következő szintaxisát használják ConnectExternalComponent() :

ConnectExternalComponent("Reference.ConnectedEquipment.Layout.DriverATOLBarcodeScanner", "ATOLScanner");

Amint láthatja, a VK illesztőprogram a "Connected Equipment" könyvtár "DriverATOLScannerBarcode" elrendezéséből csatlakozik.

Akkor mi történik?

Az 1C a komponenst a felhasználó ideiglenes mappájába menti, például "C:\Documents and Settings\User\Local Settings\Temp\1032\v8_4_12.tmp"

és megpróbálja regisztrálni a HKEY_CLASSES_ROOT rendszerleíró ágban ezen az útvonalon.

A terminálon a közönséges felhasználóknak nincs joguk megváltoztatni ezt a rendszerleíró ágat, így az összetevő nincs csatlakoztatva számukra.

Most arról, hogyan lehet kilábalni ebből a helyzetből.

Globális kontextus módszer A ConnectExternalComponent() számos szintaktikai beállítással rendelkezik. Ezt fogjuk használni.

Tehát lépésről lépésre:

1. Regisztrálja a külső összetevőt a regsvr32.exe segédprogrammal a terminálkiszolgálón a C:\WINDOWS\SYSTEM32 mappában 32 bites operációs rendszer esetén vagy a mappában. C:\WINDOWS\SYSWOW64 64 bites operációs rendszerhez.

2. Használja a két további szintaktikai beállítás egyikét a ConnectExternalComponent() metódushoz:

1.opció:

ConnectExternalComponent("C:\WINDOWS\SysWOW64\Scaner1C.dll", "ATOLScanner", ExternalComponentType.COM);

DriverObject = New("AddIn.ATOLScanner.Scanner45");

2. lehetőség:

ProgID = "AddIn.Scanner45";

Csatlakoztassa a külső komponenst (ProgID);

DriverObject = Új(ProgID);

Véleményem szerint a 2. lehetőség előnyösebb.

Ugyanakkor az 1C nem próbálja meg újra regisztrálni a VC-t egy új útvonalon a rendszerleíró adatbázisban, és így minden probléma megoldódik.

Nos, ez minden. Sok sikert a munkához!

Például nem lehet átírni egy összetevőt, ha nem Ön a szerzője, és egyszerűen nincsenek forráskódok. Vagy ha a Native API technológia által támogatott legegyszerűbb típusok (szám, karakterlánc, logikai érték, dátum) nem elegendőek a működéséhez.

A fájlbázissal való munka során nincs különösebb probléma. Az ütemezett feladatot egy normál felhasználó háttérfolyamatában hívják meg. Ezért az ügyfélhívások elérhetők számára. Egy ütemezett feladat indításakor nincs ügyfélkörnyezet a szerver adatbázisban, ezért a hívás ConnectExternalComponent() nem elérhető.

Ebben az esetben meghívhatja az összetevőt az ügyfélen. Ehhez elegendő egy másik 1C munkamenetet elindítani az ütemezett feladatból a kiszolgálón, amelyben végrehajtja a szükséges műveleteket az ügyfélen. Nos, ne felejtsd el később befejezni a futómenetet.

Tegyük fel, hogy ütemezett feladatunk során létrehozunk és mentünk egy jelentést, amely a NameDeclension.dll külső COM-összetevőt használja a teljes név elutasításához. A fájlbázison egy ilyen ütemezett feladat megfelelően működik, de a kiszolgálókomponensen nem.

A probléma megoldása érdekében adjunk hozzá egy eljárást az ütemezett feladat modulhoz, amely újabb munkamenetet indít kiszolgáló módban, és ebben jelentésgeneráló hívást hajt végre a kliensen külső feldolgozásból.

#If Client Then Procedure ExecuteFormationAndSavingReport() Exportálás If ConnectExternalComponent("CommonLayout.NAMEDECL","Cl",ExternalComponentType.COM) Then Component = New ("AddIn.Cl.NameDeclension"); //Itt található a jelentés létrehozásának és mentésének kódja: ElseJoinLogRecord("RegTask", LogLogLevel.Error, "Nem sikerült a külső komponens csatlakoztatása a kliensen"); EndIf; Az eljárás vége #Egyébként Eljárás ExecuteFormationAndSavingReport() ExecuteOperationOnClient("RegularTasks.ExecuteFormationAndSavingReport()"); EndProcedure eljárás PerformOperationOnClient(ParameterToExecute) ExportUserName = ""; UserPassword = ""; PathToExternalProcessing = "c:/temp/Autostart.epf"; Idézet = """"; DirectoryBIN = DirectoryProgram(); PathToConfiguration = InfoBase ConnectionString(); ConfigurationPath = StrReplace(ConfigurationPath, Quote, Quote + Quote); StartString = Idézet + Bin könyvtár + "1cv8.exe" + Idézet + " VÁLLALAT" + " /IBConnectionString " + Idézet + Konfigurációs útvonal + Idézet + " /N " + Idézet + Felhasználónév + Idézet + " /P " + Idézet + Felhasználói jelszó + Quote + " /Execute " + Quote + PathToExternalProcessing + Quote + " /C " + Quote + ParameterToExecute + Quote; StartApplication(StartString); Befejezési eljárás #EndIf

Külső feldolgozási kód, amely egyszerűen arra készteti az ügyfélkörnyezetet, hogy kinyomtassa a szükséges jelentést az ütemezett feladatok modulból, és a jelentés létrehozása után befejezi a munkamenetet.

Kísérlet a végrehajtásra(StartupParameter); Kivétel EndTry; ShutdownSystem(False);

A megoldás kényelme, hogy az ütemezett feladatok beállításakor nem mindegy, hogy milyen módban indul el a feladat. Ha az adatbázis fájl, akkor a szükséges eljárás azonnal elindul. Ha az adatbázis kiszolgálóoldali, és az indításkor nincs ügyfélkörnyezet, akkor egy új munkamenet inicializálódik, és az eljárás megfelelően fog működni az ügyfél környezetében.

Egy tipikus alkalmazás kódja. Elméletileg teljesen hasonló módon fog működni egy menedzseltben is.

p.s. Ezenkívül ez a megközelítés használható bármely ügyféleljárás végrehajtására ütemezett jobokban.

A CSENGŐ

Vannak, akik előtted olvassák ezt a hírt.
Iratkozzon fel a legújabb cikkekért.
Email
Név
Vezetéknév
Hogy szeretnéd olvasni a Harangszót
Nincs spam