Lansări noi „1C: Managementul comerțului”: actualizare fără dezvoltare. Utilizarea componentelor COM externe (.dll) sau a oricăror metode client în sarcinile programate ale bazei de server

O nouă versiune de configurare a fost lansată pe 23 octombrie „1C: Managementul comerțului”... Încă o dată, actualizarea a inclus modificări în VETIS, EGAIS, iar funcționalitatea generală a configurației aproape că nu a fost afectată în niciun fel.

Ce sa schimbat?

Privind structura modificărilor incluse în cea mai recentă versiune de configurare „1C: Managementul comerțului”, apoi mai mult de jumătate este o actualizare pentru EGAIS, VETIS și doar câteva rânduri din descrierea lansării sunt dedicate extinderii funcționalității produs software care nu sunt prevăzute de niciun act legislativ.

Modificări în secțiuni:

    v vânzări cu amănuntul a adăugat suport pentru citirea unui cod de bare bidimensional de accize și timbre speciale federale ale unei noi mostre, care conține un identificator digital al EGAIS;

    integrare îmbunătățită cu sistemul de control veterinar (VETIS);

    schimb îmbunătățit cu sistemul EGAIS;

    au adăugat noi caracteristici ale serviciului de schimb documente electronice;

    au fost aduse îmbunătățiri în ceea ce privește 1C: Serviciul de rețea de afaceri;

    integrare îmbunătățită cu Yandex.Checkout.

În ceea ce privește funcționalitatea generală, aici au existat mai multe modificări la blocul de planificare și trezorerie. Și în mod tradițional adăugări constante la contabilitatea TVA.

În același timp, ultima versiune curentă a configurației „1C: Managementul comerțului” nu este o excepție - acum dezvoltarea configurației pentru operațional contabilitatea mergeîn principal pe calea închiderii sarcinilor care apar ca urmare a reglementare legislativă in domeniul comertului. Este logic ca suportul cerințelor de reglementare să devină mai prioritară și, în cele din urmă, să determină direcția de dezvoltare a soluției software în ansamblu.

Contabilitatea operațională devine reglementată?

Configurație tradițională „1C: Managementul comerțului” utilizate pentru automatizarea contabilității operaționale. Mai mult, împreună cu „1C: Contabilitate” era obișnuit să se „încarce” toate cerințele pentru modificarea funcționalității standard în „1C: UT”, pentru a menține capacitatea de a actualiza programul de contabilitate cu un efort minim.

Având în vedere volumul documentelor de reglementare pentru contabilitatea operațională în comerț și reflectarea acestor cerințe în configurația standard, există motive pentru o abordare mai atentă a modificării funcționalității standard a configurației de tranzacționare. De exemplu, problemele cu schimbul cu sistemul Mercur pot, dacă nu paralizează activitățile unui număr de întreprinderi, atunci cel puțin pot duce la perioade lungi de nefuncționare.

Ca una dintre opțiunile de soluție, putem lua în considerare utilizarea mecanismului de extensie, mai ales că 1C este implicat activ în această funcționalitate. Desigur, această abordare va necesita muncă suplimentară din partea dezvoltatorilor. Dar acesta este cel mai bun mod de a susține modificările în configurațiile moderne.

Distribuția funcționalității între configurația tipică va fi mai radicală. „1C: Managementul comerțului”și un fel de sisteme externe contabile sau analitice. Din nou, 1C a făcut suficient pentru a rezolva în mod eficient acest tip de sarcini la nivel de platformă.

În orice caz, acum, atunci când proiectați sisteme de contabilitate corporativă și distribuiți funcționalitatea între configurații, trebuie să aveți în vedere: este posibil să puteți actualiza „1C: Managementul comerțului” va trebui, dacă nu la fel de des ca „1C: Contabilitate”, atunci cu siguranță nu e de 1-2 ori pe an, așa cum au făcut mulți până acum.

  • Tutorial

Introducere

