Noile versiuni ale „1C: Trade Management”: actualizare fără dezvoltare. Contabilitatea operațională devine reglementată


Acest lucru se datorează unor particularități ale funcției de context global ConnectExternalComponent() .

Deseori programatorii au probleme la conectarea componentelor externe (de exemplu, drivere pentru echipamente comerciale) atunci când utilizatorii lucrează cu 1C, conectându-se la server printr-un terminal.

În acest caz, utilizatorii văd, de exemplu, această imagine:

În timp ce atunci când lucrați de pe computere locale, nu există probleme cu conectarea componentelor externe.

Cu ce ​​este legat asta? Acest lucru se datorează faptului că atunci când utilizatorii lucrează printr-un server terminal, au mai puține drepturi decât atunci când lucrează pe un computer local.

Puteți verifica cu ușurință acest lucru dacă vă conectați la serverul terminal sub un cont cu drepturi administrative.

Motivul pentru această diferență este că 1C nu poate înregistra o componentă externă în registru atunci când utilizatorul lucrează în terminal cu drepturi normale, deoarece un utilizator obișnuit nu are permisiunea de a scrie în ramura registrului de sistem HKEY_CLASSES_ROOT.

Publicațiile pe tema conectării componentelor externe în terminal oferă o varietate de metode pentru rezolvarea acestei probleme.

De exemplu, acestea:

1. Lansați 1C pentru prima dată cu drepturi administrative.

Această opțiune nu funcționează întotdeauna. Voi explica mai jos de ce.

2. Oferiți utilizatorilor obișnuiți de terminale permisiunea de a scrie în ramura registrului de sistem HKEY_CLASSES_ROOT.

Este mai bine ca utilizatorii insuficient de „avansați” să nu facă acest lucru, altfel pot apărea probleme.

3. Folosind diverse gadget-uri, înregistrați VK în numele unui utilizator cu drepturi depline.

Nici nu e bine.

Deci, care este cel mai bun mod de a ieși din această situație?

Ofer soluția mea la această problemă. După părerea mea - simplu și frumos.

În timp ce cercetam această problemă, mi-am pus întrebarea: de ce încearcă 1C chiar să înregistreze VK folosind o nouă cale? La urma urmei, ea este deja înregistrată în sistem.

Ideea s-a dovedit a fi că, în configurațiile tipice 1C (de exemplu, „Managementul comerțului”), următoarea sintaxă este utilizată pentru metoda contextului global Connect External Component():

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

După cum puteți vedea, driverul VC este conectat din aspectul „ATOLBarcode Scanner Driver” din directorul „Connected Equipment”.

Ce se întâmplă atunci?

1C salvează componenta în folderul temporar al utilizatorului, de exemplu „C:\Documents and Settings\User\Local Settings\Temp\1032\v8_4_12.tmp”

și încearcă să-l înregistreze în filiala de registru HKEY_CLASSES_ROOT exact pe acest drum.

Pe terminal, utilizatorii obișnuiți nu au drepturi de a schimba această ramură de registry, așa că componenta nu se conectează la ei.

Acum să vorbim despre cum să ieșim din această situație.

Metoda context global ConnectExternalComponent() are mai multe opțiuni de sintaxă. Acesta este ceea ce vom folosi.

Deci, pas cu pas:

1. Înregistrați componenta externă utilizând utilitarul regsvr32.exe pe serverul terminal în folderul C:\WINDOWS\SYSTEM32 pentru un sistem de operare pe 32 de biți sau în folderul C:\WINDOWS\SYSWOW64 pentru un sistem de operare pe 64 de biți.

2. Utilizați una dintre cele două opțiuni de sintaxă suplimentare pentru metoda ConnectExternalComponent():

Opțiunea 1:

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

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

Opțiunea 2:

ProgID = "AddIn.Scaner45";

ConnectExternalComponent(ProgID);

DriverObject = New(ProgID);

După părerea mea, este de preferat varianta numărul 2.

În același timp, 1C nu încearcă să reînregistreze VK folosind o nouă cale în registry și astfel toate problemele sunt rezolvate.

Ei bine, asta-i tot. Mult succes la job!

[trebuie să vă înregistrați pentru a vedea linkul]

Întrebare: API nativă componentă externă în C++ pentru Linux (Ubuntu x64) pe 1C 8.3


Scriu la VK, dar nu mă pot conecta la 1c pe ubuntu. Nici măcar exe 1s nu se conectează. Deci o intrebare despre asta:

1) Încerc să conectez VK din exemplul VNCOMPS dat în articol

(linkul poate fi găsit la sfârșit: „Copiere”).
Există un makefile în interiorul proiectului NativeApi. Cu ajutorul lui, construiesc o bibliotecă .so pe Ununtu.
Dar când „Conectează componenta externă” 1c se blochează.
La fel, dacă construiesc folosind „build.sh” (în rădăcina proiectului).

În makefile-ul în sine schimb steag-ul de la m32 la m64, pentru că 1c și sistemul x64 însuși. (cu parametrul m32 oricum nu se conecteaza)
Iată un exemplu de apelare a VK din 1C 8.3:
Conexiune gata = ConnectExternalComponent("/home/alexeyubuntux64-20 gb/Documents/VNCOMP83/example/NativeAPI/AddInNative.so", "AddInNative", ExternalComponentType.Native); Există un articol doar pe acest subiect.
Dar, din câte văd, toate aceste puncte au fost deja luate în considerare și corectate în exemplul VNCOMPS.

Dar, în esență, este o chestiune de parametri de compilare. O componentă externă MB pe 32 de biți se conectează la un 1c pe 32 de biți în mod normal, dar am implementat-o ​​pe Ubuntu x64 1c enterprise83 8.3.5-1486 amd64. Și vreau să mă conectez cu ea pe VK.

Are cineva vreo idee despre cum să rezolv această problemă?)
Exemplul VNCOMPS ar trebui să funcționeze, dar parametrii de compilare trebuie ajustați sau platforma în sine pe care testez este incorectă.

Răspuns: Mă întreb, este posibil să scrii o componentă externă în Java?

Întrebare: Componenta externă (nativă) nu poate fi conectată


Am compilat un exemplu cu ITS, pentru sisteme pe 64 și 32 de biți.

Mă conectez așa:
Rezultat conexiune = ConnectExternalComponent(KDLLPath, "Comp", ExternalComponentType.Native); Conexiunea funcționează pe un PC, dar nu pe celălalt. Există o diferență în sistemul de operare. Unde se face conexiunea, există Win7, unde nu există Win10. În același timp, pe PC-ul unde componenta mea nu funcționează, funcționează componentele standard.

Testat pe diferite platforme (8.3.4.482, 8.3.6.2100, 8.3.11.2700, 8.3.12.1412).

