KOMBANA

Ka nga ata që e lexojnë këtë lajm para jush.
Regjistrohu për të marrë artikujt më të fundit.
Email
Emri
Mbiemri
Si do të dëshironit të lexoni Këmbanën
Nuk ka spam

Pyetje: Komponenti i jashtëm Native Api në C++ për Linux (Ubuntu x64) në 1С 8.3


Unë po shkruaj VK, nuk mund të lidhem me 1s në ubuntu. Edhe shembulli nga 1s nuk është i lidhur. Pra, një pyetje në lidhje me të:

1) Po përpiqem të lidh VK nga shembulli VNCOMPS i dhënë në artikull

(Lidhja mund të gjendet në fund: "Kopjimi").
Brenda, projekti NativeApi ka një skedar. Me të, unë ndërtoj bibliotekën .so në Ununtu.
Por te "Lidhni komponentin e jashtëm" 1 ngrihet.
Në mënyrë të ngjashme, nëse ndërtoj duke përdorur "build.sh" (në rrënjë të projektit).

Në vetë makefile, unë e ndërroj flamurin nga m32 në m64, sepse 1c dhe vetë sistemi x64. (me parametrin m32 nuk e kap gjithsesi)
Këtu është një shembull i thirrjes së VK nga 1C 8.3:
Lidhja e kryer = Lidhni një komponent të jashtëm("/home/alexeyubuntux64-20 gb/Documents/VNCOMP83/shembull/NativeAPI/AddInNative.so", "AddInNative", ExternalComponentType.Native); Ekziston një artikull vetëm për këtë temë.
Por, me sa mund të shoh, të gjitha këto pika tashmë janë marrë parasysh dhe korrigjuar në shembullin VNCOMPS.

Por në fakt biznesi në parametrat e përpilimit. Komponenti i jashtëm MB 32 bit lidh normalisht deri në 32 bit 1c, por unë vendosa në Ubuntu x64 1c enterprise83 8.3.5-1486 amd64. Dhe unë dua të marr VK tek ajo.

A ka dikush ndonjë ide se si të zgjidhet kjo çështje?
Shembulli VNCOMPS duhet të funksionojë, por parametrat e ndërtimit duhet të korrigjohen, ose vetë platforma në të cilën po testoj është e pasaktë.

Përgjigje:Është interesante, a është e mundur të shkruhet një komponent i jashtëm në Java?

Pyetje: Komponenti i jashtëm (Native) nuk është i lidhur


Përpiluar një shembull me ITS, për sistemet 64 dhe 32 bit.

Unë lidhem kështu:
ConnectionResult = ConnectExternalComponent(CDLLPath, "Comp", ExternalComponentType.Native); Një kompjuter lidhet, tjetri jo. Ka një ndryshim në OS. Aty ku shkon lidhja, ka Win7, ku nuk ka Win10. Në të njëjtën kohë, komponentët standardë punojnë në një kompjuter ku komponenti im nuk funksionon.

Testuar në platforma të ndryshme (8.3.4.482, 8.3.6.2100, 8.3.11.2700, 8.3.12.1412).

Si të kuptoni pse nuk lidhet?

Përgjigje: vc_redist nuk harroi?

Pyetja: 1C8 dhe një komponent i jashtëm me tipin Native


Mirembrema.
Ekziston një konfigurim i BP 3.0.50.12 dhe një dëshirë për të zbatuar peshimin nga kompania Scales-Soft duke përdorur UniServerAuto.
Zhvilluesit përpiluan komponentin Native për Windows 32 dhe 64 dhe e vendosën në një arkiv me skedarin kryesor. Ekziston edhe një shembull për 1C, se si mund të llogaritet pesha. Në të, me ndihmën e një paraqitjeje me të dhëna binare, tregohet ky arkiv, siç e kuptoj unë. Në shembull, gjithçka është në rregull: komponenti është instaluar, lidhur, më pas vendoset lidhja dhe lexohet pesha.
Por sapo filloni të transferoheni në 1C, pesha nuk lexohet. Duket se gjithçka është shkruar thjesht, por nuk e kuptoj se ku është grabujë.
Kush do të ketë pak kohë - ndihmë, shiko me një sy, ndoshta zgjidhja është në sipërfaqe, por unë jam duke ecur diku në vendin e gabuar dhe po bëj diçka të gabuar. Unë kurrë nuk kam punuar me teknologjinë vendase më parë ...

Dhe në bashkëngjitje është teksti im përpunues

Përgjigje:

Epo, kam disa lajme ...
Sapo fillova të shikoja hap pas hapi në cilën pikë fillon të dështojë. Për ta bërë këtë, kam krijuar një bazë të dhënash të zbrazët dhe përpunim me komandën. Për analogji me shembullin e furnizuesit, unë e transferova paraqitjen në një konfiskim të ri - funksionon herën e dytë. Ato. Herën e parë jo, herën e dytë po. Kjo nxiti idenë se do të ishte ende e nevojshme që në përpunimin e tij të ndahej lidhja e komponentit dhe objektit sipas procedurave të ndryshme.
Pastaj e transferova atë në bazën time të të dhënave me një lidhje faqosjeje - funksionon. Fuh, tashmë është mirë .... Por do të doja pa bërë ndryshime në konfigurim, kështu që le të vazhdojmë

Po përpiqem të shtoj një plan urbanistik në përpunim. Madhësia e saj rritet menjëherë nga 10kb në 3mb dhe vërehet një ngadalësim i ndjeshëm - nuk përshtatet. Filloj të gërmoj drejt lidhjes së një komponenti përmes dll. Ato. në thelb njësoj si ku keni filluar. Por ka një "POR": duke kërkuar me emrin e dll në dosjen e përdoruesit, vura re se kjo dll qëndron aty ku (siç e kuptoj unë) shtohen dll-të e regjistruara në 1C:
C:\Users\USER\AppData\Roaming\1C\1cv8\ExtCompT
në përputhje me rrethanat, nuk ka nevojë të përdorni rrugën e plotë për dll, thjesht mund të shkruani emrin e saj:
ConnectExternalComponent("Add1CUniServerAuto32.dll", "UniServerAuto", ExternalComponentType.Native);

Unë përpiqem ... betohet në regjistrim, por kthen rezultatin e peshimit. Rezulton se dll është regjistruar tashmë, që do të thotë se thjesht duhet ta lidhni atë. E heq dhe gjithçka funksionon.
Unë përmbledh:
1. Në përpunimin e peshimit në procedurën Kur hapem shtova lidhjen e një komponenti të jashtëm dhe lidhjen me objektin.
2. Rrugën për në dll nuk e kam shkruar, thjesht kam treguar emrin e saj.

Tani ulem dhe mendoj, kur u instalua dll në 1C? Në momentin e instalimit të softuerit? Vështirë... Në momentin e ekzekutimit të konfigurimit të zhvilluesit të kësaj dll, ku vendoset kur hapet formulari? Nuk e di, por më duket afër... Si mendoni?
Dhe së dyti, në një vend të ri, kur ka nevojë për të instaluar të njëjtin terminal, çfarë duhet bërë për të funksionuar gjithçka? Instaloni plotësisht softuerin, ekzekutoni konfigurimin e furnizuesit për të kontrolluar punën dhe më pas (teorikisht) përpunimi im duhet të funksionojë? Diçka pak e komplikuar... Apo pas instalimit të softuerit në përpunimin tim, bëj InstallExternalComponent një herë?

Do të doja të dëgjoja mendimet tuaja për këtë ...

Pyetje: Komponenti i jashtëm.dll


dite te mire te gjitheve.
Një pyetje.
dll komponent që funksionon mirë në 1C 7.7
në 1s 8.1 nuk dëshiron të niset fare ...
Provova dhe ngjite në C:\Program Files\1cv81\bin\cache1c.dll
U përpoqa të regjistrohesha duke përdorur regsvr32 "C:\Program Files\1cv81\bin\cache1c.dll"
Regjistruar pa probleme.
Kur përpiqem të hyj në të, më del një mesazh gabimi:

Gabim gjatë ngarkimit të komponentit të jashtëm! cache1c.dll
Procedura Ekzekutimi ButoniKlikoni(Button) Përpjekje për të ngarkuar komponentin e jashtëm( "C:\Program Files\1cv81\bin\cache1c.dll"); Raporti i përjashtimit ( "Gabim gjatë ngarkimit të komponentit të jashtëm!"+ "cache1c.dll"); Fundi i Përpjekjes; Përpjekje // Merr objektin e komponentit. // m = E re ("cache1c.GTMcmd"); m = New COMObject("cache1c.GTMcmd" ); Raporti i përjashtimit(); Fundi i Përpjekjes; Përfundimi i procedurës