Acest articol oferă o idee despre activitatea componentelor externe în sistemul 1C: Enterprise.
Procesul de dezvoltare a unei componente externe pentru sistemul 1C: Enterprise versiunea 8.2, care rulează sub sistemul de operare al familiei Windows cu opțiunea fișierului muncă. Majoritatea soluțiilor pentru afaceri mici folosesc această opțiune. VK va fi implementat în limbajul de programare C++.

Componente externe „1C: Enterprise”

1C: Enterprise este un sistem extensibil. Pentru a extinde funcționalitatea sistemului, sunt utilizate componente externe (VC). Din punctul de vedere al dezvoltatorului, VK este un obiect extern care are proprietăți și metode și poate genera și 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 hardware specific.
Sistemul 1C: Enterprise folosește două tehnologii pentru a crea componente externe:
  • folosind Native API
  • folosind tehnologia COM
Cu restricțiile date între cele două tehnologii de mai sus, diferența este nesemnificativă, așa că vom lua în considerare dezvoltarea VK folosind API-ul nativ. Dacă este necesar, dezvoltările implementate pot fi utilizate pentru dezvoltarea VC folosind tehnologia COM și, de asemenea, cu modificări minore, aplicate pentru utilizare în sistemul 1C: Enterprise cu alte opțiuni de lucru, altele decât modul fișier.
Structura VK
Componenta externă a sistemului 1C: Enterprise este prezentată sub forma unei biblioteci DLL. Codul bibliotecii descrie clasa derivată IComponentBase. În clasa care este creată trebuie definite metode care sunt responsabile de implementarea funcțiilor componentei externe. Metodele de suprascriere vor fi descrise mai detaliat mai târziu în cursul materialului.

Lansare Demo VK

Sarcină:
  1. Asamblați o componentă externă furnizată cu un abonament ITS și concepută pentru a demonstra principalele capacități ale mecanismului componentelor externe în 1C
  2. Conectați componenta demo la configurația 1C
  3. Asigurați-vă că funcțiile declarate funcționează corect
Compilare
Demo VK se află pe discul de abonament ITS în directorul / VNCOMP82 / example / NativeAPI.
Pentru a construi un VK 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 antet necesare pentru construirea proiectului. În mod implicit, acestea sunt localizate pe discul ITS din director / VNCOMP82 / include.
Rezultatul construcției este un fișier /bind/AddInNative.dll... Aceasta este biblioteca compilată pentru conectarea la configurația 1C.
Conexiune VK la configurația 1C
Să creăm o configurație 1C goală.
Mai jos este codul pentru un modul de aplicație gestionat.
schimba DemoComp; Procedura de pornire a sistemului () Atașați ExternalComponent ("... \ bind \ AddInNative.dll", "DemoVK", ExternalComponentType.Native); DemoComp = Nou ("AddIn.DemoVK.AddInNativeExtension"); Sfârșitul procedurii
Dacă nu a fost raportată nicio eroare la pornirea configurației 1C, atunci VC-ul a fost conectat cu succes.
Ca rezultat al executării codului de mai sus, apare un obiect în vizibilitatea configurației globale DemoComp care are proprietăți și metode care sunt definite în codul componentei externe.
Demonstrarea funcționalității încorporate
Să verificăm performanța demo-ului VK. Pentru a face acest lucru, vom încerca să setăm și să citim unele proprietăți, să apelăm unele metode VK și, de asemenea, să primim și să procesăm un mesaj VK.
Documentația furnizată pe discul ITS precizează următoarea funcționalitate a VC-ului demo:
  1. Managementul stării componentelor
    Metode: Aprinde, Opriți
    Proprietăți: Pornit
  2. Control cu ​​temporizator
    În fiecare secundă, componenta trimite un mesaj către sistemul 1C: Enterprise cu parametri Componentă, Temporizatorși o linie a contorului ceasului sistemului.
    Metode: StartTimer, Opriți cronometrul
    Proprietăți: Există un cronometru
  3. Metodă ShowInStatusRow care afișează în bara de stare textul trecut metodei ca parametri
  4. Metodă Descărcați imaginea... Încarcă o imagine din fișierul specificat și o transferă în sistemul 1C: Enterprise ca date binare.