Cum pot înțelege de ce nu se conectează?

Răspuns: vc_redist ați uitat?

Întrebare: 1C8 și o componentă externă cu tipul Nativ


Bună ziua.
Am o configurație BP 3.0.50.12 și dorința de a implementa cântărirea de la compania Vesy-Soft folosind UniServerAuto în ea.
Dezvoltatorii au compilat componenta în Native pentru Windows 32 și 64 și au arhivat-o cu fișierul principal. Există, de asemenea, un exemplu pentru 1C despre modul în care poate fi calculată greutatea. În ea, folosind un aspect cu date binare, această arhivă este indicată, după cum am înțeles. În exemplu, totul este în regulă: componenta este instalată, conectată, apoi se stabilește conexiunea și se citește greutatea.
Dar de îndată ce începi să-l transferi la 1C, greutatea nu este citită. Totul pare a fi scris simplu, dar nu înțeleg unde este grebla.
Cine are puțin timp - ajută, aruncă o privire cu un ochi, poate că soluția este la suprafață, dar merg undeva în locul greșit și fac lucrul greșit. Nu am fost niciodată nevoit să lucrez cu tehnologia nativă până acum...

Și în atașament este textul meu de procesare

Răspuns:

Ei bine, am vești...
Tocmai am început să văd pas cu pas în ce moment va începe să eșueze. Pentru a face acest lucru, am creat o bază de date goală și am procesat-o cu comanda. Prin analogie cu exemplul furnizorului, am transferat aspectul într-o nouă configurație - funcționează a doua oară. Acestea. prima dată nu, dar a doua oară da. Acest lucru a condus la ideea că în prelucrarea noastră ar fi totuși necesară separarea conexiunii componentei și obiectului conform diferitelor proceduri.
Apoi l-am transferat în baza mea de date cu conexiunea aspectului - funcționează. Pf, e bine.... Dar aș dori să nu fac modificări la configurație, așa că hai să mergem mai departe

Încerc să adaug aspectul la procesare. Dimensiunea sa crește imediat de la 10kb la 3mb și se observă o încetinire semnificativă a funcționării - nu este potrivit. Încep să caut să conectez componente prin dll. Acestea. în esență la fel ca de unde am început. Dar există un „DAR”: când am căutat numele dll-ului în folderul utilizatorului, am observat că acest dll se află acolo unde (după cum am înțeles) sunt adăugate dll-urile înregistrate în 1C:
C:\Utilizatori\UTILIZATOR\AppData\Roaming\1C\1cv8\ExtCompT
În consecință, nu este nevoie să folosiți calea completă către dll, puteți pur și simplu să introduceți numele acestuia:
ConnectExternalComponent(„Add1CUniServerAuto32.dll”, „UniServerAuto”, ExternalComponentType.Native);

Încerc... înjură la înregistrare, dar returnează rezultatul cântăririi. Se pare că dll-ul este deja înregistrat și asta înseamnă că trebuie doar să îl conectați. Il scot si totul merge.
Pentru a rezuma:
1. În procesarea cântăririi, procedura AtOpening a inclus conectarea unei componente externe și o conexiune la un obiect.
2. Calea către dll nu am scris-o, doar i-am indicat numele.

Acum stau și mă gândesc, când a fost instalat dll-ul în 1C? În momentul instalării software-ului? Cu greu... În momentul rulării configurației pentru dezvoltatori a acestui dll, unde este instalat când se deschide formularul? Nu știu, dar mi se pare aproape... Ce părere ai?
Și în al doilea rând, într-un loc nou, când este nevoie să instalați același terminal, ce trebuie făcut pentru ca totul să funcționeze? Ar trebui să instalez software-ul complet, să rulez configurația furnizorului pentru a verifica funcționarea și apoi (teoretic) ar trebui să funcționeze procesarea mea? Ceva este cumva complicat... Sau ar trebui să fac Instalarea componentei externe o dată în procesare după ce am instalat software-ul?

As dori sa aud parerile voastre despre aceasta chestiune...

Întrebare: External component.dll


Bună ziua tuturor.
O intrebare.
O componentă dll care funcționează excelent în 1C 7.7
1s 8.1 nu vrea să pornească deloc...
Am încercat să-l inserez în C:\Program Files\1cv81\bin\cache1c.dll
Am încercat să mă înregistrez folosind regsvr32 „C:\Program Files\1cv81\bin\cache1c.dll”
Se inregistreaza fara probleme.
Când vreau să-l accesez, primesc un mesaj de eroare:

Eroare la încărcarea componentei externe! cache1c.dll
Procedură ButtonExecutePress(Button) Încercați să încărcați o componentă externă ( „C:\Program Files\1cv81\bin\cache1c.dll”); Raport de exceptie( „Eroare la încărcarea componentei externe!”+ "cache1c.dll"); EndTempt; Încercați // Obțineți obiectul componentă. // m = Nou ("cache1c.GTMcmd"); m = New COMObject("cache1c.GTMcmd"); Raport de exceptie(); EndTempt; EndProcedure

Răspuns: E banal pana la imposibilitate...
Trebuie să întrerupeți între apeluri (milisecunde)...
Procedură ButtonExecutePress(Button) Attempt // Obține un obiect component. m = New COMObject("cache1c.GTMcmd"); Raport de exceptie( „Nu s-a putut crea obiectul component extern”); EndTempt; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Conectează(); m.Pauză(100); ...... etc
Pentru 1c 7.7 - acest lucru nu este necesar, se dovedește că manipularea este mai rapidă.

Întrebare: Lucrul cu o componentă externă cu un server 1C...


Bună ziua,

Există o componentă externă scrisă în C++, a cărei sarcină este să obțină informații dintr-o bază de date externă și să returneze rezultatul interogării sub forma unui Tabel de Valori în 1C.
Pentru a genera un tabel de valori la momentul curent, se folosește interfața IDispatch* pBackConnection, primită ca parametru în funcția Init(). În continuare, folosesc pur și simplu funcțiile 1C pentru a crea un tabel de valori, îl umplu și îl returnez la al doilea parametru din CallAsFunc (...).
Problemele au început cu trecerea la thin clients 1C. Pe partea de server, componenta externă nu pornește cu adevărat. Îl puteți rula pe partea clientului, dar totul arată ca niște cârje și iese din logica generală „client-server” în 1C. De exemplu, clientul nu înțelege ce este un tabel de valori, probleme cu variabile „globale”, sesiuni etc.
NativeAPI este și mai limitat în acest sens.
Dansul cu tamburina a dus la faptul că am putut lansa o componentă externă sub serverul 1C, DAR munca continuă până când se încearcă apelarea Invoke pe pBackConnection. Versiunea pe 64 de biți a serverului 8.2 încearcă să facă ceva până când expiră, versiunea pe 32 de biți (VK este, desigur, și pe 32 de biți) pur și simplu cade imediat.
Presupun că serverul 1C nu acceptă acest mod de operare.
În consecință, apar întrebări: este temporar sau logica 1C se rezumă la anularea acestei scheme de lucru? Dacă este imposibil să creați structuri interne 1C (un tabel de valori) în acest fel, există, în principiu, o descriere a ceea ce este un tabel de valori la nivel de sistem pentru a încerca să îl creați în C++, umpleți-l și apoi introduceți-l pur și simplu în 1C ca parametru de returnare? Aș dori măcar să obțin o direcție în care să sap.