Përgjigje: Banale deri në pamundësi...
Është e nevojshme të mbahen pauza ndërmjet thirrjeve (milisekonda)...
Procedura ButtonExecuteClick(Button) Përpjekje // Merrni objektin e komponentit. m = New COMObject("cache1c.GTMcmd" ); Raporti i përjashtimit ( "Nuk mund të krijohej objekti i komponentit të jashtëm"); Fundi i Përpjekjes; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Connect(); m.Pauzë(100); ...... etj
Për 1s 7.7 - kjo nuk është e nevojshme, rezulton se qarkullimi është më i shpejtë.

Pyetje: Puna e një komponenti të jashtëm me serverin 1C ...


Mirembrema,

Ekziston një komponent i jashtëm i shkruar në C ++, detyra e të cilit është të marrë informacion nga një bazë të dhënash e jashtme dhe të kthejë rezultatin e pyetjes në formën e një Tabele të Vlerave në 1C.
Për të formuar një tabelë vlerash në momentin aktual, përdoret ndërfaqja IDispatch* pBackConnection, e cila merret si parametër në funksionin Init(). Më tej, unë thjesht, duke përdorur funksionet 1C, formoj një tabelë vlerash, e plotësoj dhe e kthej në parametrin e dytë në CallAsFunc (...).
Problemet filluan me kalimin në klientët e hollë 1C. Nga ana e serverit, komponenti i jashtëm nuk fillon vërtet. Mund ta ekzekutoni në anën e klientit, por gjithçka duket si paterica dhe bie jashtë logjikës së përgjithshme "klient-server" në 1C. Për shembull, klienti nuk e kupton se çfarë është tabela e vlerave, problemet me variablat "globale", seancat, etj.
NativeAPI është edhe më i cunguar në këtë drejtim.
Vallëzimi me një dajre çoi në faktin se unë isha në gjendje të nisja një komponent të jashtëm nën serverin 1C, POR puna ndodh derisa të bëhet një përpjekje për të thirrur Invoke në pBackConnection. Versioni 64-bit i serverit 8.2 përpiqet të bëjë diçka derisa të bjerë në një afat kohor, versioni 32-bit (VK është natyrisht edhe 32-bit) thjesht bie menjëherë.
Unë supozoj se serveri 1C nuk e shërben këtë mënyrë funksionimi.
Prandaj, lindin pyetje, a është e përkohshme apo logjika e 1C reduktohet në heqjen e kësaj skeme pune? Nëse është e pamundur të krijohen struktura të brendshme të 1C (tabela e vlerave) në këtë mënyrë, a ekziston, në parim, një përshkrim se çfarë është një tabelë vlerash në nivelin e sistemit në mënyrë që të përpiqeni ta krijoni atë në C + +, plotësoni atë dhe pastaj thjesht rrëshqitni 1C si një parametër kthimi? Do të doja të paktën të gjeja një drejtim në cilin drejtim të gërmoj.

Faleminderit.

Përgjigje:

Ju shkruani një gjë dhe mendoni një tjetër.
Në mjedisin 1C, deklarimi i variablave që do të jenë të dukshëm në sesione të ndryshme nuk është i pamundur tani dhe nuk ishte e mundur më parë. Një seancë e ndryshme është një proces fizikisht i ndryshëm.
Sesioni është një sesion i lidhjes së bazës së të dhënave, d.m.th. sesioni i përdoruesit. Apo vendosni diçka tuajën dhe këtë koncept?

Brenda një sesioni ishte e mundur, dhe tani është e mundur, të deklarohen variabla në modulin e sesionit, të cilat do të jetojnë dhe do të jenë të dukshme brenda seancës nga vende të ndryshme ... në fakt, janë 4 të tilla.
- Moduli i sesionit;
- Moduli i rregullt i aplikimit;
- Moduli i aplikacionit të menaxhuar;
- Moduli i lidhjes së jashtme.

Dhe sigurisht, duhet të mbani mend për kontekstin. Konteksti i serverit nuk është drejtpërdrejt i aksesueshëm nga ana e klientit dhe anasjelltas.

Në përgjithësi, arkitektura 1C siguron që shkëmbimi i të dhënave do të vazhdojë:
- me anë të parametrave/kthimeve të procedurave/funksioneve;
- me anë të të ashtuquajturave parametra të sesionit (ato nuk mund të jenë objekte, ju mund ta shihni atë në paleta).

Tabela në formular... dhe lidhet me ndonjë tabelë objekti (përpunime p.sh.)? ose jo. Nëse po, atëherë është gjithashtu i disponueshëm në server (&AtServer) dhe modifikojeni atje....

Dhe po, ValueTable nuk është i disponueshëm në UV në anën e klientit. Epo, 1C vendosi kështu.

Eja! Këtu funksionon me Excel, funksionon me FSO dhe një mori gjithçka tjetër, por këtu nuk funksionon. Kape gabimin dhe analizo....

Përpjekje
...
veprimet tuaja
...
Përjashtim
str = Përshkrimi Gabim();
Fundi i Përpjekjes;

Me aftësi moderne harduerike, ky nuk është aspak një argument.

Thjesht mendimi juaj personal. Nuk ka lidhje me realitetin. Jo në asnjë mënyrë. E përsëris edhe një herë, 1C funksionon shkëlqyeshëm me COM. Të dyja me in-proc dhe jashtë-proc.

Jepni kodin që ngarkoni dhe aplikoni në VK.

Meqë ra fjala, VK... në rastin tuaj, është COM apo Native API?
Nëse COM, atëherë ju e regjistroni atë si ... përmes regsvr32 ... atëherë si e "zgjidhni" çështjen e thellësisë së bitit?

Pyetje: Instalimi i një komponenti të jashtëm


Ju lutem më tregoni se si të instaloj një komponent të jashtëm. Gjatë ekzekutimit të kodit të mëposhtëm, hidhet një gabim. Gjeni NameDecl.dll në paraqitjen

Përpjekje për SetExternalComponent ("GeneralLayout.Layout"); Përjashtim FundTry ;
Gabim: instalimi i shtojcës dështoi!

Përgjigje: ()
ConnectExternalComponent("GeneralLayout.Layout", "NameDecl", ExternalComponentType.Native) kthen FALSE,
E re("AddIn.NameDecl.CNameDecl", E Padefinuar) = (()): Lloji nuk është përcaktuar (AddIn.NameDecl.NameDecl)

Pyetje: Native dll nuk është e lidhur me 1s 8.1 (fptrwin32_fz54_9_11_0_5549.dll)


Përshëndetje.
1C përditësoi dll-në për arkat online atolin për fdd 1.05 (përfshirë në përpunimin e mirëmbajtjes fptrwin32_fz54_9_11_0_5549.dll).
Unë kam një 1C 8.1 të vjetër. Për dallim nga 8.2, ai nuk mbështet punën me pajisje të jashtme në të njëjtën mënyrë si 8.2, kështu që së pari duhet të regjistroni dll në Windows, dhe pastaj ta lidhni atë vetëm me 1C?

ProgID = "AddIn.IntegrationComponent.ATOL_KKT_1C83_V9"; LoadExternalComponent("C:\fptrwin32_fz54_9_11_0_5549.dll"); ConnectExternalComponent (ProgID); Driver = I ri (ProgID);

Megjithatë, përpunimi i vjetër u shkrua në "teknologji" com, dhe ai i ri amtare. Prandaj, gjatë regjistrimit, regsvr32 jep një gabim:
Moduli u ngarkua, por pika hyrëse e DllRegisterServer nuk u gjet. Dhe sugjeron të kontrolloni nëse ky skedar është skedari i saktë dll ose OCX.
Kush u përball me një situatë të ngjashme, si dolët? Unë e kuptoj që një problem i ngjashëm do të jetë në 7.7.
Kodi 8.2:

Layout = GetLayout("IntegrationComponent"); Adresa = PlaceInTempStorage(Layout); ConnectExternalComponent(Adresa, "IntegrationComponent", ExternalComponentType.Native); Driver = I ri ("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9");