Să ne asigurăm că aceste funcții funcționează. Pentru a face acest lucru, vom executa următorul cod:
schimba DemoComp; Procedura de pornire a sistemului () Conectați componenta externă (...); DemoComp = Nou ("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Turn off (); Raport (DemoComp.Inclus); DemoComp.Include (); Raport (DemoComp.Inclus); DemoComp.StartTimer (); EndProcedure Procedure ExternalEvent Handling (Sursă, Eveniment, Date) Raport (Sursă + "" + Eveniment + "" + Date); Sfârșitul procedurii
Rezultatul rulării configurației este afișat în imagine


Panoul „Mesaje” afișează rezultatele apelurilor de metodă DemoComp.Turn off ()și Demo.Comp.Include ()... Rândurile ulterioare de pe același panou conțin rezultatele procesării mesajelor primite de la VK - O sursă, Evenimentși Date respectiv.

Un nume arbitrar pentru o 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 clarificat. În acest caz AddInNativeExtension este numele extensiei.
Codul VK definește metoda RegisterExtensionAs, care returnează numele sistemului 1C: Enterprise, care este necesar pentru înregistrarea ulterioară a VK în sistem. Se recomandă precizarea unui identificator care într-o anumită măsură dezvăluie esența componentei externe.
Iată codul complet al metodei RegisterExtensionAs cu numele schimbat al extensiei:
bool CAddInNative :: RegisterExtensionAs (WCHAR_T ** wsExtensionName) (wchar_t * wsExtension = L "SomeName"; int iActualSize = :: wcslen (wsExtension) + 1; WCHAR_T * dest = 0; if (m_iMemory) (if (mloc->_) (void **) wsExtensionName, iActualSize * sizeof (WCHAR_T))):: convToShortWchar (wsExtensionName, wsExtension, iActualSize); return true;) return false;)
În exemplul de mai sus, numele VK a fost schimbat în SomeName... Apoi, atunci când conectați VK, trebuie să specificați un nume nou:
DemoComp = Nou ("AddIn.DemoVK.SomeName");

Extinderea listei de proprietăți VK

Sarcină:
  1. Examinați implementarea proprietăților VK
  2. Adăugați o proprietate șir de citire/scriere
  3. Adăugați o proprietate șir de citire/scriere care stochează tipul de date al ultimului set de proprietăți. Când setați valoarea proprietății, nu se întreprinde nicio acțiune

Pentru a defini 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 ordinal al proprietății, al cărui nume este transmis în parametri
GetPropName
Returnează numele proprietății după ordinal și după identificatorul de limbă transmis
GetPropVal
Returnează valoarea proprietății cu ordinalul specificat
SetPropVal
Setează valoarea proprietății cu ordinalul specificat
IsPropReadable
Returnează indicatorul de lizibilitate al proprietății cu ordinalul specificat
IsPropWritable
Returnează indicatorul de scriere al proprietății cu ordinalul specificat


Luați în considerare implementarea metodelor de clasă de mai sus CAddInNative.
În demonstrația VK, sunt definite 2 proprietăți: Pornitș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 „Au cronometru”);
care stochează nume rusești și engleze ale proprietăților. Î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 secvență ale proprietăților cu identificatori semnificativi. ePropLast cu o valoare de 2 este folosit pentru a obține numărul de proprietăți (folosind metoda GetNProps). Aceste nume sunt folosite numai în cadrul codului componentei și nu sunt accesibile 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 componentei. 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 de secvență de proprietate transmis în conformitate cu logica aplicației.
Pentru a adăuga o proprietate arbitrară, trebuie să:

  1. Adăugați numele proprietății care urmează să fie adăugate în matrice g_PropNamesși g_PropNamesRu(fişier AddInNative.cpp)
  2. La enumerare Recuzită(fişier AddInNative.h) față 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 de module ale componentei 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 se explică de la sine. Detaliile implementării acestor pași pot fi găsite în anexa la articol.