Mulțumesc.

Răspuns:

Scrii un lucru și vrei să spui altul.
În mediul 1C, declararea variabilelor care vor fi vizibile în diferite sesiuni nu este imposibilă acum și nu exista o astfel de posibilitate înainte. O altă sesiune este un proces diferit din punct de vedere fizic.
O sesiune este o sesiune care se conectează la o bază de date, de ex. sesiune utilizator. Sau pui ceva al tău în acest concept?

Într-o singură sesiune a fost posibil, iar acum este posibil, să se declare variabile în modulul de sesiune care vor trăi și vor fi vizibile în cadrul sesiunii din diferite locuri... de fapt, sunt 4 dintre ele.
- Modul de sesiune;
- Modul de aplicare regulat;
- Modul de aplicație gestionat;
- Modul de conectare extern.

Ei bine, desigur, trebuie să vă amintiți contextul. Contextul serverului nu este direct accesibil din partea clientului și invers.

De fapt, arhitectura 1C prevede că schimbul de date se va desfășura după cum urmează:
- prin intermediul parametrilor/retururilor de proceduri/functii;
- prin intermediul așa-numiților parametri de sesiune (nu pot fi obiecte, dar efectiv vizibile în paletă).

Un tabel de pe formular... este conectat la un tabel de obiecte (procesare, de exemplu)? sau nu. Dacă da, atunci este disponibil pe server (&OnServer) și editați acolo....

Și totuși, da, Tabelul de valori nu este disponibil în UV pe partea clientului. Ei bine, asta a decis 1C.

Haide! Funcționează cu Excel, funcționează cu FSO și o grămadă de alte lucruri, dar nu funcționează aici. Prinde eroarea si analizeaza....

Atentat, încercare
...
actiunile tale
...
Excepție
str = ErrorDescription();
EndTempt;

Cu capabilitățile hardware moderne, acesta nu este deloc un argument.

Părerea ta pur personală. nu are nimic de-a face cu realitatea. Nu în nici un fel. Repet încă o dată, 1C funcționează excelent cu COM. Ambele cu in-proc și out-proc.

Vă rugăm să furnizați codul pe care îl utilizați pentru a descărca și să contactați VK.

Apropo, VK... în cazul tău, este COM sau API nativ?
Dacă COM, atunci îl înregistrați ca... prin regsvr32... cum „rezolvați” problema adâncimii de biți?

Întrebare: Instalarea unei componente externe


Vă rog să-mi spuneți cum să instalez o componentă externă. La executarea următorului cod, se afișează o eroare. În aspect, găsiți NameDecl.dll

Încercarea de a SetExternalComponent("GeneralLayout.Layout"); Excepție EndTry ;
Eroare: instalarea componentelor externe a eșuat!

Răspuns: ()
ConnectExternalComponent("GeneralLayout.Layout", "NameDecl", ExternalComponentType.Native) returnează FALSE.
New("AddIn.NameDecl.CNameDecl", Nedefinit) = (()): Tip nedefinit (AddIn.NameDecl.NameDecl)

Întrebare: dll-ul nativ nu se conectează la 1c 8.1 (fptrwin32_fz54_9_11_0_5549.dll)


Buna ziua.
1C a actualizat dll-ul pentru casele de marcat online atol pentru ffd 1.05 (inclus în procesarea de întreținere fptrwin32_fz54_9_11_0_5549.dll).
Am un vechi 1C 8.1. Spre deosebire de 8.2, nu acceptă lucrul cu echipamente externe în același mod ca 8.2, așa că mai întâi trebuie să înregistrați dll-ul în Windows și apoi să îl conectați doar la 1C?

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

Cu toate acestea, procesarea veche a fost scrisă în „tehnologie” com, iar cea nouă este nativă. În consecință, la înregistrarea regsvr32, dă o eroare:
Modulul este încărcat, dar punctul de intrare DllRegisterServer nu este găsit. Și sugerează să verificați dacă acest fișier este fișierul dll sau OCX corect.
S-a confruntat cineva cu o situație similară și cum ai ieșit? Înțeleg că 7.7 va avea o problemă similară.
Cod 8.2:

Layout = GetLayout("IntegrationComponent"); Adresă = PlaceInTemporaryStorage(Layout); ConnectExternalComponent(Adresă, „IntegrationComponent”, ExternalComponentType.Native); Driver = New ("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9");

1C 8.2:
ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
1C 8.1:
ConnectExternalComponent(<Идентификатор объекта>)
Opțiuni:
<Идентификатор объекта>(necesar)
Tip: șir. ProgID (identificatorul programatic) al obiectului component extern. Trebuie să corespundă informațiilor din baza de date de înregistrare a sistemului (Registry).
Descriere:
Conectează obiectele componente externe la 1C:Enterprise.
Nu este disponibil pe serverul 1C:Enterprise. Nu este utilizat în modulul de conectare extern.
Notă:
Componentele externe sunt compatibile cu componentele 1C:Enterprise 7.7.
Exemplu:
Atentat, încercare
ConnectExternalComponent("AddinObject.Scanner");
Raport(„Componenta pentru scanerul de coduri de bare a fost încărcată”);
Excepție
Raport ("Componenta pentru scanerul de coduri de bare nu este încărcată");
EndTempt

Există vreo modalitate de a conecta acest dll la 8.1 sau nu?

Mulțumesc!

Răspuns:

Si eu am intampinat recent aceasta problema. Nu a fost posibilă conversia la o versiune ulterioară a 1c deoarece... dll cu care funcționează această configurație pur și simplu a încetat să funcționeze și 1c s-a prăbușit cu o eroare.
Am rezolvat problema in felul urmator:
Am creat o bază de date 8.3 goală în care am procesat inițializarea componentei și apoi de la 8.1 printr-o conexiune COM am accesat baza de date creată anterior și am initializat componenta acolo. Apoi, deja în 8.1, am numit metodele acestei componente.
Desigur, aceasta este o cârjă, dar încă nu am găsit altă cale de ieșire (

Exemplu de cod 8.3:
Export de drivere variabile;
Funcția ConnectionComponentsKKT() Export
Atentat, încercare

Layout = GetLayout("IntegrationComponent");
Adresă = PlaceInTemporaryStorage(Layout);
ConnectExternalComponent(Adresă, „IntegrationComponent”, ExternalComponentType.Native);
Driver = New ("AddIn.IntegrationComponent.SMDrvFR1C20");
Rezultat = Adevărat;​

Excepție

Rezultat = Fals;​

EndTempt;
Întoarceți rezultatul
EndFunction

Exemplu de cod 8.1

Funcția CreateDriverObject(Driver) Export

Rezultat = Adevărat;

Atentat, încercare

ConnectionString="File="""Cale către baza de date""";
ComObject = New COMObject("V83.ComConnector");
Conectare = ComObject.Connect(ConnectionString);

Procesare = Connect.Processing.ConnectExternalComponent.Create();
Rezultat conexiune = Processing.ConnectionCCPComponents();
Dacă rezultatul conexiunii, atunci
Driver = Procesare.Driver;
EndIf;​

Excepție
Oricine a făcut acest lucru sau a întâlnit hotărâri similare, explică principiul însuși folosind un exemplu simplu. Se pare că totul este clar cu conectarea componentelor externe.

// Exemplu de completare a tabelului de valori TK.Clear(); Solicitare = Solicitare nouă; Query.Text = „SELECTARE | Nomenclatură.Link CUM Nomenclatură |DIN | Directory.Nomenclature AS Nomenclature"; Request Result = Request.Execute(); Selection = Request Result.Select(); While Selection.Next() Cycle Page = TK.Add(); Fill inPropertyValues(Page, Selection); EndCycle;
Ați putea folosi acest exemplu pentru a explica ce parte a codului este de obicei scoasă? Ar fi logic să eliminam partea cu cerere, dar atunci cum putem accesa baza de date din componenta externă, ocolind platforma? Nu are rost să scoți textul. Sau eliminați însăși formarea părții tabulare. Împărtășește-ți experiența cu oricine s-a confruntat cu asta.

Răspuns:Și că cuvântul „Incompatibil” înseamnă întotdeauna cuvântul „Rău”? Da, mi se pare că dacă mi-aș numi stilul „1C: Cea mai proastă programare pe acest motor de scripting care există în natură (tradusă în limbaj literar)!” și atunci probabil vor exista oameni care vor să verifice această fiară. Și arată ca un clasic: „Nu am citit Pasternak, dar nu sunt complet de acord cu el!”

Întrebare: Conectarea unei componente externe în 1s 8.3.6 și Win8


Trebuie să conectați Componenta externă vk_rs232.dll la configurația personalizată. Se pare că a fost înregistrat prin regsvr32.exe. „Se pare” pentru că am primit un mesaj că „componenta este înregistrată, dar este ceva în neregulă cu firewall-ul”. Bazându-mă pe prima jumătate a mesajului, scriu codul în 1C
AfterConnecting = New Alert Description("AfterConnectingVK", ThisForm); StartInstallingExternalComponents(,"C:\Controller\vk_rs232.dll"); StartConnectingExternalComponents(AfterConnecting,"C:\Controller\vk_rs232.dll","DLL_Scales");
și primesc eroarea că
„Instalarea unei componente externe a eșuat! Este posibil să lipsească o componentă pentru aplicația client pe care o utilizați!”.

Si acum nu inteleg:
1. Poate componenta nu este înregistrată în registry - cum pot să o verific acolo?
2. Poate că „versiunea” sa nu funcționează sub Win8, deși o am pe 32 de biți.
3. Poate că 1C în sine este prea nou, adică. În consecință, nu poate funcționa cu acest dll?
4. Ei bine, este banal - scriu ceva greșit.

Răspuns:Și toate acestea m-au condus la următoarea problemă. VneshComp este instalat, acum trebuie să-l conectați. Și aici sunt ambele opțiuni
ConnectExternalComponent("C:\Controller\vk_rs232.dll","Libra")
ConnectExternalComponent("GeneralLayout.Layout","Balanta")

Opțiune de sintaxă: După nume și locație

Sintaxă:

ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
Opțiuni:

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

Tip: șir.
Locația componentei externe.
Locația poate fi folosită:
calea către fișierul component extern de pe sistemul de fișiere (nu este disponibil pe clientul web), nu o arhivă ZIP;
numele complet calificat al aspectului care stochează datele binare sau arhiva ZIP;
URL-ul către componenta externă, ca date binare sau arhivă ZIP, într-un format similar cu GetNavigationLink.
<Имя>(necesar)

Tip: șir.
Numele simbolic al componentei externe de conectat.
Numele trebuie să respecte convențiile de denumire ale limbajului încorporat.
<Тип>(optional)

Tip: ExternalComponentType.
Tipul de componentă externă care trebuie conectată.
Nu este utilizat dacă componenta este ambalată într-o arhivă ZIP.
Descrierea opțiunii de metodă:

Conectează componente realizate folosind tehnologia nativă și COM.
Componenta poate fi stocată în baza de informații sau în configurația ca date binare sau într-o arhivă ZIP.
Pentru modurile de lansare „Thin Client” și „Web Client”, componenta trebuie mai întâi instalată utilizând metoda Instalare componente externe.
Opțiune de sintaxă: După ID

Sintaxă:

ConnectExternalComponent(<ИдентификаторОбъекта>)
Opțiuni:

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

Tip: șir.
Identificatorul obiectului component extern sub forma ProgID (Identificatorul programatic) al registrului MS Windows (de exemplu: „AddIn.Scanner”).
Trebuie să corespundă informațiilor din baza de date de înregistrare a sistemului (Registry).
Descrierea opțiunii de metodă:

Componenta trebuie implementată folosind tehnologia COM și înregistrată în registrul MS Windows.
Aceste componente sunt compatibile cu componentele 1C:Enterprise 7.7.
Atenţie! Opțiunea de metodă nu funcționează pe server și în conexiunea externă.
Valoare returnată:

Tip: boolean.
Adevărat - conexiunea a avut succes.
Descriere:

Conectează o componentă externă la 1C:Enterprise.
Componentele externe pot fi stocate în baza de informații sau în configurații ca arhivă ZIP sau ca date binare sau într-un fișier de sistem de fișiere.
Când lucrați la un client subțire și un client web, componenta trebuie să fie preinstalată.

Disponibilitate:

Thin client, client web, server, conexiune externă.
Notă:

Componentele externe pot fi implementate folosind tehnologia Native API sau COM. Componentele realizate folosind tehnologia COM sunt compatibile cu componentele 1C:Enterprise 7.7.
Clientul web poate lucra numai cu componente din baza de informații care sunt ambalate într-o arhivă.
Clientul subțire poate lucra cu componente din baza de informații, ambalate într-o arhivă și cu componente situate în sistemul de fișiere.
Clientul gros poate gestiona toate opțiunile de stocare a componentelor. În acest caz, dacă o componentă este instalată folosind metoda Instalare componentă externă, atunci componenta instalată este utilizată, iar dacă nu este instalată, componenta va fi primită în momentul conectării.
Serverul poate funcționa cu toate componentele. Componenta este stocată în cache pentru fiecare sesiune de server.
Exemplu:

Dacă ConnectExternalComponent ("AddinObject.Scanner"), atunci
Raport ("Componenta pentru scanerul de coduri de bare încărcate");
In caz contrar
Raport ("Componenta pentru scanerul de coduri de bare nu este încărcată");
endIf;

  • Tutorial

Introducere

Acest articol oferă o idee despre cum funcționează componentele externe în sistemul 1C: Enterprise.
Va fi afișat procesul de dezvoltare a unei componente externe pentru versiunea 8.2 a sistemului 1C: Enterprise, care rulează sub sistemul de operare Windows cu un mod de funcționare fișier. Această opțiune este utilizată în majoritatea soluțiilor concepute pentru întreprinderile mici. VK va fi implementat în limbajul de programare C++.

Componente externe „1C: Enterprise”

„1C: Enterprise” este un sistem extensibil. Componentele externe (EC) sunt utilizate pentru a extinde funcționalitatea sistemului. Din punctul de vedere al dezvoltatorului, un VC este un obiect extern care are proprietăți și metode și poate genera, de asemenea, evenimente pentru procesare de către sistemul 1C: Enterprise.
Componentele externe pot fi folosite pentru a rezolva o clasă de probleme care sunt dificil sau chiar imposibil de implementat în limbajul de programare integrat în 1C: Enterprise. În special, această clasă include sarcini care necesită interacțiune la nivel scăzut cu sistemul de operare, de exemplu, pentru a lucra cu echipamente specifice.
Sistemul 1C: Enterprise folosește două tehnologii pentru a crea componente externe:
  • folosind Native API
  • folosind tehnologia COM
Având în vedere restricțiile date, diferența dintre cele două tehnologii mai sus menționate este nesemnificativă, așa că vom lua în considerare dezvoltarea jocurilor video folosind API-ul nativ. Dacă este necesar, dezvoltările implementate pot fi aplicate dezvoltării de software de calculator folosind tehnologia COM și, de asemenea, cu modificări minore, aplicate pentru utilizare în sistemul 1C: Enterprise cu alte opțiuni de operare, altele decât modul de operare fișier.
Structura VK
Componenta externă a sistemului 1C: Enterprise este prezentată sub forma unei biblioteci DLL. Codul bibliotecii descrie clasa descendentă IComponentBase. Clasa creată trebuie să definească metode responsabile de implementarea funcțiilor componentei externe. Metodele anulate vor fi descrise mai detaliat mai jos pe măsură ce materialul este prezentat.

Lansarea unui demo VK

Sarcină:
  1. Asamblați o componentă externă furnizată cu un abonament ITS și destinată să demonstreze principalele capacități ale mecanismului de componentă externă în 1C
  2. Conectați componenta demo la configurația 1C
  3. Asigurați-vă că funcțiile declarate funcționează corect
Compilare
VK-ul demo este situat pe discul de abonament ITS în directorul „/VNCOMP82/example/NativeAPI”.
Pentru a construi VC demonstrativ vom folosi Microsoft Visual Studio 2008. Alte versiuni ale acestui produs nu acceptă formatul de proiect Visual Studio utilizat.


Deschideți proiectul AddInNative. În setările proiectului, includem directorul cu fișierele de antet necesare pentru a construi proiectul. În mod implicit, acestea sunt localizate pe discul ITS din director /VNCOMP82/include.
Rezultatul build-ului este fișierul /bind/AddInNative.dll. Aceasta este biblioteca compilată pentru conectarea la configurația 1C.
Se conectează configurația VK la 1C
Să creăm o configurație 1C goală.
Mai jos este codul pentru modulul aplicației gestionate.
variabila DemoComp; Procedură la pornirea sistemului() Conectați Componenta externă("...\bind\AddInNative.dll", "DemoVK", Tipul componentei externe.Native); DemoComp = New ("AddIn.DemoVK.AddInNativeExtension"); EndProcedure
Dacă nu a fost raportată nicio eroare la pornirea configurației 1C, atunci VK-ul a fost conectat cu succes.
Ca urmare a executării codului de mai sus, un obiect apare în vizibilitatea globală a configurației DemoComp, care are proprietăți și metode care sunt definite în codul componentei externe.
Demonstrarea funcționalității încorporate
Să verificăm funcționalitatea demo-ului VK. Pentru a face acest lucru, să încercăm să setăm și să citim unele proprietăți, să apelăm unele metode VK și, de asemenea, să primim și să procesăm mesajul VK.
Documentația furnizată pe discul ITS precizează următoarea funcționalitate a VC-ului demo:
  1. Gestionarea stării obiectelor componente
    Metode: Porniți, Opriți
    Proprietăți: Inclus
  2. Control cu ​​temporizator
    În fiecare secundă, componenta trimite un mesaj către sistemul 1C: Enterprise cu parametri Componentă, Temporizatorși o linie de contor al ceasului de sistem.
    Metode: StartTimer, StopTimer
    Proprietăți: Există un cronometru
  3. Metodă ShowInStatusLine, care afișează textul transmis metodei ca parametri în linia de stare
  4. Metodă Încarcă imagine. Încarcă o imagine din fișierul specificat și o transferă în sistemul 1C: Enterprise sub formă de date binare.
Să ne asigurăm că aceste funcții funcționează. Pentru a face acest lucru, rulați următorul cod:
variabila DemoComp; Procedura la pornirea sistemului() ConnectExternalComponent(...); DemoComp = New ("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Disable(); Raport (DemoComp.Activat); DemoComp.Enable(); Raport (DemoComp.Activat); DemoComp.StartTimer(); Sfârșitul procedurii Procesare externă a evenimentelor (Sursă, Eveniment, Date) Raport (Sursă + " " + Eveniment + " " + Date); EndProcedure
Rezultatul rulării configurației este afișat în imagine


Panoul „Mesaje” afișează rezultatele apelurilor de metodă DemoComp.Disable()Și Demo.Comp.Enable(). Rândurile ulterioare din același panou conțin rezultatele procesării mesajelor primite de la VK - Sursă, EvenimentȘi Date respectiv.

Nume personalizat de componentă externă

Sarcină: Schimbați numele componentei externe într-unul arbitrar.
Secțiunea anterioară a folosit identificatorul AddInNativeExtension, al cărui sens nu a fost explicat. În acest caz AddInNativeExtension- acesta este numele extensiei.
Codul VK definește o metodă RegisterExtensionAs, returnând numele sistemului 1C: Enterprise, care este necesar pentru înregistrarea ulterioară a VK-ului în sistem. Se recomandă specificarea unui identificator care dezvăluie într-o oarecare măsură esența componentei externe.
Iată codul complet al metodei RegisterExtensionAs cu numele extensiei schimbat:
bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) ( wchar_t *wsExtension = L"SomeName"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* dest = 0; if (m_iMemory) ( if(m_iMemory) ( if(m_iMemory) ((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, iActualSize) returnează false;
În exemplul dat, numele VK este schimbat în SomeName. Apoi, atunci când vă conectați VK, trebuie să specificați un nume nou:
DemoComp = New("AddIn.DemoVK.SomeName");

Extinderea listei de proprietăți VK

Sarcină:
  1. Studiați implementarea proprietăților VK
  2. Adăugați o proprietate de citire/scriere de tip șir
  3. Adăugați o proprietate șir de citire/scriere care stochează tipul de date al ultimului set de proprietăți. Nu se întreprinde nicio acțiune la setarea valorii proprietății

Pentru a determina proprietățile componentei care se creează, dezvoltatorul trebuie să implementeze următoarele metode în codul bibliotecii AddInNative.cpp:
GetNProps
Returnează numărul de proprietăți ale acestei extensii, 0 dacă nu există proprietăți
FindProp
Returnează numărul de serie al proprietății al cărei nume este trecut în parametri
GetPropName
Returnează numele proprietății după numărul de serie și prin identificatorul de limbă transmis
GetPropVal
Returnează valoarea proprietății cu numărul ordinal specificat
SetPropVal
Setează valoarea proprietății cu numărul ordinal specificat
IsPropReadable
Returnează indicatorul de lizibilitate al proprietății cu numărul de secvență specificat
IsPropWritable
Returnează indicatorul de scriere al proprietății cu numărul de secvență specificat


Să luăm în considerare implementarea metodelor de clasă de mai sus CAddInNative.
În VC demonstrativ, sunt definite 2 proprietăți: InclusȘi Există un cronometru (Este activatȘi IsTimerPresent).
În domeniul global al codului bibliotecii, sunt definite două matrice:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent"); static wchar_t *g_PropNamesRu = (L"Activat", L"Există un temporizator");
care stochează nume de proprietate în limba rusă și engleză. În fișierul antet AddInNative.h enumerarea este definită:
Enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Întotdeauna ultimul );
ePropIsEnabledȘi ePropIsTimerPresent, respectiv având valorile 0 și 1, sunt folosite pentru a înlocui numerele de serie ale proprietăților cu identificatori semnificativi. ePropLast, care are valoarea 2, este folosit pentru a obține numărul de proprietăți (folosind metoda GetNProps). Aceste nume sunt folosite numai în codul componentei și nu sunt disponibile din exterior.
Metodele FindProp și GetPropName efectuează căutări în matrice g_PropNamesȘi g_PropNamesRu.
Pentru a stoca valorile câmpurilor din modulul bibliotecă, clasa CAddInNative are proprietăți care stochează valoarea proprietăților componente. Metode GetPropValȘi SetPropVal returnați și setați valoarea acestor proprietăți în consecință.
Metode IsPropReadableȘi IsPropWritableși întoarce-te Adevărat sau fals, în funcție de numărul ordinal transmis al proprietății în conformitate cu logica aplicației.
Pentru a adăuga o proprietate personalizată, trebuie să:

  1. Adăugați numele proprietății care este adăugată la matrice g_PropNamesȘi g_PropNamesRu(fişier AddInNative.cpp)
  2. A lista Recuzită(fişier AddInNative.h) inainte de ePropLast adăugați un nume care identifică în mod unic proprietatea adăugată
  3. Organizați memoria pentru stocarea valorilor proprietăților (creați câmpuri componente ale modulului care stochează valorile corespunzătoare)
  4. Faceți modificări metodelor GetPropValȘi SetPropVal pentru a interacționa cu memoria alocată în pasul anterior
  5. În conformitate cu logica aplicației, efectuați modificări metodelor IsPropReadableȘi IsPropWritable
Punctele 1, 2, 5 nu au nevoie de explicații. Detalii despre implementarea acestor pași pot fi găsite studiind anexa la articol.
Să dăm nume proprietăților de testare TestȘi Verificare tip respectiv. Apoi, ca rezultat al pasului 1, avem:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"); static wchar_t *g_PropNamesRu = (L"Activat", L"Există un temporizator", L"Test", L"Verificare tip");
Transfer Recuzită va arata ca:
Enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Întotdeauna ultimul);
Pentru a simplifica semnificativ codul, vom folosi STL C++. În special, pentru lucrul cu șiruri WCHAR, haideți să conectăm biblioteca wstring.
Pentru a salva valoarea unei metode Test, definim în clasă CAddInNativeîn domeniul privat:
testul șirurilor1;
Pentru a transfera parametrii de șir între componentele 1C: Enterprise și externe, se folosește managerul de memorie 1C: Enterprise. Să aruncăm o privire mai atentă la munca lui. Funcțiile sunt folosite pentru a aloca și, respectiv, elibera memorie AllocMemoryȘi Memorie libera, definit în dosar ImemoryManager.h. Dacă este necesar să se transmită un parametru șir sistemului 1C: Enterprise, componenta externă trebuie să aloce memorie pentru acesta apelând funcția AllocMemory. Prototipul său arată astfel:
virtual bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0;
Unde pMemorie- adresa pointerului în care va fi plasată adresa zonei de memorie alocată,
ulCountByte- dimensiunea zonei de memorie alocată.
Un exemplu de alocare de memorie pentru un șir:
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);
Pentru confortul lucrului cu tipuri de date șir, vom descrie funcția wstring_to_p. Primește un șir wstring ca parametru. Rezultatul funcției este o structură umplută tVariant. Codul funcției:
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) * sizeof(WCHAR_T)); memcpy(t1, str.c_str(), (str.length()+1) * sizeof(WCHAR_T)); returneaza adevarat)
Apoi, secțiunea de caz corespunzătoare a instrucțiunii switch a metodei GetPropVal va lua forma:
caz ePropTest1: wstring_to_p(test1, pvarPropVal); pauză;
Metodă SetPropVal:
caz ePropTest1: dacă (TV_VT(varPropVal) != VTYPE_PWSTR) returnează fals; test1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); pauză;
Pentru a implementa a doua proprietate, definim un câmp de clasă CaddInNative
uint8_t last_type;
în care vom salva tipul ultimei valori transferate. Pentru a face acest lucru, adăugați comanda la metoda CaddInNative::SetPropVal:
ultimul_tip = TV_VT(varPropVal);
Acum, când solicităm citirea valorii celei de-a doua proprietăți, vom returna valoarea ultimul_tip, ceea ce necesită sarcina desemnată.
Să verificăm funcționalitatea modificărilor făcute.
Pentru a face acest lucru, să prezentăm aspectul configurației 1C după cum urmează:
variabila DemoComp; Procedură la pornirea sistemului() Conectare componentă externă("...", "DemoVK", Tip componentă externă.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.TypeCheck = 1; Raport(String(DemoComp.TypeCheck)); DemoComp.Test = "Vasya"; Raport(String(DemoComp.Test)); DemoComp.Test = "Petya"; Raport(String(DemoComp.Test)); Raport(String(DemoComp.TypeCheck)); EndProcedure
Ca urmare a lansării, vom primi o secvență de mesaje:
3
Vasia
Petru
22

Al doilea și al treilea mesaj sunt rezultatul citirii proprietății stabilite în pasul anterior. Primul și al doilea mesaj conțin codul de tip al ultimului set de proprietăți. 3 corespunde unei valori întregi, 22 unei valori șir. Corespondența tipurilor și a codurilor acestora se stabilește în dosar tipuri.h, care se află pe discul ITS.

Extinderea listei de metode

Sarcină:
  1. Extindeți funcționalitatea componentei externe cu următoarea funcționalitate:
  2. Explorați modalități de implementare a metodelor componentelor externe
  3. Adăugați o metodă de funcție Funcția 1, care ia două șiruri de caractere („Parameter1” și „Parameter2”) ca parametru. Rezultatul este un șir de genul: „Verificare. Parametrul 1, Parametrul 2"
  4. Asigurați-vă că modificările pe care le faceți funcționează.

Pentru a defini metodele componentei care se creează, dezvoltatorul trebuie să implementeze următoarele metode în codul bibliotecii AddInNative:
GetNMethods, FindMethod, GetMethodName
Conceput pentru a obține numărul corespunzător de metode, căutați numărul și numele metodei. Similar cu metodele corespunzătoare pentru proprietăți
GetNParams
Returnează numărul de parametri ai metodei cu numărul de secvență specificat; dacă o metodă cu acest număr este absentă sau nu are parametri, returnează 0
GetParamDefValue
Returnează valoarea implicită a parametrului specificat al metodei specificate
HasRetVal
Returnează indicatorul dacă metoda cu valoarea de returnare ordinală specificată are o valoare returnată: true pentru metodele cu o valoare returnată și fals in caz contrar
CallAsProc
fals, apare o eroare de rulare și execuția modulului 1C: Enterprise este încheiată. Memoria pentru matricea de parametri este alocată și eliberată de 1C: Enterprise.
CallAsFunc
Execută metoda cu numărul de ordine specificat. Dacă metoda revine fals, apare o eroare de rulare și execuția modulului 1C: Enterprise este încheiată. Memoria pentru matricea de parametri este alocată de 1C: Enterprise. Dacă valoarea returnată este un șir sau un tip de date binare, componenta alocă memorie cu funcția AllocMemory manager de memorie, scrie acolo datele și stochează această adresă în câmpul corespunzător al structurii. 1C: Întreprinderea va elibera această memorie prin apel Memorie libera.
O descriere completă a metodelor, inclusiv o listă de parametri, este descrisă în detaliu în documentația furnizată pe discul ITS.
Să ne uităm la implementarea metodelor descrise mai sus.
În codul componentelor, sunt definite două matrice:
static wchar_t *g_MethodNames = (L"Activare", L"Dezactivare", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"); static wchar_t *g_MethodNamesRu = (L"Activare", L"Dezactivare", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage");
si enumerare:
Metode enum ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Întotdeauna ultimul);
Sunt folosite în funcții GetNMethods, FindMethodȘi GetMethodName, prin analogie cu descrierea proprietăților.
Metode GetNParams, GetParamDefValue, HasRetVal comutatorul instrumentului, în funcție de parametrii trecuți și de logica aplicației, returnează valoarea necesară. Metodă HasRetValîn codul său are o listă de numai metode care pot returna un rezultat. Pentru ei se întoarce Adevărat. Pentru toate metodele de oțel returnări fals.
Metode CallAsProcȘi CallAsFunc conţin cod executabil direct al metodei.
Pentru a adăuga o metodă care poate fi apelată doar ca funcție, trebuie să faceți următoarele modificări la codul sursă al componentei externe:
  1. Adăugați numele metodei la matrice g_MethodNamesȘi g_MethodNamesRu(fişier AddInNative.cpp)
  2. Adăugați un identificator de metodă semnificativ la enumerarea Metode (fișier AddInNative.h)
  3. Efectuați modificări la codul funcției GetNParams conform logicii programului
  4. Dacă este necesar, faceți modificări la codul metodei GetParamDefValue, dacă doriți să utilizați valorile implicite ale parametrilor metodei.
  5. Efectuați modificări ale funcției HasRetVal
  6. Faceți modificări în logica funcțiilor CallAsProc sau CallAsFunc, plasând acolo codul executabil direct al metodei
Să prezentăm matricele g_MethodNamesȘi g_MethodNamesRu, precum și listare Metode la forma:
static wchar_t *g_MethodNames = (L"Activare", L"Dezactivare", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"); static wchar_t *g_MethodNamesRu = (L"Activare", L"Dezactivare", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test");

Metode de enumerare ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Întotdeauna ultimul);
Să edităm funcția GetNProps astfel încât să returneze numărul de parametri ai metodei „Test”:
long CAddInNative::GetNParams(const long lMethodNum) ( switch(lMethodNum) (case eMethShowInStatusLine: return 1; case eMethLoadPicture: return 1; case eMethTest: return 2; implicit: return 0; ) return 0; )
Să facem modificări în funcție:
bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) ( ​​​​TV_VT(pvarParamDefValue)= VTYPE_EMPTY; switch(lMethodNum) (case eMethEnable:case eMeth Timer: caz eMethStopTimer: caz eMethTest : // Nu există valori ale parametrilor implicit break: return false;
Mulțumită liniei adăugate
caz eMethTest:
dacă lipsesc unul sau mai multe argumente, parametrii corespunzători vor avea o valoare goală ( VTYPE_EMPTY). Dacă aveți nevoie de o valoare implicită pentru un parametru, ar trebui să o setați în secțiune eMethTest instrucțiunea de comutare a funcției CAddInNative::GetParamDefValue.
Deoarece metoda Test poate returna o valoare, trebuie să faceți modificări codului funcției HasRetVal:
bool CAddInNative::HasRetVal(const long lMethodNum) ( switch(lMethodNum) (case eMethLoadPicture: case eMethTest: return true; default: return false; ) return false; )
Și adăugați codul executabil al metodei la funcție CallAsFunc:
bool CAddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) (... std::wstring s1, s2; switch(lMethodNum) (case eMethLoadPicture: ...T break; if (!lSizeArray || !paParams) return s1 = (paParams) -> pwstrVal = (paParams+1) -> pwstring_to_p(std::wstring(s1+s2), pvarRetValue ; ;
Să compilam componenta și să aducem codul de configurare la forma:
variabila DemoComp; Procedură la pornirea sistemului() Conectare componentă externă("...", "DemoVK", Tip componentă externă.Native); DemoComp = New("AddIn.DemoVK.SomeName"); lane = DemoComp.Test ("Bună ziua," "Lumea!"); Raport (per); EndProcedure
După lansarea configurației, vom primi mesajul: „Hello, World!”, care indică faptul că metoda a funcționat cu succes.

Temporizator

Sarcină:
  1. Studiați implementarea temporizatorului în demo VK
  2. Modificați metoda „StartTimer” adăugând posibilitatea de a trece în parametri intervalul de răspuns al temporizatorului (în milisecunde)
  3. Asigurați-vă că modificările pe care le faceți funcționează.

În WinAPI, puteți folosi mesajul pentru a lucra cu timpul WM_TIMER. Acest mesaj va fi trimis programului dumneavoastră la intervalul de timp pe care l-ați setat la crearea cronometrului.
Pentru a crea un cronometru, utilizați funcția SetTimer:
UINT SetTimer(HWND hWnd, // descriptor de fereastră UINT nIDevent, // identificator timer (număr) UINT nElapse, // întârziere TIMERPROC lpTimerFunc); // pointer către funcție
Sistemul de operare va trimite un mesaj WM_TIMERîn program cu intervalul specificat în argument nElapse(în milisecunde). În ultimul parametru puteți specifica o funcție care va fi executată de fiecare dată când se declanșează cronometrul. Antetul acestei funcții ar trebui să arate astfel (numele poate fi orice):
void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Să luăm în considerare implementarea unui cronometru în VC demonstrativ.
Deoarece luăm în considerare procesul de dezvoltare a unei componente externe pentru familia de sisteme de operare Windows, nu vom lua în considerare implementarea temporizatorului în alte sisteme de operare. Pentru sistemul de operare GNU/Linux, în special, implementarea va diferi în sintaxa funcției SetTimerȘi TimerProc.
Codul executabil apelează metoda SetTimer, căruia i se trece funcția MyTimerProc:
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
ID-ul temporizatorului creat este plasat într-o variabilă m_uiTimer pentru a putea fi dezactivat ulterior.
Funcţie MyTimerProc după cum urmează:
VOID CALLBACK MyTimerProc(HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime // time system time) (dacă (!pAsyncEvent) return; wchar_t *who = L "ComponentNative", *what = L"Timer"; wchar_t *wstime = new wchar_t if (wstime) ( wmemset(wstime, 0, TIME_LEN); ::_ultow(dwTime, wstime, 10); pAsyncEvent->ExternalEvent(who); , ce, wstime);
Esența funcției este că metoda este numită Eveniment extern, care trimite un mesaj către sistemul 1C: Enterprise.
Pentru a extinde funcționalitatea metodei StartTimer Să facem următoarele:
Modificarea codului metodei GetNParams astfel încât să fie pentru metodă eMethStartTimer valoarea returnată 1:
caz eMethStartTimer: return 1;
Iată codul metodei CallAsProc la forma:
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;
Acum să verificăm funcționalitatea. Pentru a face acest lucru, vom scrie codul în modulul aplicației gestionate al configurației:
variabila DemoComp; Procedură la pornirea sistemului() Conectare componentă externă("...", "DemoVK", Tip componentă externă.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.StartTimer(2000); EndProcedure
După pornirea configurației, programul va primi mesaje la intervale de 2 secunde, ceea ce indică faptul că temporizatorul funcționează corect.

Interacțiune cu sistemul 1C: Enterprise

Pentru a interacționa între componenta externă și sistemul 1C: Enterprise, metodele clasei IAddInDefBase, descrise în fișier AddInDefBase.h. Le enumerăm pe cele mai frecvent utilizate:
Generarea unui mesaj de eroare
virtual bool ADDIN_API AddError(unsigned short wcode, const WCHAR_T* source, const WCHAR_T* descr, long code)
wcode, cod- coduri de eroare (o listă de coduri de eroare cu descrieri poate fi găsită pe discul ITS)
sursă- sursa erorii
descr- descrierea erorii
Trimiterea unui mesaj către sistemul 1C: Enterprise
virtual bool ADDIN_API ExternalEvent(WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;
wszSource- sursa mesajului
wszMessage- Mesaj text
wszData- datele transmise
Interceptarea mesajelor este efectuată prin procedura de procesare externă a evenimentelor
Înregistrarea unei componente externe în sistemul 1C: Enterprise
virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszProfileName- denumirea componentei.
Aceste metode sunt suficiente pentru o interacțiune completă între VK și 1C. Pentru a primi date de către o componentă externă de la sistemul 1C: Enterprise și invers, componenta externă trimite un mesaj special, care la rândul său este interceptat de sistemul 1C și, dacă este necesar, apelează metodele componentei externe pentru a transmite date înapoi. .

tVariant tip de date

La schimbul de date între componenta externă și sistemul 1C: Enterprise, este utilizat tipul de date tVariant. Este descris în fișierul types.h, care poate fi găsit pe discul ITS:
struct _tVariant ( _ANONYMOUS_UNION union ( int8_t i8Val; int16_t shortVal; int32_t lVal; int intVal; unsigned int uintVal; int64_t llVal; uint8_t ui8Val; uint16_t ushortVal; uint32_t ult32_t; uint32_t; bVal; wchar_t struct _tVal; struct tm tmVal; ANT_NAME_1 ; matrice dimensională în pvarVal TYPEVAR vt);
Tip tVariant este o structură care include:
  • amestec (unire) destinat direct stocării datelor
  • identificatorul tipului de date
În general, lucrul cu variabile de tip tVariant are loc conform următorului algoritm:
  1. Determinarea tipului de date stocate în prezent într-o variabilă
  2. Accesați câmpul de amestec corespunzător pentru a accesa direct datele
Folosind tipul tVariant simplifică semnificativ interacțiunea dintre sistemul 1C: Enterprise și componentele externe

Aplicație

Directorul „exemple” conține exemple pentru articol
exemple/1 - lansați componenta demo
exemple/2 - demonstrarea extinderii listei de proprietăți
exemple/3 - demonstrarea extinderii listei de metode
Fiecare director conține un proiect VS 2008 și o configurație 1C gata făcută.