1C 8.2:
Lidhni komponentin e jashtëm (<Местоположение>, <Имя>, <Тип>)
1C 8.1:
Lidhni komponentin e jashtëm (<Идентификатор объекта>)
Opsione:
<Идентификатор объекта>(e nevojshme)
Lloji: String. ProgID (Identifikuesi Programatik) i objektit të komponentit të jashtëm. Duhet të përputhet me informacionin në bazën e të dhënave të regjistrimit të sistemit (Regjistri).
Përshkrim:
Lidh objektet e komponentëve të jashtëm me 1C: Enterprise.
Nuk disponohet në serverin 1C:Enterprise. Nuk përdoret në modulin e lidhjes së jashtme.
Shënim:
Komponentët e jashtëm janë të pajtueshëm me komponentët 1C:Enterprise 7.7.
Shembull:
Përpjekje
ConnectExternalComponent ("AddinObject.Scanner");
alarm ("Përbërësi i skanerit të barkodit u ngarkua");
Përjashtim
alarm ("Përbërësi i skanerit të barkodit nuk është ngarkuar");
Fundi i përpjekjeve

A ka ndonjë mënyrë për ta lidhur këtë dll me 8.1 apo jo?

Faleminderit!

Përgjigje:

Kohët e fundit kam pasur edhe këtë problem. Nuk ishte e mundur të konvertohej në një version të mëvonshëm të 1s. dll me të cilin funksionon ky konfigurim thjesht ndaloi së punuari dhe 1c ra me një gabim.
Problemi u zgjidh në mënyrën e mëposhtme:
Krijova një bazë të dhënash të zbrazët 8.3 në të cilën përpunova inicializimin e komponentit dhe më pas nga 8.1 përmes lidhjes COM hyra në bazën e të dhënave të krijuar më herët dhe inicializova komponentin atje. Pastaj, tashmë në 8.1, thirra metodat e këtij komponenti.
Sigurisht, kjo është një paterica, por unë nuk kam gjetur ende një rrugëdalje tjetër (

Shembulli i kodit 8.3:
Rem Driver Export;
Funksioni ConnectionComponentsCCP() Eksporto
Përpjekje

Layout = GetLayout("IntegrationComponent");
Adresa = PlaceInTempStorage(Layout);
ConnectExternalComponent(Adresa, "IntegrationComponent", ExternalComponentType.Native);
Driver = I ri ("AddIn.IntegrationComponent.SMDrvFR1C20");
rezultat = i vërtetë;

Përjashtim

rezultat = i rremë;

Fundi i Përpjekjes;
Rezultati i Kthimit
Funksionet e Fundit

Shembulli i kodit 8.1

Funksioni CreateDriverObject(Driver) Export

rezultat = i vërtetë;

Përpjekje

ConnectionString="File="""Rruga drejt bazës së të dhënave""";
ComObject= COMObject i ri ("V83.ComConnector");
Connect = ComObject.Connect(ConnectionString);

Përpunimi = Connect.Processing.ConnectingExternalComponent.Create();
ConnectionResult = Processing.ConnectingKKT Components();
Nëse rezultati lidhet atëherë
Driver = Përpunim.Driver;
FundNëse;

Përjashtim
Kushdo që e ka bërë këtë ose ka përjetuar probleme të ngjashme, ju lutemi të shpjegojë. shembull i thjeshtë vetë parimi. Duket se gjithçka është e qartë me lidhjen e komponentëve të jashtëm.

// Një shembull i plotësimit të tabelës së vlerave TK.Clear(); Kërkesë = Kërkesë e re; Query.Text = "ZGJEDH | Nomenklatura Link SI Nomenklatura | NGA | Directory.Nomenklature AS Nomenklature"; QueryResult = Query.Execute(); Sampling = QueryResult.Select(); Ndërsa Sampling.Next() Loop Str = TK.Add(); FillPropertyValues(Pr, Sampling); EndCycle;
A mund të shpjegoni me këtë shembull se cila pjesë e kodit zakonisht hiqet. Do të ishte logjike të hiqnim pjesën me kërkesën, por atëherë si mund të hyjmë në bazën e të dhënave nga komponenti i jashtëm nga komponenti i jashtëm, duke anashkaluar platformën? Teksti është i pakuptimtë. Ose hiqni vetë formimin e pjesës tabelare. Ju lutemi ndani përvojën tuaj me këtë.

Përgjigje: Dhe se fjala "I papajtueshëm" do të thotë gjithmonë fjalën "E keqe"? Po, më duket se nëse e quaj stilin tim "1C: Programimi më i keq në këtë motor shkrimi që ekziston në natyrë (i përkthyer në një gjuhë letrare)!" dhe pastaj me siguri do të ketë nga ata që duan ta kontrollojnë këtë bishë. Dhe duket si një klasik: "Unë nuk e kam lexuar Pasternak, por nuk jam plotësisht dakord me të!" :)

Pyetje: Lidhja e një komponenti të jashtëm në 1s 8.3.6 dhe Win8


Është e nevojshme të lidhni Komponentin e Jashtëm vk_rs232.dll me konfigurimin e shkruar vetë. Ashtu si i regjistruar përmes regsvr32.exe. "Duket" sepse mora një mesazh që "komponenti është i regjistruar, por diçka nuk shkon me murin e zjarrit". Duke u mbështetur në gjysmën e parë të mesazhit, unë shkruaj kodin në 1s
AfterConnection = Përshkrim i ri i njoftimit ("AfterConnectionVK",ThisForm); StartExternalComponentInstallation("C:\Controller\vk_rs232.dll"); StartConnectingExternalComponent(Pas Lidhjes,"C:\Controller\vk_rs232.dll","DLL_Scales");
dhe marr gabimin se
"Instalimi i komponentit të jashtëm dështoi! Komponenti për aplikacionin e klientit që po përdorni mund të mungojë!".

Dhe tani nuk e kuptoj
1. Ndoshta komponenti nuk është i regjistruar në regjistër - si mund ta kontrolloj atje?
2. Ndoshta "versioni" i tij nuk funksionon nën Win8, megjithëse unë e kam 32-bit.
3. Ndoshta vetë 1s është shumë e re, d.m.th. prandaj nuk mund të punojë me këtë dll?
4. Epo, është banale - po shkruaj diçka të gabuar.

Përgjigje: Dhe e gjithë kjo më çoi në problemin tjetër. VneshComp i instaluar, tani duhet ta lidhni. Dhe këtu janë të dyja opsionet.
ConnectExternalComponent ("C:\Controller\vk_rs232.dll","Shkallët")
ConnectExternalComponent ("GeneralLayout.Layout","Scales")

Opsioni sintaksor: Sipas emrit dhe vendndodhjes

Sintaksë:

Lidhni komponentin e jashtëm (<Местоположение>, <Имя>, <Тип>)
Opsione:

<Местоположение>(e nevojshme)

Lloji: String.
Vendndodhja e komponentit të jashtëm.
Vendndodhja mund të përdoret:
rruga për në skedarin e komponentit të jashtëm në sistemin e skedarëve (nuk disponohet në klientin në internet), jo një arkiv ZIP;
emri i plotë një plan urbanistik që ruan të dhëna binare ose një arkiv ZIP;
URL-ja e komponentit të jashtëm, në formën e të dhënave binare ose një arkivi ZIP, në një , të ngjashme me GetNaviLink.
<Имя>(e nevojshme)

Lloji: String.
Emri simbolik i komponentit të jashtëm të mbyllshëm.
Emri duhet të ndjekë konventat e emërtimit të gjuhës së integruar.
<Тип>(opsionale)

Lloji: Lloji i Komponentit të Jashtëm.
Lloji i komponentit të jashtëm që do të lidhet.
Nuk përdoret nëse komponenti është i paketuar në një arkiv ZIP.
Përshkrimi i variantit të metodës:

Lidh komponentët e bërë duke përdorur teknologjinë Native dhe COM.
Komponenti mund të ruhet në një bazë informacioni ose konfigurim si të dhëna binare ose në një arkiv ZIP.
Për mënyrat e nisjes "Thin client" dhe "Web client", komponenti duhet të instalohet më parë duke përdorur metodën Install External Component.
Opsioni sintaksor: Me ID

Sintaksë:

Lidhni komponentin e jashtëm (<ИдентификаторОбъекта>)
Opsione:

<ИдентификаторОбъекта>(e nevojshme)

Lloji: String.
Identifikuesi i objektit të komponentit të jashtëm në formën e ProgID (Identifikuesi Programatik) i regjistrit MS Windows (për shembull: "AddIn.Scanner").
Duhet të përputhet me informacionin në bazën e të dhënave të regjistrimit të sistemit (Regjistri).
Përshkrimi i variantit të metodës:

Komponenti duhet të zbatohet duke përdorur teknologjinë COM dhe të regjistrohet në regjistrin MS Windows.
Këta komponentë janë të pajtueshëm me komponentët 1C:Enterprise 7.7.
Kujdes! Varianti i metodës nuk funksionon në server dhe në lidhjen e jashtme.
Vlera e kthimit:

Lloji: Boolean.
E vërtetë - lidhja ishte e suksesshme.
Përshkrim:

Lidh një komponent të jashtëm me 1C: Enterprise.
Komponentët e jashtëm mund të ruhen në bazën e informacionit ose paraqitjet e konfigurimit si një arkiv ZIP ose si të dhëna binare, ose në një skedar të sistemit të skedarëve.
Kur punoni në një klient të hollë dhe klient në internet, komponenti duhet të jetë i instaluar paraprakisht.

Disponueshmëria:

Thin klient, klient web, server, lidhje e jashtme.
Shënim:

Komponentët e jashtëm mund të zbatohen duke përdorur teknologjinë Native API ose COM. Komponentët e bërë duke përdorur teknologjinë COM janë në përputhje me komponentët 1C:Enterprise 7.7.
Klienti i uebit mund të punojë vetëm me komponentë në një bazë informacioni që janë të paketuara në një arkiv.
Klienti i hollë mund të punojë me komponentë në infobazë, të paketuar në një arkiv dhe komponentë të vendosur në sistemin e skedarëve.
Klienti i trashë mund të punojë me të gjitha opsionet e ruajtjes së komponentëve. Në këtë rast, nëse komponenti instalohet duke përdorur metodën InstallExternalComponent, atëherë përdoret komponenti i instaluar, dhe nëse nuk është i instaluar, atëherë komponenti do të merret në momentin e lidhjes.
Serveri mund të punojë me të gjithë komponentët. Komponenti ruhet në memorie për seancën e serverit.
Shembull:

Nëse ConnectExternalComponent ("AddinObject.Scanner") Pastaj
alarm ("Përbërësi i skanerit të barkodit u ngarkua");
Përndryshe
alarm ("Përbërësi i skanerit të barkodit nuk është ngarkuar");
FundNëse;

  • tutorial

Prezantimi

Ky artikull jep një ide se si funksionojnë komponentët e jashtëm në sistemin 1C: Enterprise.
Do të shfaqet procesi i zhvillimit të një komponenti të jashtëm për sistemin 1C: Enterprise version 8.2 që funksionon nën sistemin operativ Windows me një version skedari të punës. Ky opsion përdoret në shumicën e zgjidhjeve të dizajnuara për bizneset e vogla. VC do të zbatohet në gjuhën e programimit C++.

Komponentët e jashtëm "1C: Ndërmarrja"

"1C: Enterprise" është një sistem i shtrirë. Për zgjerim funksionalitetin sistemi përdor komponentë të jashtëm (VC). Nga këndvështrimi i një zhvilluesi, një VC është një objekt i jashtëm që ka veti dhe metoda, dhe gjithashtu mund të gjenerojë ngjarje për përpunim nga sistemi 1C:Enterprise.
Komponentët e jashtëm mund të përdoren për të zgjidhur një klasë detyrash që janë të vështira apo edhe të pamundura për t'u zbatuar duke përdorur gjuhën e programimit të integruar në 1C: Enterprise. Në veçanti, kjo klasë përfshin detyra që kërkojnë ndërveprim të nivelit të ulët me sistemin operativ, për shembull, për të punuar me pajisje specifike.
Sistemi 1C: Enterprise përdor dy teknologji për krijimin e komponentëve të jashtëm:
  • duke përdorur Native API
  • duke përdorur teknologjinë COM
Duke pasur parasysh kufizimet midis dy teknologjive të mësipërme, ndryshimi është i parëndësishëm, kështu që ne do të shqyrtojmë zhvillimin e VK duke përdorur API-në vendase. Nëse është e nevojshme, zhvillimet e zbatuara mund të aplikohen në zhvillimin e VC duke përdorur teknologjinë COM, dhe gjithashtu, me modifikime të vogla, të aplikohen për përdorim në sistemin 1C: Enterprise me opsione të tjera operative përveç mënyrës së funksionimit të skedarit.
Struktura VK
Komponenti i jashtëm i sistemit 1C:Enterprise paraqitet si një bibliotekë DLL. Kodi i bibliotekës përshkruan klasën e nxjerrë nga IComponentBase. Në klasën që krijohet, duhet të përcaktohen metodat përgjegjëse për zbatimin e funksioneve të komponentit të jashtëm. Metodat e anashkaluara do të përshkruhen më në detaje më vonë gjatë prezantimit të materialit.

Nisja e demonstrimit VK

Një detyrë:
  1. Mblidhni komponentin e jashtëm të furnizuar me abonimin ITS dhe të krijuar për të demonstruar aftësitë kryesore të mekanizmit të komponentit të jashtëm në 1C
  2. Lidhni komponentin demo me konfigurimin 1C
  3. Sigurohuni që funksionet e deklaruara të funksionojnë saktë
Përpilimi
VC-ja demonstruese ndodhet në diskun e abonimit ITS në drejtorinë "/VNCOMP82/shembull/NativeAPI".
Ne do të përdorim Microsoft Visual Studio 2008 për të montuar demonstrimin VK. Versionet e tjera të këtij produkti nuk e mbështesin formatin e përdorur të projektit Visual Studio.


Hapni projektin AddInNative. Në cilësimet e projektit, ne lidhim direktorinë me skedarët e titullit të nevojshëm për të ndërtuar projektin. Si parazgjedhje, ato janë të vendosura në diskun ITS në drejtori /VNCOMP82/përfshi.
Rezultati i ndërtimit është një skedar /bind/AddInNative.dll. Kjo është biblioteka e përpiluar për t'u lidhur me konfigurimin 1C.
Lidhja e konfigurimit VK me 1C
Le të krijojmë një konfigurim bosh 1C.
Më poshtë është kodi për modulin e aplikacionit të menaxhuar.
var DemoComp; Procedura e nisjes së sistemit() ConnectExternalComponent("...\bind\AddInNative.dll", "DemoVK", ExternalComponentType.Native); DemoComp = I ri ("AddIn.DemoVK.AddInNativeExtension"); Përfundimi i procedurës
Nëse nuk u raportua asnjë gabim gjatë fillimit të konfigurimit 1C, atëherë VK u lidh me sukses.
Si rezultat i ekzekutimit të kodit të mësipërm, një objekt shfaqet në dukshmërinë globale të konfigurimit DemoComp Një që ka veti dhe metoda që përcaktohen në kodin e fasules së jashtme.
Demonstrimi i funksionalitetit të ngulitur
Le të kontrollojmë performancën e demo VK. Për ta bërë këtë, le të përpiqemi të vendosim dhe lexojmë disa veti, të thërrasim disa metoda VK dhe gjithashtu të marrim dhe përpunojmë një mesazh VK.
Dokumentacioni i dhënë në diskun ITS deklaron funksionalitetin e mëposhtëm të VC-së demo:
  1. Menaxhimi i gjendjes së objektit të komponentit
    Metodat: Ndez, Fikeni
    Vetitë: Të përfshira
  2. Kontrolli i kohëmatësit
    Çdo sekondë, komponenti dërgon një mesazh në sistemin 1C: Enterprise me parametra Komponenti, kohëmatës dhe një varg numëruesi i orës së sistemit.
    Metodat: StartTimer, StopTimer
    Vetitë: Ka një kohëmatës
  3. Metoda ShowInStatusLine, e cila shfaq në shiritin e statusit tekstin e kaluar në metodë si parametra
  4. Metoda Ngarko imazh. Ngarkon një imazh nga skedari i specifikuar dhe e transferon atë në sistemin 1C: Enterprise si të dhëna binare.
Le të sigurohemi që këto funksione të funksionojnë. Për ta bërë këtë, ne do të ekzekutojmë kodin e mëposhtëm:
var DemoComp; Procedura SystemStart() ConnectExternalComponent(...); DemoComp = I ri ("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Disable(); Njofto (DemoComp. Enabled); DemoComp.Enable(); Njofto (DemoComp. Enabled); DemoComp.StartTimer(); EndProcedure ProcedureExternalEventHandler(Burimi, Ngjarja, Të Dhënat) Raporti(Burimi + " " + Ngjarja + " " + Të dhënat); Përfundimi i procedurës
Rezultati i ekzekutimit të konfigurimit tregohet në imazh


Rezultatet e thirrjeve të metodës shfaqen në panelin "Mesazhet". DemoComp.Disable() dhe Demo.Comp.Enable(). Rreshtat pasues në të njëjtin panel përmbajnë rezultatet e përpunimit të mesazheve të marra nga VK - Burimi, Ngjarje dhe Të dhënat përkatësisht.

Emri arbitrar i komponentit të jashtëm

Detyrë: Ndryshoni emrin e komponentit të jashtëm në një arbitrar.
Seksioni i mëparshëm përdori identifikuesin AddInNativeExtension, kuptimi i të cilit nuk u shpjegua. Në këtë rast AddInNativeExtensionështë emri i shtesës.
Kodi VC përcakton një metodë Register ExtensionAs, i cili kthen emrin në sistemin 1C: Enterprise, i cili është i nevojshëm për regjistrimin e mëvonshëm të QV-së në sistem. Rekomandohet të specifikoni një identifikues që, në një masë të caktuar, zbulon thelbin e komponentit të jashtëm.
Këtu është kodi i plotë i metodës Register ExtensionAs me emrin shtesë të ndryshuar:
bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) ( wchar_t *wsExtension = L"SomeName"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* (wsExtension) + 1; ((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, wsExtension, iActualSize); kthe e vërtetë; ) kthe false; )
Në shembullin e mësipërm, emri VK është ndryshuar në Disa Emra. Pastaj, kur lidhni VK, duhet të specifikoni një emër të ri:
DemoComp = I ri ("AddIn.DemoVK.SomeName");

Zgjerimi i listës së pronave VK

Një detyrë:
  1. Studioni zbatimin e vetive të QV
  2. Shtoni një veçori leximi-shkrimi të një lloji vargu
  3. Shtoni një veçori të tipit të vargut të leximit/shkrimit që ruan llojin e të dhënave të grupit të fundit të vetive. Asnjë veprim nuk ndërmerret gjatë vendosjes së vlerës së pronës

Për të përcaktuar vetitë e komponentit që krijohet, zhvilluesi duhet të zbatojë metodat e mëposhtme në kodin e bibliotekës AddInNative.cpp:
GetNProps
Rikthen numrin e vetive për këtë shtesë, 0 nëse nuk ka veçori
FindProp
Kthen numrin rendor të pronës emri i së cilës kalohet në parametra
GetPropName
Kthen emrin e pronës me rendoren e saj dhe me ID-në e gjuhës së kaluar
GetPropVal
Kthen vlerën e pronës me rendin e specifikuar
SetPropVal
Vendos vlerën e pronës me rendin e caktuar
IsPropReadable
Kthen flamurin e lexueshmërisë së pronës me rendin e specifikuar
IsPropWritable
Kthen flamurin e shkrueshmërisë së vetive me numrin e sekuencës së specifikuar


Merrni parasysh zbatimin e metodave të mësipërme të klasës CAddInNative.
VC demonstruese përcakton 2 veti: Të përfshira dhe Ka një kohëmatës (Është Enabled dhe IsTimerPresent).
Dy vargje janë përcaktuar në shtrirjen globale të kodit të bibliotekës:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent"); static wchar_t *g_PropNamesRu = (L"Enabled", L"Ka një kohëmatës");
të cilat ruajnë emrat rusisht dhe anglisht të pronave. Në skedarin e kokës AddInNative.h një numër është përcaktuar:
enum Props (ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Gjithmonë e fundit);
ePropIsEnabled dhe ePropIsTimerPresent, përkatësisht që kanë vlerat 0 dhe 1, përdoren për të zëvendësuar numrat rendorë të vetive me identifikues kuptimplotë. ePropLast, i cili ka një vlerë prej 2, përdoret për të marrë numrin e vetive (duke përdorur metodën GetNProps). Këta emra përdoren vetëm brenda kodit të komponentit dhe nuk janë të aksesueshëm nga jashtë.
Metodat FindProp dhe GetPropName kërkojnë nëpër vargje g_PropEmrat dhe g_PropEmrat.
Për të ruajtur vlerën e fushave në modulin e bibliotekës, klasa CAddInNative ka veti që ruajnë vlerën e vetive të komponentit. Metodat GetPropVal dhe SetPropVal përkatësisht kthejnë dhe vendosin vlerën e këtyre vetive.
Metodat IsPropReadable dhe IsPropWritable dhe kthehu e vërtetë ose i rremë, në varësi të rendores së kaluar të pasurisë sipas logjikës së aplikimit.
Për të shtuar një pronë të personalizuar:

  1. Shto emrin e pronës që do të shtohet në vargje g_PropEmrat dhe g_PropEmrat(skedar AddInNative.cpp)
  2. Për të numëruar props(skedar AddInNative.h) më parë ePropLast shtoni një emër që identifikon në mënyrë unike pronën që do të shtohet
  3. Organizoni memorien për ruajtjen e vlerave të vetive (krijoni fusha të modulit të komponentit që ruajnë vlerat përkatëse)
  4. Bëni ndryshime në metoda GetPropVal dhe SetPropVal për të bashkëvepruar me memorien e alokuar në hapin e mëparshëm
  5. Në përputhje me logjikën e aplikimit, bëni ndryshime në metoda IsPropReadable dhe IsPropWritable
Pikat 1, 2, 5 nuk kanë nevojë për shpjegim. Detajet e zbatimit të këtyre hapave mund të gjenden në shtojcën e artikullit.
Le të emërtojmë vetitë e provës Test dhe Lloji Kontrollo përkatësisht. Pastaj, si rezultat i paragrafit 1, kemi:
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");
Numërimi props do të duket si:
enum Props (ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Gjithmonë e fundit);
Për të thjeshtuar ndjeshëm kodin, ne do të përdorim STL C++. Në veçanti, për të punuar me vargje WCHAR, lidhni bibliotekën string.
Për të ruajtur vlerën e një metode Test, përcaktoni në klasë CAddInNative në fushën private:
testi i vargut1;
Për të transferuar parametrat e vargut midis 1C:Enterprise dhe një komponenti të jashtëm, përdoret menaxheri i memories 1C:Enterprise. Le të hedhim një vështrim më të afërt në punën e tij. Për të shpërndarë dhe liruar memorie, përkatësisht, përdorni funksionet AllocMemory dhe Memoria e Lirë, të përcaktuara në skedar MemoryManager.h. Nëse është e nevojshme të kaloni një parametër të vargut në sistemin 1C: Enterprise, komponenti i jashtëm duhet të ndajë memorie për të duke thirrur funksionin AllocMemory. Prototipi i tij duket si ky:
virtual bool ADDIN_API AllocMemory (void** pMemory, ulCountByte e gjatë e panënshkruar) = 0;
ku pKujtesa- adresa e treguesit në të cilin do të vendoset adresa e memories së alokuar,
ulCountByte- madhësia e zonës së caktuar të memories.
Një shembull i ndarjes së memories për një varg:
WCHAR_T *t1 = NULL, *test = L"TEST_STRING"; int iActualSize = wcslen(test1)+1; m_iMemory->AllocMemory((void**)&t1, iActualSize * sizeof(WCHAR_T)); ::convToShortWchar(&t1, test1, iActualSize);
Për lehtësinë e punës me llojet e të dhënave të vargut, ne përshkruajmë funksionin wstring_to_p. Merr një varg wstring si parametër. Rezultati i funksionit është një strukturë e mbushur tVariant. Kodi i funksionit:
bool CAddInNative::wstring_to_p(std::wstring str, tVariant* val) (char* t1; TV_VT(val) = VTYPE_PWSTR; m_iMemory->AllocMemory((void**)&t1, (rr. gjatësia ()+1) madhësia e(WCHAR_T));memcpy(t1, str.c_str(), (str.gjatësia()+1) * madhësia(WCHAR_T));val -> pstrVal = t1; val -> strLen = str.gjatësia(); kthehu i vërtetë;)
Pastaj seksioni përkatës i rastit të deklaratës switch të metodës GetPropVal do të marrë formën:
rasti ePropTest1: wstring_to_p(test1, pvarPropVal); pushim;
metodë SetPropVal:
rasti ePropTest1: nëse (TV_VT(varPropVal) != VTYPE_PWSTR) kthen false; test1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); pushim;
Për të zbatuar vetinë e dytë, ne përcaktojmë një fushë të klasës CaddInNative
uint8_t lloji i fundit;
në të cilin do të ruajmë llojin e vlerës së fundit të kaluar. Për ta bërë këtë, shtoni komandën e mëposhtme në metodën CaddInNative::SetPropVal:
Lloji_i fundit = TV_VT(varPropVal);
Tani, kur kërkojmë të lexojmë vlerën e pronës së dytë, ne do ta kthejmë vlerën lloji i fundit, e cila kërkohet nga detyra e caktuar.
Le të kontrollojmë performancën e ndryshimeve të bëra.
Për këtë ne paraqesim pamjen konfigurimi 1C për pamjen:
var DemoComp; Procedura e nisjes së sistemit() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = I ri ("AddIn.DemoVK.SomeName"); DemoComp.CheckType = 1; Raporti(String(DemoComp.TypeCheck)); DemoComp.Test = "Vasya"; Raporti(String(DemoComp.Test)); DemoComp.Test = "Petya"; Raporti(String(DemoComp.Test)); Raporti(String(DemoComp.TypeCheck)); Përfundimi i procedurës
Si rezultat i nisjes, marrim një sekuencë mesazhesh:
3
Vasya
Petya
22

Mesazhi i dytë dhe i tretë janë rezultat i leximit të vetive të vendosura në hapin e mëparshëm. Mesazhi i parë dhe i dytë përmbajnë kodin e tipit të grupit të fundit të vetive. 3 korrespondon me një vlerë të plotë, 22 - me një vlerë vargu. Në dosje vendoset korrespondenca e llojeve dhe kodeve të tyre llojet.h, i cili ndodhet në diskun e ITS.

Zgjerimi i listës së metodave

Një detyrë:
  1. Zgjeroni funksionalitetin e komponentit të jashtëm me funksionalitetin e mëposhtëm:
  2. Mësoni se si të zbatoni metodat e komponentëve të jashtëm
  3. Shto metodë-funksion Funksioni 1, i cili merr dy vargje ("Parameter1" dhe "Parameter2") si parametër. Si rezultat, kthehet një varg i formularit: "Kontrollo. Parametri 1, Parametri 2"
  4. Verifikoni që ndryshimet e bëra po funksionojnë.

Për të përcaktuar metodat e komponentit që krijohet, zhvilluesi duhet të zbatojë metodat e mëposhtme në kodin e bibliotekës AddInNative:
GetNMethods, FindMethod, GetMethodName
Projektuar për të marrë, përkatësisht, numrin e metodave, kërkoni numrin dhe emrin e metodës. Ngjashëm me metodat përkatëse për vetitë
GetNParams
Rikthen numrin e parametrave të metodës me numrin e sekuencës së specifikuar; nëse nuk ka metodë me këtë numër ose nuk ka parametra, kthen 0
GetParamDefValue
Kthen vlerën e paracaktuar të parametrit të specifikuar të metodës së specifikuar
HasRetVal
Kthen një flamur që metoda me vlerën e caktuar të kthimit ka rendore: true për metodat me një vlerë kthimi dhe i rremë ndryshe
CallAsProc
i rremë, ndodh një gabim në kohën e ekzekutimit dhe ekzekutimi i modulit 1C: Enterprise ndalon. Kujtesa për grupin e parametrave ndahet dhe lëshohet nga 1C: Enterprise.
CallAsFunc
Ekzekuton metodën me rendoren e caktuar. Nëse metoda kthehet i rremë, ndodh një gabim në kohën e ekzekutimit dhe ekzekutimi i modulit 1C: Enterprise ndalon. Kujtesa për grupin e parametrave ndahet nga 1C: Enterprise. Nëse vlera e kthyer është e tipit string ose të dhëna binare, komponenti alokon memorie me funksionin AllocMemory menaxheri i memories, shkruan aty të dhënat dhe e ruan këtë adresë në fushën përkatëse të strukturës. 1С: Ndërmarrja do ta lëshojë këtë memorie duke telefonuar Memoria e Lirë.
Një përshkrim i plotë i metodave, duke përfshirë listën e parametrave, përshkruhet në detaje në dokumentacionin e dhënë në diskun e ITS.
Konsideroni zbatimin e metodave të përshkruara më sipër.
Në kodin e komponentit, përcaktohen dy vargje:
static wchar_t *g_MethodNames = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"); static wchar_t *g_MethodNamesRu = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage");
dhe numërimi:
enum Metodat (eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Gjithmonë e fundit );
Ato përdoren në funksione GetNMethods, FindMethod dhe GetMethodName, në analogji me përshkrimin e vetive.
Metodat GetNParams, GetParamDefValue, HasRetVal ndërprerësi i implementimit, në varësi të parametrave të kaluar dhe logjikës së aplikimit, ktheni vlerën e kërkuar. Metoda HasRetVal në kodin e tij ka një listë të metodave të vetme që mund të kthejnë një rezultat. Për ta rikthehet e vërtetë. Për të gjitha metodat e çelikut kthimet i rremë.
Metodat CallAsProc dhe CallAsFunc përmbajnë kodin e metodës drejtpërdrejt të ekzekutueshme.
Për të shtuar një metodë që mund të thirret vetëm si funksion, duhet të bëni ndryshimet e mëposhtme në kodin burimor të komponentit të jashtëm:
  1. Shtoni emrin e metodës në vargje g_Emrat e metodave dhe g_Emrat e metodave(skedar AddInNative.cpp)
  2. Shtoni një identifikues kuptimplotë të metodës në enumin e metodave (skedari AddInNative.h)
  3. Bëni ndryshime në kodin e funksionit GetNParams sipas logjikës së programit
  4. Nëse është e nevojshme, bëni ndryshime në kodin e metodës GetParamDefValue nëse dëshironi të përdorni vlerat e paracaktuara të parametrave të metodës.
  5. Bëni ndryshime në një funksion HasRetVal
  6. Bëni ndryshime në logjikën e funksioneve CallAsProc ose CallAsFunc, duke vendosur kodin direkt të ekzekutueshëm të metodës atje
Le të sjellim vargje g_Emrat e metodave dhe g_Emrat e metodave, si dhe numërimin metodat për pamjen:
static wchar_t *g_MethodNames = (L"Aktivizo", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"); static wchar_t *g_MethodNamesRu = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage", L"Test");

Metodat Enum (eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Gjithmonë e fundit );
Le të modifikojmë funksionin GetNProps në mënyrë që të kthejë numrin e parametrave të metodës "Test":
gjatë CAddInNative::GetNParams(konst long lMethodNum) ( switch(lMethodNum) (rasti eMethShowInStatusLine: kthen 1; rasti eMethLoadPicture: kthen 1; rasti eMethTest: kthen 2; parazgjedhje: kthen 0; ) kthen 0; )
Le të bëjmë ndryshime në funksion:
bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) ( ​​​​TV_VT(pvarParamDefValue)= VTYPE_EMPTY; switch(lMethodNum) ( case eMethEnable: case eMethDisable: case eMethShowInStatusLine: case eMethStartTimer: case eMethStopTimer: case eMethTest : rasti / Nuk ka vlera parametrash sipas parazgjedhjes; default: kthe false; ) kthe false; )
Falë linjës së shtuar
rasti eMethTest:
në mungesë të një ose më shumë argumenteve, parametrat përkatës do të kenë një vlerë boshe ( VTYPE_EMPTY). Nëse keni nevojë për një vlerë të paracaktuar për një parametër, duhet ta specifikoni atë në seksion eMethTest deklarata e ndërruesit të funksionit CAddInNative::GetParamDefValue.
Meqenëse metoda "Test" mund të kthejë një vlerë, duhet të bëni ndryshime në kodin e funksionit HasRetVal:
bool CAddInNative::HasRetVal(konst long lMethodNum) ( switch(lMethodNum) (rasti eMethLoadPicture: rasti eMethTest: kthen true; default: kthen false; ) kthen false; )
Dhe shtoni kodin e ekzekutueshëm të metodës në funksion CallAsFunc:
bool CAddInNative::CallAsFunc(konst long lMethodNum, tVariant* pvarRetValue, tVariant* paparams, const long lSizeArray) ( ... std::wstring s1, s2; switch(lMethodNum) (rasti eMethLoadT; nëse (!lSizeArray || !paParams) kthen false; s1 = (paParams) -> pwstrVal; s2 = (paParams+1) -> pwstrVal; wstring_to_p(std::wstring(s1+s2), pvarRetValue); ret = true ; pushim; ) kthim ret;)
Le të përpilojmë komponentin dhe të sjellim kodin e konfigurimit në formën:
var DemoComp; Procedura e nisjes së sistemit() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = I ri ("AddIn.DemoVK.SomeName"); korsi = DemoComp.Test("Përshëndetje, ", "Bota!"); Njoftoni (për); Përfundimi i procedurës
Pas fillimit të konfigurimit, do të marrim një mesazh: "Përshëndetje, Botë!", që tregon se metoda ka funksionuar me sukses.

Timer

Një detyrë:
  1. Studioni zbatimin e kohëmatësit në demo VK
  2. Ndryshoni metodën "StartTimer" duke shtuar aftësinë për të kaluar në parametra intervalin e kohëmatësit (në milisekonda)
  3. Verifikoni që ndryshimet e bëra po funksionojnë.

Në WinAPI, për të punuar me kohën, mund të përdorni mesazhin WM_TIMER. Ky mesazh do t'i dërgohet programit tuaj në intervalin kohor që specifikoni kur krijoni kohëmatësin.
Për të krijuar një kohëmatës përdorni funksionin SetTimer:
UINT SetTimer(HWND hWnd, // doreza e dritares UINT nIDevent, // identifikuesi i kohëmatësit (numri) UINT nElapse, // vonesa TIMERPROC lpTimerFunc); // treguesi i funksionit
Sistemi operativ do të dërgojë një mesazh WM_TIMER në program me intervalin e specifikuar në argument nKalimi(në milisekonda). Në parametrin e fundit, mund të specifikoni një funksion që do të ekzekutohet sa herë që ndizet kohëmatësi. Kreu i këtij funksioni duhet të duket kështu (emri mund të jetë çdo gjë):
void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Konsideroni zbatimin e kohëmatësit në demonstrimin VK.
Meqenëse po shqyrtojmë procesin e zhvillimit të një komponenti të jashtëm për familjen Windows OS, ne nuk do të shqyrtojmë zbatimin e kohëmatësit në të tjera sistemet operative. Për GNU/Linux OS, në veçanti, zbatimi do të ndryshojë në sintaksën e funksionit SetTimer dhe TimerProc.
Metoda thirret në kodin e ekzekutueshëm SetTimer, të cilit i kalon funksioni MyTimerProc:
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
ID-ja e kohëmatësit të krijuar vendoset në një variabël m_uiTimer në mënyrë që ta fikni më vonë.
Funksioni MyTimerProc si vijon:
BANKËSHTJA E Thirrjes VOID MyTimerProc(HWND hwnd, // doreza e dritares për mesazhet e kohëmatësit UINT uMsg, // mesazhi WM_TIMER UINT idEvent, // identifikuesi i kohëmatësit DWORD dwTime // koha aktuale e sistemit) ( nëse (!pAsyncEvent) *who = wchar "ComponentNative", *what = L"Timer"; wchar_t *wstime = new wchar_t; if (wstime) ( wmemset(wstime, 0, TIME_LEN); ::_ultow(dwTime, wstime, 10); pAsyncEvent->ExternalEvent(who , çfarë, wstime); fshi wstime; ))
Thelbi i funksionit është se thirret metoda Ngjarje e jashtme, i cili dërgon një mesazh në sistemin 1C: Enterprise.
Për të zgjeruar funksionalitetin e metodës StartTimer le të bëjmë sa vijon:
Modifikimi i kodit të metodës GetNParams në mënyrë që të jetë për metodën eMethStartTimer vlera e kthyer 1:
rasti eMethStartTimer: kthimi 1;
Këtu është kodi i metodës CallAsProc për pamjen:
rasti eMethStartTimer: nëse (!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;
Tani le të kontrollojmë funksionalitetin. Për ta bërë këtë, në modulin e aplikacionit të menaxhuar të konfigurimit, ne do të shkruajmë kodin:
var DemoComp; Procedura e nisjes së sistemit() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = I ri ("AddIn.DemoVK.SomeName"); DemoComp.StartTimer (2000); Përfundimi i procedurës
Pas fillimit të konfigurimit, programi do të marrë mesazhe me një interval prej 2 sekondash, gjë që tregon funksionimin e saktë të kohëmatësit.

Ndërveprimi me sistemin 1C: Enterprise

Për të bashkëvepruar midis komponentit të jashtëm dhe sistemit 1C:Enterprise, metodat e klasës IAddInDefBase të përshkruara në skedar AddInDefBase.h. Ne listojmë më të përdorurat:
Gjenerimi i mesazhit të gabimit
virtual bool ADDIN_API AddError (kodi i shkurtër i panënshkruar, burimi konst WCHAR_T*, përshkrimi WCHAR_T* konst, kodi i gjatë)
wcode, kodi- kodet e gabimit (një listë e kodeve të gabimit me një përshkrim mund të gjendet në diskun ITS)
burimi- burimi i gabimit
përshkruaj- përshkrimi i gabimit
Dërgimi i një mesazhi në sistemin 1C: Enterprise
virtual bool ADDIN_API Ngjarje e jashtme (WCHAR_T* wszBurimi, WCHAR_T* wszMesazh, WCHAR_T* wszData) = 0;
wszBurimi- burimi i mesazhit
wszMesazhi- Teksti i mesazhit
wszTë dhënat- të dhënat e transmetuara
Përgjimi i mesazhit kryhet me procedurën HandlingExternalEvent
Regjistrimi i një komponenti të jashtëm në sistemin 1C: Enterprise
virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszEmri i profilit- emri i komponentit.
Këto metoda janë të mjaftueshme për ndërveprimin e plotë të VK dhe 1C. Për të marrë të dhëna nga një komponent i jashtëm nga sistemi 1C: Enterprise dhe anasjelltas, komponenti i jashtëm dërgon një mesazh të veçantë, i cili, nga ana tjetër, kapet nga sistemi 1C dhe, nëse është e nevojshme, thërret metodat e komponentit të jashtëm për të dërguar. të dhëna prapa.

Lloji i të dhënave tVariant

Kur shkëmbeni të dhëna midis një komponenti të jashtëm dhe sistemit 1C:Enterprise, përdoret lloji i të dhënave tVariant. Ai përshkruhet në skedarin type.h, i cili mund të gjendet në diskun ITS:
strukturë _tvariant (_anonyony_union bashkim (int8_t i8val; int16_t shortval; int32_t lval; int intval; int int uintval; int64_t llval; uint8_t ui8val; uint16_t ushortval; uint32_t ulval; uint64_t ulLval; int32_t hart; i gjatë; bVal; char chVal; wchar_t wchVal; DATE data; IID IDVal; struct _tVariant *pvarVal; struct tm tmVal; _ANONYMOUS_STRUCT struct ( void* pInterfaceVal; IID InterfaceID; ) __VARIANT_NAMEY_2;* /numërimi i bajteve ) __VARIANT_NAME_3/*str*/; Struktura _ANONYMOUS_STRUCT ( WCHAR_T* pwstrVal; uint32_t wstrLen; //numërimi i simbolit ) __VARIANT_NAME_4/*wstr*/; ) __VARIANT_3 dimensionElements an-Dimensioni //Dimensioni i __VARIANT_3Elements_1b; në pvarVal TYPEVAR vt;);
Lloji i tVariantështë një strukturë që përfshin:
  • përzierje (bashkim) i destinuar drejtpërdrejt për ruajtjen e të dhënave
  • identifikues i llojit të të dhënave
Në përgjithësi, puna me variabla të llojit tVariant ndodh sipas algoritmit të mëposhtëm:
  1. Përcaktimi i llojit të të dhënave të ruajtura aktualisht në një variabël
  2. Qasje në fushën përkatëse të përzierjes, për akses të drejtpërdrejtë në të dhëna
Lloji i përdorimit tVariant thjeshton shumë ndërveprimin e sistemit 1C: Enterprise dhe një komponenti të jashtëm

Aplikacion

Drejtoria "shembuj" përmban shembuj për artikullin
shembuj/1 - ekzekutoni komponentin demo
shembuj/2 - demonstrim i zgjerimit të listës së pronave
shembuj/3 - demonstrim i zgjerimit të listës së metodave
Çdo direktori përmban një projekt VS 2008 dhe një konfigurim të para-ndërtuar 1C.

Shpesh, programuesit kanë probleme në lidhjen e komponentëve të jashtëm (për shembull, drejtuesit e pajisjeve komerciale) kur përdoruesit punojnë me 1C duke u lidhur me serverin përmes terminalit.

Në të njëjtën kohë, përdoruesit shohin, për shembull, foton e paraqitur në njoftimin e artikullit.

Ndërsa kur punoni nga kompjuterët lokalë, nuk ka probleme me lidhjen e komponentëve të jashtëm.

Me çfarë lidhet? Kjo është për shkak se kur përdoruesit punojnë përmes serverit Terminal, ata kanë më pak të drejta sesa kur punojnë në kompjuterin lokal.

Kjo është e lehtë për t'u verifikuar nëse hyni në serverin e terminalit nën një llogari me të drejta administrative.

Arsyeja për këtë ndryshim është se 1C nuk mund të regjistrojë një komponent të jashtëm në regjistër kur përdoruesi punon në terminal nën të drejta normale, sepse një përdorues normal nuk ka leje shkrimi në degën e regjistrit të sistemit HKEY_CLASSES_ROOT.

Në botimet me temën e lidhjes së komponentëve të jashtëm në terminal, ofrohen një sërë metodash për zgjidhjen e këtij problemi.

Për shembull, këto:

1. Drejtoni 1C për herë të parë nën të drejtat administrative.

Ky opsion nuk funksionon gjithmonë. Unë do të shpjegoj pse më poshtë.

2. Jepni të drejtën përdoruesve të zakonshëm të terminalit të shkruajnë në degën e regjistrit të sistemit HKEY_CLASSES_ROOT.

Përdoruesit e pamjaftueshëm "të avancuar" nuk duhet ta bëjnë këtë, përndryshe mund të ketë probleme.

3. Duke përdorur "gadgets" të ndryshëm, regjistroni VK në emër të një përdoruesi me të drejta të plota.

Nuk është mirë as të hahet.

Pra, cila është mënyra më e mirë për të dalë nga kjo situatë?

Unë ofroj zgjidhjen time për këtë problem. Sipas mendimit tim - e thjeshtë dhe e bukur, e pa ofruar më parë në infostart.

Duke hetuar këtë problem, pyesja veten - pse 1C madje përpiqet të regjistrojë VK përgjatë një rruge të re? Në fund të fundit, ajo tashmë është e regjistruar në sistem.

Gjëja doli të ishte se në konfigurimet tipike 1C (për shembull, "Menaxhimi i Tregtisë") përdoret sintaksa e mëposhtme e metodës së kontekstit global ConnectExternalComponent() :

ConnectExternalComponent("Reference.ConnectedEquipment.Layout.DriverATOLScanner Barcode", "ATOLScanner");

Siç mund ta shihni, drejtuesi VK është i lidhur nga faqosja "DriverATOLScannerBacode" e drejtorisë "Pajisjet e lidhura".

Çfarë ndodh pastaj?

1C ruan komponentin në dosjen e përkohshme të përdoruesit, për shembull "C:\Documents and Settings\User\Local Settings\Temp\1032\v8_4_12.tmp"

dhe përpiqet ta regjistrojë atë në degën e regjistrit HKEY_CLASSES_ROOT përgjatë kësaj rruge.

Në terminal, përdoruesit e zakonshëm nuk kanë të drejtë të ndryshojnë këtë degë të regjistrit, kështu që komponenti nuk është i lidhur për ta.

Tani se si të dilni nga kjo situatë.

Metoda e kontekstit global ConnectExternalComponent() ka disa opsione sintakse. Kjo është ajo që ne do të përdorim.

Pra, hap pas hapi:

1. Regjistroni komponentin e jashtëm duke përdorur mjetin regsvr32.exe në serverin e terminalit në dosjen C:\WINDOWS\SYSTEM32 për një OS 32-bit ose në dosje C:\WINDOWS\SYSWOW64 për OS 64-bit.

2. Përdorni një nga dy opsionet shtesë të sintaksës për metodën ConnectExternalComponent():

Opsioni 1:

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

DriverObject = I ri ("AddIn.ATOLScanner.Scanner45");

Opsioni 2:

ProgID = "AddIn.Scanner45";

Lidh komponentin e jashtëm (ProgID);

DriverObject = New(ProgID);

Sipas mendimit tim, opsioni numër 2 është i preferueshëm.

Në të njëjtën kohë, 1C nuk përpiqet të ri-regjistrojë QV-në përgjatë një rruge të re në regjistër, dhe kështu, të gjitha problemet zgjidhen.

Epo, kjo është e gjitha. Suksese ne pune!

Për shembull, nuk do të jetë e mundur të rishkruhet një komponent nëse nuk jeni autori i tij dhe thjesht nuk ka kode burimore. Ose nëse llojet më të thjeshta të mbështetura nga teknologjia Native API (numri, vargu, boolean, data) nuk mjaftojnë për funksionimin e tij.

Nuk ka probleme të veçanta kur punoni me bazën e skedarëve. Detyra e planifikuar thirret në procesin e sfondit të një përdoruesi normal. Prandaj, thirrjet e klientit janë të disponueshme për të. Nuk ka asnjë kontekst klienti në bazën e të dhënave të serverit kur fillon një detyrë e planifikuar, kështu që thirrja ConnectExternalComponent() i padisponueshem.

Në këtë rast, mund ta telefononi komponentin në klient. Për ta bërë këtë, mjafton të nisni një seancë tjetër 1C nga detyra e planifikuar në server në të cilën të kryeni veprimet e nevojshme në klient. Epo, mos harroni të përfundoni seancën e drejtimit më vonë.

Le të themi se në detyrën tonë të planifikuar, ne gjenerojmë dhe ruajmë një raport që përdor komponentin e jashtëm COM NameDeclension.dll për të refuzuar emrin e plotë. Në bazën e skedarit, një detyrë e tillë e planifikuar do të funksionojë si duhet, por nuk do të funksionojë në komponentin e serverit.

Për të rregulluar problemin, le të shtojmë një procedurë në modulin e detyrave të planifikuara që do të nisë një sesion tjetër në modalitetin e serverit dhe në të do të ekzekutojë një thirrje për gjenerimin e raportit te klienti nga përpunimi i jashtëm.

#If Client then Procedure ExecuteFormationAndSavingReport() Export If ConnectExternalComponent("CommonLayout.NAMEDECL","Cl",ExternalComponentType.COM) Pastaj Komponenti = I ri ("AddIn.Cl.NameDeclension"); //Këtu është kodi për gjenerimin dhe ruajtjen e raportit ElseJoinLogRecord("RegTask", LogLogLevel.Gabim, "Dështoi të lidhë komponentin e jashtëm në klient"); FundNëse; Fundi i procedurës #Otherwise Procedura ExecuteFormationAndSavingReport() Export ExecuteOperationOnClient("RegularTasks.ExecuteFormationAndSavingReport()"); Procedura e Endprocedurës PerformOperationOnClient(ParameterToExecute) ExportUserName = ""; Fjalëkalimi i përdoruesit = ""; PathToExternalProcessing = "c:/temp/Autostart.epf"; Citate = """"; DirectoryBIN = DirectoryProgram(); PathToConfiguration = InfoBase ConnectionString(); ConfigurationPath = StrReplace(ConfigurationPath, Quote, Quote + Quote); StartString = Quote + Bin Directory + "1cv8.exe" + Citate + " ENTERPRISE" + " /IBConnectionString " + Citate + ConfigurationPath + Quote + " /N " + Citate + Emri i përdoruesit + Citat + " /P " + Citate + Fjalëkalimi i përdoruesit + Citate + " /Execute " + Citate + PathToExternalProcessing + Citate + " /C " + Citate + ParameterToExecute + Citate; StartApplication (StartString); FundProcedura #EndIf

Kodi i jashtëm i përpunimit që thjesht bën që konteksti i klientit të printojë raportin e kërkuar nga moduli i punëve të planifikuara dhe përfundon seancën pasi të gjenerohet raporti.

Përpjekje për të ekzekutuar (StartupParameter); Përjashtim FundTry; ShutdownSystem (False);

Komoditeti i zgjidhjes është që kur vendosni detyra të planifikuara, nuk ka rëndësi se në cilën mënyrë do të nisë detyra. Nëse baza e të dhënave është një skedar, atëherë procedura e nevojshme do të fillojë menjëherë. Nëse baza e të dhënave është në anën e serverit dhe nuk ka kontekst klienti në fillim, atëherë do të inicializohet një sesion i ri dhe procedura do të funksionojë siç duhet në kontekstin e klientit.

Kodi për një aplikacion tipik. Teorikisht, do të funksionojë në një mënyrë krejtësisht të ngjashme në një të menaxhuar.

p.s. Gjithashtu, kjo qasje mund të përdoret për të ekzekutuar çdo procedurë klienti në punët e planifikuara.

KOMBANA

Ka nga ata që e lexojnë këtë lajm para jush.
Regjistrohu për të marrë artikujt më të fundit.
Email
Emri
Mbiemri
Si do të dëshironit të lexoni Këmbanën
Nuk ka spam