Să numim proprietățile testului Testși Verificați tipul respectiv. Apoi, ca urmare a paragrafului 1, avem:
static wchar_t * g_PropNames = (L "IsEnabled", L "IsTimerPresent", L "Test", L "TestType"); static wchar_t * g_PropNamesRu = (L „Activat”, L „Au cronometru”, L „Test”, L „Tip de verificare”);
Enumerare Recuzită va arata ca:
Enum Props (ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Întotdeauna ultimul);
Pentru a simplifica foarte mult codul, vom folosi STL C++. În special, pentru lucrul cu șiruri WCHAR, conectați biblioteca wstring.
Pentru a stoca valoarea metodei Test, definim în clasă CAddInNativeîn domeniul privat:
testul șirurilor1;
Pentru a transfera parametrii șir între componentele 1C: Enterprise și externe, se folosește 1C: Manager de memorie Enterprise. Să luăm în considerare munca sa mai detaliat. Pentru a aloca și, respectiv, a elibera memorie, utilizați funcțiile AllocMemoryși Memorie libera definite în fișier 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)); val -> pstrVal = t1; val -> strLen = str.length () ; 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 transmise. Pentru a face acest lucru, adăugați comanda la metoda CaddInNative :: SetPropVal:
last_type = TV_VT (varPropVal);
Acum, când solicităm citirea valorii celei de-a doua proprietăți, vom returna valoarea ultimul_tip, care este cerut de sarcina desemnată.
Să verificăm performanța modificărilor făcute.
Pentru asta dăm aspect Configurații 1C la formular:
schimba DemoComp; Procedura de pornire a sistemului () Conectați ExternalComponent ("...", "DemoVK", ExternalComponentType.Native); DemoComp = Nou ("AddIn.DemoVK.SomeName"); DemoComp.Type Check = 1; Raport (Șir (DemoComp.Type Check)); DemoComp.Test = "Vasya"; Raport (Șir (DemoComp.Test)); DemoComp.Test = "Petya"; Raport (Șir (DemoComp.Test)); Raport (Șir (DemoComp.Type Check)); Sfârșitul procedurii
În urma 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 ultimei proprietăți setate. 3 corespunde unei valori întregi, 22 unei valori șir. Corespondența dintre tipuri și codurile acestora este stabilită în fișier tipuri.h, care se află pe discul ITS.

Extinderea listei de metode

Sarcină:
  1. Extindeți funcționalitatea unei componente 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 Funkts1, care ia două șiruri de caractere ca parametru ("Parameter1" și "Parameter2"). Ca rezultat, este returnat un șir de tipul următor: „Verifică. Parametrul 1, Parametrul 2 "
  4. Asigurați-vă că modificările efectuate 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. La fel ca și metodele corespunzătoare pentru proprietăți
GetNParams
Returnează numărul de parametri ai metodei cu numărul ordinal specificat; dacă nu există o metodă cu acest număr 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 specificată este adevărată 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 ordinalul 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 de tip șir sau 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: Enterprise va elibera această memorie prin apel Memorie libera.
O descriere completă a metodelor, inclusiv lista de parametri, este descrisă în detaliu în documentația furnizată pe discul ITS.
Să luăm în considerare implementarea metodelor descrise mai sus.
În codul componentei, 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 „Afișare în linia de stare”, L „StartTimer”, L „StopTimer”, L „Încărcare imagine”);
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 codul direct executabil al metodei.
Pentru a adăuga o metodă care poate fi apelată doar ca funcție, trebuie să faceți următoarele modificări în 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 de metodă direct executabil
Să dăm matricele g_MethodNamesși g_MethodNamesRu precum şi enumerarea Metode A se uita:
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 „Afișare în linia de stare”, L „StartTimer”, L „StopTimer”, L „Încărcare imagine”, L „Test”);

Metode Enum (eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Întotdeauna ultimul);
Să edităm funcția GetNProps pentru a returna numărul de parametri pentru metoda de testare:
long CAddInNative :: GetNParams (const long lMethodNum) (comutator (lMethodNum) (cazul 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; comutator (lMethodNum) (cazul eMethEnestable; implicit nu există valoare de parametru fals; ) returnează fals;)
Mulțumită liniei adăugate
caz eMethTest:
în absența unuia sau a mai multor 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) (comutator (lMethodNum) (case eMethLoadPicture: case eMethTest: return true; default: return false;) return false;)
Și adăugați codul de metodă executabil 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: case eMethTicture: ... dacă (! lSizeArray ||! paParams) returnează false; s1 = (paParams) -> pwstrVal; s2 = (paParams + 1) -> pwstrVal; wstring_to_p (std :: wstring (s1 + s2), pvarRetValue); ret = adevărat ; pauză;) întoarcere ret;)
Să compilam componenta și să aducem codul de configurare la forma:
schimba DemoComp; Procedura de pornire a sistemului () Conectați ExternalComponent ("...", "DemoVK", ExternalComponentType.Native); DemoComp = Nou ("AddIn.DemoVK.SomeName"); bandă = DemoComp.Test ("Bună ziua", "Lumea!"); Raport (banda); Sfârșitul procedurii
După începerea configurației, vom primi un mesaj: „Bună, lume!”, ceea ce înseamnă că metoda a funcționat cu succes.

Temporizator

Sarcină:
  1. Explorați implementarea temporizatorului în demonstrația VK
  2. Modificați metoda „StartTimer” adăugând posibilitatea de a transfera intervalul temporizatorului în parametri (în milisecunde)
  3. Asigurați-vă că modificările efectuate funcționează

În WinAPI, pentru a lucra cu timpul, puteți folosi mesajul WM_TIMER... Acest mesaj va fi trimis programului dumneavoastră la intervalul de timp pe care îl specificați la crearea cronometrului.
Pentru a crea un cronometru, utilizați funcția SetTimer:
UINT SetTimer (HWND hWnd, // mânerul ferestrei UINT nIDevent, // identificatorul (numărul) temporizatorului UINT nElapse, // întârziere TIMERPROC lpTimerFunc); // indicatorul funcției
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 funcția care va fi executată de fiecare dată când este declanșat temporizatorul. Antetul funcției ar trebui să arate astfel (numele poate fi orice):
void __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Luați în considerare implementarea unui cronometru într-un VK demonstrativ.
Deoarece luăm în considerare procesul de dezvoltare a unei componente externe pentru sistemele 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);
Identificatorul temporizatorului creat este plasat într-o variabilă m_uiTimer pentru ca ulterior să poată fi oprit.
Funcţie MyTimerProc după cum urmează:
VOID CALLBACK MyTimerProc (HWND hwnd, // mânerul ferestrei pentru mesajele timer UINT uMsg, // mesaj WM_TIMER UINT idEvent, // identificator timer DWORD dwTime // ora curentă a sistemului) (dacă (! PAsyncEvent) return; wchar_t * who = L „ComponentNative”, * what = L „Timer”; wchar_t * wstime = wchar_t nou; if (wstime) (wmemset (wstime, 0, TIME_LEN); :: _ ultow (dwTime, wstime, 10); pAsyncEvent-> ExternalEvent ( cine, ce, wstime); șterge 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 vom efectua urmatoarele actiuni:
Modificarea codului metodei GetNParams astfel încât să fie pentru metodă eMethStartTimer a returnat valoarea 1:
caz eMethStartTimer: return 1;
Iată codul metodei CallAsProc A se uita:
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, în modulul aplicației de configurare gestionată, scrieți codul:
schimba DemoComp; Procedura de pornire a sistemului () Conectați ExternalComponent ("...", "DemoVK", ExternalComponentType.Native); DemoComp = Nou ("AddIn.DemoVK.SomeName"); DemoComp.StartTimer (2000); Sfârșitul procedurii
După pornirea configurației, programul va primi mesaje cu un interval de 2 secunde, ceea ce indică funcționarea corectă a cronometrului.

Interacțiune cu sistemul 1C: Enterprise

Pentru interacțiunea dintre componenta externă și sistemul 1C: Enterprise, metode din clasa IAddInDefBase, descrise în fișier AddInDefBase.h... Să le enumerăm pe cele mai frecvent utilizate:
Generarea unui mesaj de eroare
virtual bool ADDIN_API AddError (wcode scurt nesemnat, const WCHAR_T * sursă, const WCHAR_T * descr, cod lung)
wcode, cod- coduri de eroare (o listă de coduri de eroare cu o descriere 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
Mesajul este interceptat prin procedura ExternalEvent Handling.
Înregistrarea unei componente externe în sistemul 1C: Enterprise
virtual bool ADDIN_API RegisterProfileAs (WCHAR_T * wszProfileName)
wszProfileName- denumirea componentei.
Aceste metode sunt suficiente pentru interacțiunea completă a VK și 1C. Pentru a primi date de către componenta externă din 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 transfera datele înapoi. .

Tip de date TVariant

La schimbul de date între o componentă 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 cu ITS:
struct _tVariant (_ANONYMOUS_UNION uniune (int8_t i8Val; int16_t shortVal; int32_t lVal; int intVal; unsigned int uintVal; int64_t llVal; uint8_t ui8Val; uint16_t ushortVal; uint_t_t ushortVal; uint_t_t ushortVal; uint_t_t ushortVal; uint_t_t IDValt; ; struct _tVariant * pvarVal; struct tm tmVal; _ANONYMOUS_STRUCT struct (void * pInterfaceVal; IID InterfaceID;) __VARIANT_NAME_2 / * ifONYST32 /; struct_tVariant ; // număr de octeți) *__VARIANT_STRUCT_NAME * /_US; wstrLen; // număr de simbol) __VARIANT_NAME_4 / * wstr * /;) ___t1ART uint32 matrice dimensională în pvarVal TYPEVAR vt;);
Tip de tVariant este o structură care include:
  • amestec (unire) destinat direct stocării datelor
  • identificatorul tipului de date
În general, lucrul cu variabile precum tVariant are loc conform următorului algoritm:
  1. Determinarea tipului de date care sunt stocate în prezent într-o variabilă
  2. Referindu-se la câmpul corespunzător al amestecului pentru acces direct la date
Folosind tip tVariant simplifică foarte mult interacțiunea dintre sistemul 1C: Enterprise și componentele externe

Aplicație

Directorul „exemple” conține exemple pentru articol
exemple / 1 - rulați componenta demo
exemple / 2 - demonstrație de extindere a 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ă.

De exemplu, nu veți putea rescrie o componentă dacă nu sunteți autorul acesteia și pur și simplu nu există surse. Sau dacă cele mai simple tipuri suportate de tehnologia Native API (număr, șir, boolean, dată) nu sunt suficiente pentru funcționarea acesteia.

Nu există probleme speciale atunci când lucrați cu baza de fișiere. Lucrarea programată este apelată în procesul de fundal al unui utilizator obișnuit. Prin urmare, apelurile clienților îi sunt disponibile. În baza de date server, la pornirea unui job programat, nu există context client, respectiv apelul Conectare componentă externă () nu e disponibil.

În acest caz, puteți apela componenta pe client. Pentru a face acest lucru, este suficient să porniți o altă sesiune 1C dintr-o sarcină programată pe server, în care sunt efectuate acțiunile necesare pe client. Ei bine, nu uitați să încheiați sesiunea de rulare mai târziu.

De exemplu, într-o sarcină de rutină, generăm și salvăm un raport care utilizează componenta externă COM NameDeclension.dll pentru a refuza numele complet. Pe baza de fișiere, o astfel de sarcină programată va funcționa corect; nu va fi posibilă conectarea la componenta server.

Pentru a elimina problema, adăugați o procedură la modulul de sarcini de rutină care va lansa o altă sesiune în modul server și în acesta va executa un apel pentru a genera un raport asupra clientului din procesare externă.

# Dacă Client Atunci Procedura RunFormationSaveReport () Export Dacă ExternalComponent este conectat ("GeneralLayout.NAMEDECL", "Skl", ExternalComponentType.COM) Then Component = New ("AddIn.Incl.NameDeclension"); // Iată codul pentru generarea și salvarea raportului. În caz contrar, LogRecordRecord ("JobRegulations", LogRegistrationLevel.Error, "Failed to connect an external component on the client"); EndIf; EndProcedure #Otherwise Procedure ExecuteFormationAndSavingReport () Export ExecuteOperationOnClient ("TaskRegl.RunFormationSavingReport ()"); EndProcedure Procedure ExecuteOperationOnClient (ParameterFor Execution) Export UserName = ""; UserPassword = ""; PathToExternalProcessing = "c: /temp/Autostart.epf"; Citat = "" ""; DirectoryBIN = DirectoryProgram (); ConfigurationPath = InfoBaseConnectionString (); ConfigurationPath = StrReplace (ConfigurationPath, Quote, Quote + Quote); StartString = Citat + Director BIN + „1cv8.exe” + Citat + „ENTERPRISE” + „/ IBConnectionString” + Citat + ConfigurationPath + Citat + „/ N” + Citat + Nume utilizator + Citat + „/ P” + Citat + Parola utilizator + Citat + „/ Execute” + Ghilimele + PathToExternalProcessing + Citat + „/ C” + Citat + ParametruPentru Execuție + Citat; RunApplication (StartString); EndProcedure #EndIf

Cod de procesare extern care va determina pur și simplu, în contextul clientului, să tipăriți raportul necesar din modulul de sarcini de rutină și să încheiați sesiunea după generarea raportului.

Încercarea de a executa (LaunchParameter); Excepție EndTry; EndSystemWork (Fals);

Comoditatea soluției este că atunci când configurați joburi programate, nu contează în ce mod va fi lansat jobul. Dacă baza de date este un fișier, atunci procedura necesară va începe imediat. Dacă baza de date este bazată pe server și nu există un context client la pornire, atunci o nouă sesiune va fi inițializată și procedura va funcționa corect în contextul clientului.

Cod pentru o aplicație obișnuită. Teoretic, va funcționa complet similar într-unul controlat.

p.s. De asemenea, această abordare poate fi utilizată pentru a efectua orice proceduri client în joburile programate.

Aplicația mobilă vă permite să efectuați operațiuni de depozit (inventar de mărfuri și mijloace fixe, mișcare de mărfuri) în 1C Contabilitate 3. +. Aplicația este dezvoltată nativ pe Android. Pentru o muncă cu drepturi depline atunci când se schimbă printr-un fișier, este necesară doar procesarea externă. Această aplicație nu necesită baze de date intermediare și niciun software suplimentar. Aplicația poate funcționa atunci când nu există nicio conexiune.

Functionalitate:
... Inventarul bunurilor;
... Inventarierea mijloacelor fixe;
... Mutarea mărfurilor;

Link pentru descărcare.

Versiunea istorică.

Suport pentru versiunile Android.

Android 4.4 și versiuni ulterioare.

Suport de configurare.

1C: Contabilitate 3. +

Suport pentru scanere de coduri de bare și TSD.

  • GS-М100BT este acceptat în modul SPP;
  • TSD CARIBE PL 50L
  • Sunt acceptate orice scanere în modul HID conectat prin OTG.

Funcţional.

Inventarul mărfurilor.

Pentru a efectua un inventar al mărfurilor, este necesar să se întocmească un document Inventarul mărfurilor în 1C fără cantitatea reală. Apoi, trebuie să mergeți în aplicație la secțiunea Inventar de mărfuri. Dacă ați configurat schimbul online cu 1C, atunci faceți clic pe meniul Descărcare. Aceasta va încărca toate documentele de inventar, documentele editate nu vor fi suprascrise.

Parte tabulară

Potrivirea codului de bare este căutată în memoria dispozitivului, dacă nu este găsită, atunci este căutată în baza de date 1C, dacă nu este găsită, atunci este căutată în baza de date 1C în mijloace fixe. Dacă un articol este găsit în urma căutării, căutarea se va efectua în secțiunea tabelară a documentului. Dacă obiectul se găsește în secțiunea tabelară, atunci la această linie se va adăuga cantitatea 1 + cantitatea găsită în secțiunea tabelară. Dacă obiectul nu se găsește în secțiunea tabelară, acesta va fi adăugat la secțiunea tabelară a documentului cu cantitatea reală de 1 și cantitatea contabilă de 0. În cazul în care căutarea are ca rezultat un mijloc fix, programul va oferi adăugarea în documentul de inventar al sistemului de operare.

Descărcarea documentelor în 1C

Inventarul mijloacelor fixe.

Pentru a efectua un inventar al mijloacelor fixe (denumit în continuare OS), este necesar să se întocmească un document Inventarul mijloacelor fixe în 1C fără disponibilitate reală. Apoi, trebuie să mergeți la secțiunea Inventar OS din aplicație. Dacă ați configurat schimbul online cu 1C, atunci faceți clic pe meniul Descărcare. Aceasta va încărca toate documentele OS Inventory; documentele editate nu vor fi suprascrise.

Dacă aplicația dvs. este offline, puteți descărca documente dintr-un fișier. Fișierul este descărcat din 1C folosind procesare.

Documentele pot fi șterse dintr-o dată făcând clic pe Ștergeți toate sau unul câte unul, glisând la stânga sau la dreapta.

Parte tabulară

Făcând clic pe documentul solicitat, se va deschide o secțiune tabelară, similară cu 1C. Partea tabulară vă permite să adăugați / modificați / ștergeți linii, editați cantitatea.

Scanarea și procesarea codurilor de bare

Codurile de bare pot fi scanate cu o cameră, scaner de mână, scaner GS-M100BT, Carible PL 50L TSD sau introduse manual.

Algoritmul de căutare a codurilor de bare este următorul:

Potrivirea codului de bare este căutată în memoria dispozitivului, dacă nu este găsită, atunci este căutată în baza de date 1C. Dacă rezultatele căutării sunt găsite, atunci căutarea se va efectua în secțiunea tabelară a documentului. Dacă obiectul este găsit în secțiunea tabelară, atunci prezența reală va fi setată în această linie. Dacă obiectul nu se găsește în secțiunea tabelară, atunci va fi adăugat la secțiunea tabulară a documentului cu prezența sa reală.

Descărcarea documentelor în 1C

Documentele completate sunt încărcate în 1C din meniul secțiunii tabelare.

Prin analogie cu încărcarea, documentele pot fi încărcate online în 1C sau printr-un fișier.

Atribuiți și imprimați coduri de bare pentru articole.

Pentru a instala un cod de bare și pentru a imprima etichete, trebuie să conectați un formular de imprimare extern în cardul de nomenclatură și să faceți clic pe Tipărire cod de bare. Dacă acest articol nu are un cod de bare, atunci codul de bare va fi generat automat și tipărit pe etichetă. Eticheta va fi tipărită la dimensiunea 60x30.

Numirea și tipărirea etichetelor mijloacelor fixe.

Codul de referință al sistemului de operare este utilizat ca cod de bare pentru sistemul de operare. Pentru a imprima, trebuie să conectați un formular de imprimare extern și să faceți clic pe Imprimare cod de bare pe cardul OS. Eticheta va fi tipărită la dimensiunea 60x30.

Setări.

Descrierea setărilor.

Configurarea scanerului bluetooth GS-M100BT.

Pe ecranul Setări, puteți configura scanerul de coduri de bare Bluetooth GS-M100BT. Pentru prima configurare, trebuie mai întâi să deschideți „Bluetooth”, se va deschide o interfață standard pentru împerecherea dispozitivelor (va arăta diferit pe diferite dispozitive).

Pornire rapidă

  • Instalați aplicația
  • Publicați interfața OData în 1C
  • Personalizați compoziția interfeței OData
  • Încărcați toate directoarele, codurile de bare și documentele de la 1C în aplicație, fie online, fie printr-un fișier.
  • Efectuează operațiuni de depozit
  • Încărcați datele procesate în 1C

 

Ar putea fi util să citiți: