Nauji „1C: Trade Management“ leidimai: atnaujinimas be tobulinimo. Operatyvinė apskaita tampa reglamentuota


Taip yra dėl kai kurių globalaus konteksto funkcijos ConnectExternalComponent() ypatumų.

Dažnai programuotojams kyla problemų prijungiant išorinius komponentus (pavyzdžiui, komercinės įrangos tvarkykles), kai vartotojai dirba su 1C, prisijungdami prie serverio per terminalą.

Šiuo atveju vartotojai mato, pavyzdžiui, šį paveikslėlį:

Dirbant iš vietinių kompiuterių, nekyla problemų su išorinių komponentų prijungimu.

Su kuo tai susiję? Taip yra todėl, kad kai vartotojai dirba per terminalo serverį, jie turi mažiau teisių nei dirbdami vietiniame kompiuteryje.

Tai galite lengvai patikrinti, jei prie terminalo serverio prisijungiate naudodami administratoriaus teises.

Šio skirtumo priežastis yra ta, kad 1C negali užregistruoti išorinio komponento registre, kai vartotojas terminale dirba su įprastomis teisėmis, nes paprastas vartotojas neturi leidimo rašyti į sistemos registro filialą HKEY_CLASSES_ROOT.

Publikacijose išorinių komponentų prijungimo terminale tema siūlomi įvairūs šios problemos sprendimo būdai.

Pavyzdžiui, šie:

1. Pirmą kartą paleiskite 1C naudodami administravimo teises.

Ši parinktis ne visada veikia. Toliau paaiškinsiu kodėl.

2. Suteikite paprastiems terminalo vartotojams leidimą rašyti sistemos registro filialui HKEY_CLASSES_ROOT.

Nepakankamai pažengę vartotojai neturėtų to daryti, kitaip gali kilti problemų.

3. Naudodamiesi įvairiomis programėlėmis, užregistruokite VK vartotojo, turinčio visas teises, vardu.

Tai irgi nėra gerai.

Taigi, koks yra geriausias būdas išeiti iš šios situacijos?

Siūlau savo šios problemos sprendimą. Mano nuomone – paprasta ir gražu.

Tyrinėdamas šią problemą, uždaviau sau klausimą: kodėl 1C net bando užregistruoti VK naudodamas naują kelią? Juk ji jau registruota sistemoje.

Paaiškėjo, kad įprastose 1C konfigūracijose (pavyzdžiui, „Prekybos valdymas“) pasaulinio konteksto metodui Connect External Component() naudojama ši sintaksė:

ConnectExternalComponent ("Katalogas. Prijungta įranga. Išdėstymas. VairuotojasATOLBarcodeScanner", "ATOLScanner");

Kaip matote, tvarkyklės VC yra prijungtas iš "ATOLBrūkšninio kodo skaitytuvo tvarkyklės" išdėstymo, esančio kataloge "Prijungta įranga".

Kas tada atsitiks?

1C išsaugo komponentą laikinajame vartotojo aplanke, pvz., „C:\Documents and Settings\User\Local Settings\Temp\1032\v8_4_12.tmp“

ir bando jį užregistruoti registro skyriuje HKEY_CLASSES_ROOT tiksliai šiuo keliu.

Terminale paprasti vartotojai neturi teisės keisti šios registro šakos, todėl komponentas prie jų neprisijungia.

Dabar pakalbėkime apie tai, kaip išeiti iš šios situacijos.

Globalaus konteksto metodas ConnectExternalComponent() turi keletą sintaksės parinkčių. Tai mes naudosime.

Taigi, žingsnis po žingsnio:

1. Užregistruokite išorinį komponentą naudodami regsvr32.exe paslaugų programą terminalo serveryje aplanke C:\WINDOWS\SYSTEM32, jei naudojate 32 bitų OS, arba aplanke C:\WINDOWS\SYSWOW64, jei naudojate 64 bitų OS.

2. Naudokite vieną iš dviejų papildomų sintaksės parinkčių ConnectExternalComponent() metodui:

1 variantas:

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

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

2 variantas:

ProgID = "AddIn.Scaner45";

ConnectExternalComponent (ProgID);

DriverObject = Naujas(ProgID);

Mano nuomone, 2 variantas yra geresnis.

Tuo pačiu metu 1C nebando perregistruoti VK naudodamas naują registro kelią, todėl visos problemos išspręstos.

Na, tai viskas. Sėkmės darbe!

[norėdami pamatyti nuorodą, turite užsiregistruoti]

Klausimas: Išorinis komponentas Native Api C++, skirtas Linux (Ubuntu x64) 1C 8.3 versijoje


Rašau į VK, bet negaliu prisijungti prie 1c ubuntu. Net vykdomasis failas iš 1c neprisijungia. Taigi klausimas apie tai:

1) Bandau prijungti VK iš VNCOMPS pavyzdžio, pateikto straipsnyje

(nuorodą rasite pačioje pabaigoje: „Kopijuojama“).
NativeApi projekto viduje yra makefile. Su jo pagalba kuriu .so biblioteką Ununtu.
Bet kai „Prijunkite išorinį komponentą“ 1c sugenda.
Panašiai, jei kuriu naudodamas „build.sh“ (projekto šaknyje).

Pačiame makefile vėliavėlę keičiu iš m32 į m64, nes 1c ir pati x64 sistema. (su parametru m32 vis tiek neprisijungia)
Štai pavyzdys, kaip skambinti VK iš 1C 8.3:
Prisijungimas atliktas = ConnectExternalComponent("/home/alexeyubuntux64-20 gb/Documents/VNCOMP83/example/NativeAPI/AddInNative.so", "AddInNative", ExternalComponentType.Native); Yra straipsnis tik šia tema.
Bet, kiek matau, į visus šiuos punktus VNCOMPS pavyzdyje jau buvo atsižvelgta ir pataisyta.

Bet iš esmės tai yra kompiliavimo parametrų klausimas. MB 32 bitų išorinis komponentas paprastai jungiasi prie 32 bitų 1c, bet aš jį įdiegiau Ubuntu x64 1c enterprise83 8.3.5-1486 amd64. Ir aš noriu su ja prisijungti prie VK.

Ar kas nors turi idėjų, kaip išspręsti šią problemą?)
VNCOMPS pavyzdys turėtų veikti, bet reikia pakoreguoti kūrimo parametrus arba pati platforma, kurioje testuoju, yra neteisinga.

Atsakymas:Įdomu, ar galima Java parašyti išorinį komponentą?

Klausimas: Negalima prijungti išorinio komponento (vietinio).


Sudariau pavyzdį su ITS, 64 ir 32 bitų sistemoms.

Jungiu taip:
Ryšio rezultatas = ConnectExternalComponent(KDLLPath, "Comp", ExternalComponentType.Native); Ryšys veikia viename kompiuteryje, bet ne kitame. Yra skirtumas tarp OS. Kur užmegztas ryšys, yra Win7, kur nėra Win10. Tuo pačiu metu kompiuteryje, kuriame mano komponentas neveikia, veikia standartiniai komponentai.

Išbandyta skirtingose ​​platformose (8.3.4.482, 8.3.6.2100, 8.3.11.2700, 8.3.12.1412).

Kaip suprasti, kodėl jis neprisijungia?

Atsakymas: vc_redist pamiršote?

Klausimas: 1C8 ir išorinis komponentas su Native tipo


Laba diena.
Turiu BP 3.0.50.12 konfigūraciją ir noriu į ją įdiegti Vesy-Soft kompanijos svėrimą naudojant UniServerAuto.
Kūrėjai sukompiliavo komponentą „Native“, skirtoje „Windows 32“ ir „Windows 64“, ir suarchyvavo jį su „maifest“ failu. Taip pat yra 1C pavyzdys, kaip galima apskaičiuoti svorį. Jame, naudojant maketą su dvejetainiais duomenimis, kaip suprantu, nurodytas šis archyvas. Pavyzdyje viskas gerai: komponentas sumontuotas, prijungtas, tada ryšys užmezgamas ir nuskaitomas svoris.
Bet kai tik pradedi perkelti į 1C, svoris nenuskaitomas. Atrodo, kad viskas parašyta paprastai, bet nesuprantu, kur yra grėblys.
Kas turi šiek tiek laiko - padėk, pažiūrėk viena akimi, gal sprendimas paviršiuje, bet aš einu kur nors ne ten ir darau ne taip. Man niekada anksčiau neteko dirbti su vietine technologija...

Ir priede yra mano apdorojimo tekstas

Atsakymas:

Na, turiu naujienų...
Tiesiog pradėjau žingsnis po žingsnio matyti, kada tai pradės žlugti. Norėdami tai padaryti, sukūriau tuščią duomenų bazę ir apdorojau ją komanda. Pagal analogiją su tiekėjo pavyzdžiu išdėstymą perkėliau į naują konfigūraciją – veikia antrą kartą. Tie. pirmą kartą ne, bet antrą kartą taip. Tai paskatino mintį, kad mūsų apdorojime vis tiek reikės atskirti komponento ir objekto sujungimą pagal skirtingas procedūras.
Tada perkėliau į savo duomenų bazę su maketo ryšiu – veikia. Fu, tai gerai.... Bet aš norėčiau nekeisti konfigūracijos, taigi eikime toliau

Bandau pridėti maketą prie apdorojimo. Jo dydis iš karto padidėja nuo 10kb iki 3mb ir pastebimas didelis veikimo sulėtėjimas – jis netinkamas. Aš pradedu ieškoti komponentų prijungimo per dll. Tie. iš esmės tas pats, kur aš pradėjau. Tačiau yra vienas „BET“: ieškodamas dll pavadinimo vartotojo aplanke, pastebėjau, kad šis dll yra ten, kur (kaip suprantu) susumuojami 1C registruoti dll:
C:\Users\USER\AppData\Roaming\1C\1cv8\ExtCompT
Atitinkamai, nereikia naudoti viso kelio į dll, galite tiesiog įvesti jo pavadinimą:
ConnectExternalComponent ("Add1CUniServerAuto32.dll", "UniServerAuto", ExternalComponentType.Native);

Bandau... registruojantis keikiasi, bet grąžina svėrimo rezultatą. Pasirodo, dll jau užregistruotas ir tai reiškia, kad jums tereikia jį prijungti. Nuimu ir viskas veikia.
Apibendrinant:
1. Svėrimo procese AtOpening procedūra apėmė išorinio komponento prijungimą ir prijungimą prie objekto.
2. Kelias į dll Aš jo nerašiau, tik nurodžiau jo pavadinimą.

Dabar sėdžiu ir galvoju, kada dll buvo įdiegtas 1C? Programinės įrangos diegimo metu? Vargu... Kur paleidžiant šio dll kūrėjo konfigūraciją, ji įdiegta atidarius formą? Nežinau, bet man tai atrodo artima... Ką manai?
Ir antra, naujoje vietoje, kai reikia įdiegti tą patį terminalą, ką reikia padaryti, kad viskas veiktų? Ar turėčiau visiškai įdiegti programinę įrangą, paleisti tiekėjo konfigūraciją, kad patikrinčiau veikimą, ir tada (teoriškai) turėtų veikti mano apdorojimas? Kažkas kažkaip sudėtinga... Ar turėčiau vieną kartą įdiegti išorinį komponentą, kai įdiegiu programinę įrangą?

Norėčiau išgirsti jūsų mintis šiuo klausimu...

Klausimas: Išorinis komponentas.dll


laba diena visiems.
Klausimas.
dll komponentas, puikiai veikiantis 1C 7.7 versijoje
1s 8.1 visai nenori paleisti...
Bandžiau įklijuoti į C:\Program Files\1cv81\bin\cache1c.dll
Bandžiau registruotis naudojant regsvr32 "C:\Program Files\1cv81\bin\cache1c.dll"
Registruojasi be problemų.
Kai noriu jį pasiekti, gaunu klaidos pranešimą:

Įkeliant išorinį komponentą įvyko klaida! cache1c.dll
Procedūros mygtukasVykdytiPaspauskite (mygtuką) Bandymas įkelti išorinį komponentą ( "C:\Program Files\1cv81\bin\cache1c.dll"); Išimčių ataskaita ( "Klaida įkeliant išorinį komponentą!"+ "cache1c.dll" ); EndAttempt; Bandymas // Gaukite komponento objektą. // m = Naujas ("cache1c.GTMcmd" ); m = naujas COMObject("cache1c.GTMcmd" ); Išimčių ataskaita (); EndAttempt; Procedūros pabaiga

Atsakymas: Tai banalu iki neįmanomumo...
Turite padaryti pauzę tarp skambučių (milisekundėmis)...
Procedūra ButtonExecutePress(Button) Attempt // Gaukite komponento objektą. m = naujas COMObject("cache1c.GTMcmd" ); Išimčių ataskaita ( „Nepavyko sukurti išorinio komponento objekto“); EndAttempt; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Connect(); m.Pauzė(100); ...... ir tt
1c 7.7 - tai nėra būtina, pasirodo, kad valdymas yra greitesnis.

Klausimas: Darbas su išoriniu komponentu su 1C serveriu...


Laba diena,

Yra išorinis komponentas, parašytas C++, kurio užduotis yra gauti informaciją iš išorinės duomenų bazės ir grąžinti užklausos rezultatą 1C verčių lentelės pavidalu.
Norint sugeneruoti reikšmių lentelę dabartiniu momentu, naudojama IDispatch* pBackConnection sąsaja, gauta kaip parametras funkcijoje Init(). Tada aš tiesiog naudoju 1C funkcijas, kad sukurčiau reikšmių lentelę, užpildau ją ir grąžinu ją į antrąjį parametrą CallAsFunc (...).
Problemos prasidėjo perėjus prie 1C plonųjų klientų. Serverio pusėje išorinis komponentas tikrai neįsijungia. Galite paleisti jį kliento pusėje, tačiau viskas atrodo kaip ramentai ir iškrenta iš bendros „kliento-serverio“ logikos 1C. Pavyzdžiui, klientas nesupranta, kas yra verčių lentelė, problemos su „pasauliniais“ kintamaisiais, seansais ir pan.
NativeAPI šiuo atžvilgiu yra dar labiau ribotas.
Šokis su tamburinu lėmė tai, kad galėjau paleisti išorinį komponentą pagal 1C serverį, BET darbas tęsiasi tol, kol bus bandoma iškviesti Invoke per pBackConnection. 64 bitų 8.2 serverio versija bando kažką daryti, kol baigiasi skirtasis laikas, o 32 bitų versija (VK natūraliai taip pat yra 32 bitų) tiesiog iš karto nukrinta.
Manau, kad 1C serveris nepalaiko šio darbo režimo.
Atitinkamai kyla klausimų: ar tai laikina, ar 1C logika apsiriboja šios darbo schemos atšaukimu? Jei tokiu būdu neįmanoma sukurti vidinių 1C struktūrų (reikšmių lentelės), ar iš principo yra aprašymas, kas yra verčių lentelė sistemos lygiu, kad būtų galima bandyti ją sukurti C++, užpildyti, o tada tiesiog įstumti į 1C kaip grąžinimo parametrą? Norėčiau bent kryptį, kuria kryptimi kasti.

Ačiū.

Atsakymas:

Jūs rašote viena, o reiškiate kitą.
1C aplinkoje deklaruoti kintamuosius, kurie bus matomi skirtingose ​​sesijose, dabar neįmanoma, o anksčiau tokios galimybės nebuvo. Kitas užsiėmimas yra fiziškai kitoks procesas.
Sesija – tai seansas, jungiantis prie duomenų bazės, t.y. vartotojo sesija. O gal į šią koncepciją įdedate kažką savo?

Per vieną sesiją buvo galima ir dabar galima deklaruoti seanso modulio kintamuosius, kurie gyvuos ir bus matomi sesijos metu iš skirtingų vietų... iš tikrųjų jų yra 4.
- Sesijos modulis;
- Įprasto taikymo modulis;
- Tvarkomų programų modulis;
- Išorinis prijungimo modulis.

Na, žinoma, reikia atsiminti kontekstą. Serverio kontekstas nėra tiesiogiai pasiekiamas kliento pusėje ir atvirkščiai.

Tiesą sakant, 1C architektūra numato, kad duomenų mainai vyks taip:
- naudojant parametrus / procedūrų / funkcijų grąžinimus;
- naudojant vadinamuosius seanso parametrus (negali būti objektai, bet iš tikrųjų matomi paletėje).

Lentelė formoje... ar ji prijungta prie kažkokios objektų lentelės (pvz., apdorojimas)? arba ne. Jei taip, tada jis pasiekiamas serveryje (&OnServer) ir redaguoti ten....

Ir vis dėlto, taip, verčių lentelė kliento pusėje nepasiekiama UV spinduliu. Na, taip nusprendė 1C.

Nagi! Jis veikia su „Excel“, veikia su FSO ir daugybe kitų dalykų, bet čia neveikia. Pagauk klaidą ir analizuok....

Bandymas
...
savo veiksmus
...
Išimtis
str = Klaidos aprašymas();
EndAttempt;

Dėl šiuolaikinių techninės įrangos galimybių tai nėra argumentas.

Grynai tavo asmeninė nuomonė. Nieko bendro neturi su realybe. Jokiu būdu ne. Dar kartą kartoju, 1C puikiai veikia su COM. Tiek su in-proc, tiek su out-proc.

Pateikite kodą, kurį naudojate atsisiųsdami ir susisiekite su VK.

Beje, VK... jūsų atveju tai COM ar Native API?
Jei COM, tai registruojate kaip... per regsvr32... kaip tada "išspręsi" bitų gylio problemą?

Klausimas: išorinio komponento įdiegimas


Pasakykite man, kaip įdiegti išorinį komponentą. Vykdant šį kodą, pateikiama klaida. Makete raskite NameDecl.dll

Bandoma SetExternalComponent("GeneralLayout.Layout"); Išimtis EndTry ;
Klaida: nepavyko įdiegti išorinio komponento!

Atsakymas: ()
ConnectExternalComponent ("GeneralLayout.Layout", "NameDecl", ExternalComponentType.Native) grąžina FALSE.
New("AddIn.NameDecl.CNameDecl", Undefined) = (()): Tipas undefined (AddIn.NameDecl.NameDecl)

Klausimas: gimtoji dll neprisijungia prie 1c 8.1 (fptrwin32_fz54_9_11_0_5549.dll)


Sveiki.
1C atnaujino internetinių kasos aparatų dll, skirtą ffd 1.05 (įtraukta į techninės priežiūros procesą fptrwin32_fz54_9_11_0_5549.dll).
Turiu seną 1C 8.1. Skirtingai nuo 8.2, jis nepalaiko darbo su išorine įranga taip pat, kaip 8.2, todėl pirmiausia turite užregistruoti dll sistemoje „Windows“, o tada prijungti tik prie 1C?

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

Tačiau senasis apdorojimas buvo parašytas com "technologija", o naujasis yra gimtoji. Atitinkamai, registruojant regsvr32, pateikiama klaida:
Modulis įkeltas, bet DllRegisterServer įėjimo taškas nerastas. Taip pat siūloma patikrinti, ar šis failas yra teisingas dll arba OCX failas.
Ar kas nors susidūrė su panašia situacija ir kaip išėjote? Suprantu, kad 7.7 turės panašią problemą.
8.2 kodas:

Išdėstymas = GetLayout("Integracijos komponentas"); Adresas = PlaceInTemporaryStorage(Layout); ConnectExternalComponent(Adresas, "IntegrationComponent", ExternalComponentType.Native); Vairuotojas = New("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9");

1C 8.2:
ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
1C 8.1:
ConnectExternalComponent(<Идентификатор объекта>)
Galimybės:
<Идентификатор объекта>(būtina)
Tipas: Styga. Išorinio komponento objekto ProgID (programinis identifikatorius). Turi atitikti sistemos registracijos duomenų bazėje (Registre) esančią informaciją.
Apibūdinimas:
Sujungia išorinių komponentų objektus su 1C:Enterprise.
Nepasiekiamas 1C:Enterprise serveryje. Nenaudojamas išoriniame prijungimo modulyje.
Pastaba:
Išoriniai komponentai yra suderinami su 1C:Enterprise 7.7 komponentais.
Pavyzdys:
Bandymas
ConnectExternalComponent ("AddinObject.Scanner");
Report("Brūkšninio kodo skaitytuvo komponentas buvo įkeltas");
Išimtis
Report("Brūkšninio kodo skaitytuvo komponentas neįkeltas");
Pabaiga Bandymas

Ar yra koks nors būdas prijungti šį dll prie 8.1 ar ne?

Ačiū!

Atsakymas:

Aš taip pat neseniai susidūriau su šia problema. Neįmanoma konvertuoti į vėlesnę 1c versiją, nes... dll, su kuriuo veikia ši konfigūracija, tiesiog nustojo veikti ir 1c sudužo su klaida.
Aš išsprendžiau problemą taip:
Sukūriau tuščią 8.3 duomenų bazę, kurioje apdorojau komponento inicijavimą ir tada iš 8.1 per COM ryšį pasiekiau anksčiau sukurtą duomenų bazę ir ten inicijavau komponentą. Tada jau 8.1 iškviečiau šio komponento metodus.
Žinoma, tai yra ramentas, bet aš dar neradau kitos išeities (

8.3 kodo pavyzdys:
Kintamųjų tvarkyklių eksportas;
Funkcija RyšysKomponentaiKKT() Eksportuoti
Bandymas

Išdėstymas = GetLayout("Integracijos komponentas");
Adresas = PlaceInTemporaryStorage(Layout);
ConnectExternalComponent(Adresas, "IntegrationComponent", ExternalComponentType.Native);
Vairuotojas = New("AddIn.IntegrationComponent.SMDrvFR1C20");
Rezultatas = Tiesa;​

Išimtis

Rezultatas = klaidingas;​

EndAttempt;
Grąžinimo rezultatas
EndFunction

Kodo pavyzdys 8.1

Funkcija CreateDriverObject(Driver) Export

Rezultatas = Tiesa;

Bandymas

ConnectionString="Failas="""Kelias į duomenų bazę""";
ComObject = naujas COMObject("V83.ComConnector");
Connect = ComObject.Connect(ConnectionString);

Apdorojimas = Connect.Processing.ConnectExternalComponent.Create();
Ryšio rezultatas = Processing.ConnectionCCPComponents();
Jei prisijungimo rezultatas tada
Vairuotojas = Processing.Driver;
EndIf;

Išimtis
Kiekvienas, kas tai padarė ar susidūrė su panašiais sprendimais, paaiškinkite patį principą naudodami paprastą pavyzdį. Atrodo, kad su išorinių komponentų prijungimu viskas aišku.

// Reikšmių lentelės pildymo pavyzdys TK.Clear(); Užklausa = nauja užklausa; Query.Text = "PASIRINKTI | Nomenklatūra.Nuoroda KAIP Nomenklatūra |NUO | Directory.Nomenclature AS nomenklatūra"; Užklausos rezultatas = Request.Execute(); Pasirinkimas = Užklausa Result.Select(); Nors pasirinkimas.Next() Ciklo puslapis = TK.Add(); UžpildykitePropertyValues(Page, Selection); EndCycle;
Ar galėtumėte naudoti šį pavyzdį, kad paaiškintumėte, kokia kodo dalis paprastai išimama? Būtų logiška pašalinti dalį su užklausa, bet kaip tada galime pasiekti duomenų bazę iš išorinio komponento, apeinant platformą? Nėra prasmės iškelti teksto. Arba išimkite pačią lentelės dalies formaciją. Pasidalinkite savo patirtimi su visais, kurie su tuo susidūrė.

Atsakymas: Ir kad žodis „nesuderinamas“ visada reiškia žodį „blogas“? Taip, man atrodo, kad jei pavadinčiau savo stilių „1C: pats blogiausias gamtoje egzistuojantis šio scenarijų variklio programavimas (išverstas į literatūrinę kalbą)! ir tada tikriausiai atsiras norinčių patikrinti šį žvėrį. Ir tai atrodo kaip klasika: „Aš neskaičiau Pasternako, bet visiškai su juo nesutinku :)

Klausimas: Išorinio komponento prijungimas 1s 8.3.6 ir Win8


Turite prijungti išorinį komponentą vk_rs232.dll prie savarankiškai parašytos konfigūracijos. Atrodo, kad jis buvo užregistruotas per regsvr32.exe. „Atrodo“, nes gavau pranešimą, kad „komponentas užregistruotas, bet kažkas negerai su užkarda“. Remdamasis pirmąja pranešimo puse, rašau kodą 1C
AfterConnecting = Naujas įspėjimo aprašymas ("AfterConnectingVK", ši forma); StartInstallingExternalComponents(,"C:\Controller\vk_rs232.dll"); StartConnectingExternalComponents(AfterConnecting,"C:\Controller\vk_rs232.dll","DLL_Scales");
ir aš gaunu tokią klaidą
"Išorinio komponento įdiegimas nepavyko! Gali trūkti jūsų naudojamos kliento programos komponento!".

O dabar nesuprantu:
1. Gal komponentas neužregistruotas registre – kaip ten patikrinti?
2. Galbūt jo "versija" neveikia naudojant Win8, nors aš ją turiu 32 bitų.
3. Gal pats 1C per naujas, t.y. Atitinkamai, jis negali veikti su šiuo dll?
4. Na, tai nereikšminga – rašau kažką ne taip.

Atsakymas: Ir visa tai privedė mane prie kitos problemos. „VneshComp“ yra įdiegtas, dabar turite jį prijungti. Ir čia yra abu variantai
ConnectExternalComponent ("C:\Controller\vk_rs232.dll","Libra")
ConnectExternalComponent ("Bendras išdėstymas. Išdėstymas", "Svarstyklės")

Sintaksės parinktis: pagal pavadinimą ir vietą

Sintaksė:

ConnectExternalComponent(<Местоположение>, <Имя>, <Тип>)
Galimybės:

<Местоположение>(būtina)

Tipas: Styga.
Išorinio komponento vieta.
Vieta gali būti naudojama:
kelias į išorinio komponento failą failų sistemoje (negalima žiniatinklio kliente), o ne ZIP archyvą;
visiškai apibrėžtas maketo, kuriame saugomi dvejetainiai duomenys, arba ZIP archyvo pavadinimas;
Išorinio komponento URL, kaip dvejetainiai duomenys arba ZIP archyvas, panašiu į GetNavigationLink formatu.
<Имя>(būtina)

Tipas: Styga.
Simbolinis jungiamo išorinio komponento pavadinimas.
Pavadinimas turi atitikti įtaisytosios kalbos pavadinimo taisykles.
<Тип>(neprivaloma)

Tipas: ExternalComponentType.
Prijungiamo išorinio komponento tipas.
Nenaudojamas, jei komponentas yra supakuotas ZIP archyve.
Metodo parinkties aprašymas:

Sujungia komponentus, pagamintus naudojant Native ir COM technologijas.
Komponentas gali būti saugomas informacijos bazėje arba konfigūracijos išdėstyme kaip dvejetainiai duomenys arba ZIP archyve.
„Thin Client“ ir „Web Client“ paleidimo režimuose komponentas pirmiausia turi būti įdiegtas naudojant išorinio komponento diegimo metodą.
Sintaksės parinktis: pagal ID

Sintaksė:

ConnectExternalComponent(<ИдентификаторОбъекта>)
Galimybės:

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

Tipas: Styga.
Išorinio komponento objekto identifikatorius MS Windows registro ProgID (programinio identifikatoriaus) pavidalu (pvz.: „AddIn.Scanner“).
Turi atitikti sistemos registracijos duomenų bazėje (Registre) esančią informaciją.
Metodo parinkties aprašymas:

Komponentas turi būti įdiegtas naudojant COM technologiją ir užregistruotas MS Windows registre.
Šie komponentai yra suderinami su 1C:Enterprise 7.7 komponentais.
Dėmesio! Metodo parinktis neveikia serveryje ir išoriniame ryšyje.
Grąžinimo vertė:

Tipas: Būlio.
Tiesa – ryšys pavyko.
Apibūdinimas:

Sujungia išorinį komponentą prie 1C:Enterprise.
Išoriniai komponentai gali būti saugomi informacijos bazėje arba konfigūracijos maketuose kaip ZIP archyvas arba dvejetainiai duomenys, arba failų sistemos faile.
Dirbant su plonu klientu ir žiniatinklio klientu, komponentas turi būti iš anksto įdiegtas.

Prieinamumas:

Plonas klientas, žiniatinklio klientas, serveris, išorinis ryšys.
Pastaba:

Išorinius komponentus galima įdiegti naudojant Native API arba COM technologiją. Komponentai, pagaminti naudojant COM technologiją, yra suderinami su 1C:Enterprise 7.7 komponentais.
Žiniatinklio klientas gali dirbti tik su informacijos bazėje esančiais komponentais, kurie yra supakuoti į archyvą.
Plonasis klientas gali dirbti su komponentais, esančiais informacijos bazėje, supakuotais į archyvą, ir komponentais, esančiais failų sistemoje.
Storasis klientas gali valdyti visas komponentų saugojimo parinktis. Tokiu atveju, jei komponentas įdiegtas naudojant Diegti išorinį komponentą metodą, tada naudojamas įdiegtas komponentas, o jei neįdiegtas, komponentas bus gautas prisijungimo metu.
Serveris gali dirbti su visais komponentais. Komponentas saugomas talpykloje per serverio seansą.
Pavyzdys:

Jei ConnectExternalComponent ("AddinObject.Scanner") Tada
Report ("Įkeltas brūkšninio kodo skaitytuvo komponentas");
Priešingu atveju
Report("Brūkšninio kodo skaitytuvo komponentas neįkeltas");
endIf;

  • Pamoka

Įvadas

Šiame straipsnyje pateikiama idėja, kaip išoriniai komponentai veikia sistemoje 1C: Enterprise.
Bus parodytas išorinio komponento kūrimo procesas, skirtas 1C: Enterprise sistemos versijai 8.2, veikiančiai Windows OS su failo veikimo režimu. Ši parinktis naudojama daugelyje sprendimų, skirtų mažoms įmonėms. VK bus įdiegtas C++ programavimo kalba.

Išoriniai komponentai „1C: Enterprise“

„1C: Enterprise“ yra išplečiama sistema. Sistemos funkcionalumui išplėsti naudojami išoriniai komponentai (EC). Kūrėjo požiūriu, VC yra išorinis objektas, turintis savybių ir metodų, taip pat galintis generuoti įvykius, kuriuos apdoroja „1C: Enterprise“ sistema.
Išoriniai komponentai gali būti naudojami sprendžiant daugybę problemų, kurias sunku ar net neįmanoma įgyvendinti programavimo kalba, integruota į 1C: Enterprise. Visų pirma, ši klasė apima užduotis, kurioms reikalinga žemo lygio sąveika su operacine sistema, pavyzdžiui, norint dirbti su konkrečia įranga.
Sistema 1C: Enterprise išoriniams komponentams kurti naudoja dvi technologijas:
  • naudojant Native API
  • naudojant COM technologiją
Atsižvelgiant į pateiktus apribojimus, skirtumas tarp dviejų aukščiau paminėtų technologijų yra nereikšmingas, todėl svarstysime vaizdo žaidimų kūrimą naudojant Native API. Jei reikia, įgyvendintus patobulinimus galima pritaikyti kuriant kompiuterių programinę įrangą naudojant COM technologiją, o taip pat su nedideliais pakeitimais pritaikyti naudoti sistemoje 1C: Enterprise su kitomis veikimo galimybėmis, išskyrus failo veikimo režimą.
VK struktūra
Išorinis 1C: Enterprise sistemos komponentas pateikiamas DLL bibliotekos pavidalu. Bibliotekos kodas apibūdina palikuonių klasę IComponentBase. Sukurta klasė turi apibrėžti metodus, atsakingus už išorinio komponento funkcijų įgyvendinimą. Nepaisyti metodai bus išsamiau aprašyti toliau, kai pateikiama medžiaga.

Demonstracinio VK paleidimas

Užduotis:
  1. Surinkite išorinį komponentą, tiekiamą su ITS prenumerata ir skirtą parodyti pagrindines išorinio komponento mechanizmo galimybes 1C.
  2. Prijunkite demonstracinį komponentą prie 1C konfigūracijos
  3. Įsitikinkite, kad deklaruotos funkcijos veikia tinkamai
Kompiliacija
Demonstracinė VK yra ITS prenumeratos diske „/VNCOMP82/example/NativeAPI“ kataloge.
Norėdami sukurti demonstracinį VC, naudosime Microsoft Visual Studio 2008. Kitos šio produkto versijos nepalaiko naudojamo Visual Studio projekto formato.


Atidarykite AddInNative projektą. Į projekto nustatymus įtraukiame katalogą su antraščių failais, reikalingais projektui sukurti. Pagal numatytuosius nustatymus jie yra ITS diske, esančiame kataloge /VNCOMP82/įtraukti.
Konstravimo rezultatas yra failas /bind/AddInNative.dll. Tai yra sudaryta biblioteka, skirta prisijungti prie 1C konfigūracijos.
VK prijungimas prie 1C konfigūracijos
Sukurkime tuščią 1C konfigūraciją.
Toliau pateikiamas valdomos programos modulio kodas.
kintamasis DemoComp; Procedūra, kai sistema paleidžiama () Prijunkite išorinį komponentą ("...\bind\AddInNative.dll", "DemoVK", išorinio komponento tipas. Native); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); Procedūros pabaiga
Jei paleidžiant 1C konfigūraciją nebuvo pranešta apie klaidą, VK buvo sėkmingai prijungtas.
Vykdant aukščiau pateiktą kodą, konfigūracijos visuotiniame matomumo lange atsiranda objektas DemoComp, kurios savybės ir metodai yra apibrėžti išorinio komponento kode.
Integruoto funkcionalumo demonstravimas
Patikrinkime demonstracinės VK funkcionalumą. Norėdami tai padaryti, pabandykime nustatyti ir perskaityti kai kurias ypatybes, iškviesti kai kuriuos VK metodus, taip pat gauti ir apdoroti VK pranešimą.
ITS diske pateiktoje dokumentacijoje nurodomos šios demonstracinės VC funkcijos:
  1. Valdymo komponento objekto būsena
    Metodai: Įjungti, Išjungti
    Savybės: Įskaitant
  2. Laikmačio valdymas
    Kas sekundę komponentas siunčia pranešimą „1C: Enterprise“ sistemai su parametrais Komponentas, Laikmatis ir sistemos laikrodžio skaitiklio linija.
    Metodai: StartTimer, Sustabdyti laikmatį
    Savybės: Yra laikmatis
  3. Metodas ShowInStatusLine, kuri būsenos eilutėje rodo metodui perduotą tekstą kaip parametrus
  4. Metodas Įkelti paveikslėlį. Įkelia vaizdą iš nurodyto failo ir perkelia jį į 1C: Enterprise sistemą dvejetainių duomenų pavidalu.
Įsitikinkite, kad šios funkcijos veikia. Norėdami tai padaryti, paleiskite šį kodą:
kintamasis DemoComp; Procedūra, kai sistema paleidžiama() ConnectExternalComponent(...); DemoComp = New("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Disable(); Report(DemoComp.Enabled); DemoComp.Enable(); Report(DemoComp.Enabled); DemoComp.StartTimer(); Procedūros pabaigos procedūra Išorinio įvykio apdorojimo (šaltinis, įvykis, duomenys) ataskaita (šaltinis + " " + įvykis + " " + duomenys); Procedūros pabaiga
Konfigūracijos vykdymo rezultatas parodytas paveikslėlyje


Skydelyje „Pranešimai“ rodomi metodų iškvietimų rezultatai DemoComp.Disable() Ir Demo.Comp.Enable(). Tolesnėse to paties skydelio eilutėse pateikiami iš VK gautų pranešimų apdorojimo rezultatai - Šaltinis, Renginys Ir Duomenys atitinkamai.

Pasirinktinis išorinio komponento pavadinimas

Užduotis: pakeiskite išorinio komponento pavadinimą į savavališką.
Ankstesnėje dalyje buvo naudojamas identifikatorius AddInNativeExtension, kurios reikšmė nebuvo paaiškinta. Tokiu atveju AddInNativeExtension– tai plėtinio pavadinimas.
VK kodas apibrėžia metodą RegistruotisPlėtinysAs, grąžindamas pavadinimą į sistemą 1C: Enterprise, kuris reikalingas vėlesniam VK registravimui sistemoje. Rekomenduojama nurodyti identifikatorių, kuris tam tikru mastu atskleidžia išorinio komponento esmę.
Čia yra visas metodo kodas RegistruotisPlėtinysAs su pakeisto plėtinio pavadinimu:
bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) ( wchar_t *wsExtension = L"SomeName"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* tikslas = 0; if (m_m_Memory_Memory ((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, iActualSize) return false;
Pateiktame pavyzdyje VK pavadinimas pakeistas į SomeName. Tada prisijungdami prie VK turite nurodyti naują pavadinimą:
DemoComp = New("AddIn.DemoVK.SomeName");

Išplečiamas VK savybių sąrašas

Užduotis:
  1. Ištirti VK savybių įgyvendinimą
  2. Pridėkite eilutės tipo skaitymo / rašymo savybę
  3. Pridėkite skaitymo / rašymo eilutės ypatybę, kurioje saugomas paskutinio ypatybių rinkinio duomenų tipas. Nustatant nuosavybės vertę neatliekama jokių veiksmų

Kad nustatytų kuriamo komponento ypatybes, kūrėjas AddInNative.cpp bibliotekos kode turi įdiegti šiuos metodus:
GetNprops
Grąžina šio plėtinio ypatybių skaičių, 0, jei ypatybių nėra
FindProp
Grąžina nuosavybės, kurios pavadinimas perduotas parametruose, serijos numerį
GetPropName
Grąžina nuosavybės pavadinimą pagal serijos numerį ir perduotą kalbos identifikatorių
GetPropVal
Grąžina turto vertę nurodytu eilės numeriu
SetPropVal
Nurodo turto vertę nurodytu eilės numeriu
IsPropReadable
Grąžina nuosavybės skaitomumo vėliavėlę su nurodytu eilės numeriu
IsPropWritable
Grąžina nuosavybės įrašymo vėliavėlę su nurodytu eilės numeriu


Panagrinėkime aukščiau pateiktų klasės metodų įgyvendinimą CAddInNative.
Demonstracinėje VC apibrėžiamos 2 savybės: Įskaitant Ir Yra laikmatis (Įjungta Ir IsTimerPresent).
Visuotinėje bibliotekos kodo apimtyje yra apibrėžti du masyvai:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent"); static wchar_t *g_PropNamesRu = (L"Įjungta", L"Yra laikmatis");
kuriuose saugomi rusiški ir angliški nuosavybės pavadinimai. Antraštės faile AddInNative.h sąrašas yra apibrėžtas:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Visada paskutinis );
ePropIsEnabled Ir ePropIsTimerPresent, turinčios atitinkamai reikšmes 0 ir 1, naudojami savybių serijos numeriams pakeisti reikšmingais identifikatoriais. ePropLast, kurio reikšmė yra 2, naudojama ypatybių skaičiui gauti (naudojant GetNprops metodą). Šie pavadinimai naudojami tik komponento kode ir nepasiekiami išorėje.
Metodai FindProp ir GetPropName atlieka masyvo paieškas g_PropNames Ir g_PropNamesRu.
Norėdami išsaugoti bibliotekos modulio laukų reikšmes, CAddInNative klasėje yra ypatybių, kuriose saugoma komponento ypatybių reikšmė. Metodai GetPropVal Ir SetPropVal grąžinti ir atitinkamai nustatyti šių savybių vertę.
Metodai IsPropReadable Ir IsPropWritable ir grįžti tiesa arba klaidinga, priklausomai nuo perduodamo turto eilės numerio pagal taikymo logiką.
Norėdami pridėti pasirinktinę nuosavybę, turite:

  1. Pridėkite prie masyvų pridedamos nuosavybės pavadinimą g_PropNames Ir g_PropNamesRu(failas AddInNative.cpp)
  2. Išvardinti Rekvizitas(failas AddInNative.h) anksčiau ePropLast pridėkite pavadinimą, kuris vienareikšmiškai identifikuoja pridedamą nuosavybę
  3. Tvarkykite atmintį savybių vertėms saugoti (sukurkite modulio komponentų laukus, kuriuose saugomos atitinkamos reikšmės)
  4. Pakeiskite metodus GetPropVal Ir SetPropVal sąveikauti su atmintimi, skirta ankstesniame veiksme
  5. Vadovaudamiesi taikymo logika, pakeiskite metodus IsPropReadable Ir IsPropWritable
1, 2, 5 punktų paaiškinti nereikia. Išsamią informaciją apie šių žingsnių įgyvendinimą galite rasti perskaitę straipsnio priedą.
Suteikime pavadinimus testo savybėms Testas Ir Tipo patikrinimas atitinkamai. Tada, atlikdami 1 veiksmą, turime:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"); static wchar_t *g_PropNamesRu = (L"Įjungta", L"Yra laikmatis", L"Test", L"Tipo patikra");
Perdavimas Rekvizitas atrodys taip:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Visada paskutinis );
Norėdami žymiai supaprastinti kodą, naudosime STL C++. Ypač darbui su stygomis WCHAR, prijungkime biblioteką wstring.
Norėdami išsaugoti metodo reikšmę Testas, mes apibrėžiame klasėje CAddInNative privačioje srityje:
stygos testas1;
Norėdami perkelti eilutės parametrus tarp 1C: Enterprise ir išorinių komponentų, naudojama 1C: Enterprise atminties tvarkyklė. Pažvelkime į jo darbus atidžiau. Funkcijos naudojamos atitinkamai paskirstyti ir atlaisvinti atmintį AllocMemory Ir Laisva atmintis apibrėžta faile „ImemoryManager.h“. Jei reikia perduoti eilutės parametrą 1C: Enterprise sistemai, išorinis komponentas turi skirti jam atmintį iškviesdamas funkciją AllocMemory. Jo prototipas atrodo taip:
virtualus bool ADDIN_API AllocMemory (tuščia** pAtmintis, nepasirašytas ilgas ulCountByte) = 0;
Kur pAtmintis- rodyklės, į kurią bus patalpintas paskirtos atminties srities adresas, adresas,
ulCountByte- skirtos atminties srities dydis.
Eilutės atminties paskirstymo pavyzdys:
WCHAR_T *t1 = NULL, *testas = L"TEST_STRING"; int iActualus dydis = wcslen(test1)+1; m_iMemory->AllocMemory((void**)&t1, iActualSize * sizeof(WCHAR_T)); ::convToShortWchar(&t1, test1, iActualSize);
Kad būtų patogiau dirbti su eilučių duomenų tipais, apibūdinsime funkciją wstring_to_p. Jis kaip parametras gauna wstring eilutę. Funkcijos rezultatas yra užpildyta struktūra tVariantas. Funkcijos kodas:
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; grąžinti tiesa)
Tada atitinkamas atvejis skirsnis jungiklis pareiškimo metodas GetPropVal bus tokia forma:
atvejis ePropTest1: wstring_to_p(test1, pvarPropVal); pertrauka;
Metodas SetPropVal:
case ePropTest1: if (TV_VT(varPropVal) != VTYPE_PWSTR) return false; testas1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); pertrauka;
Norėdami įgyvendinti antrąją savybę, apibrėžiame klasės lauką „CaddInNative“.
uint8_t last_type;
kuriame išsaugosime paskutinės perduotos vertės tipą. Norėdami tai padaryti, pridėkite komandą prie CaddInNative::SetPropVal metodo:
paskutinis_tipas = TV_VT(varPropVal);
Dabar, kai prašome perskaityti antrojo turto vertę, mes grąžinsime vertę paskutinis_tipas, ko reikalauja paskirta užduotis.
Patikrinkime atliktų pakeitimų funkcionalumą.
Norėdami tai padaryti, pateiksime 1C konfigūracijos išvaizdą taip:
kintamasis DemoComp; Procedūra, kai sistema paleidžiama() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.TypeCheck = 1; Report(String(DemoComp.TypeCheck)); DemoComp.Test = "Vasya"; Report(String(DemoComp.Test)); DemoComp.Test = "Petya"; Report(String(DemoComp.Test)); Report(String(DemoComp.TypeCheck)); Procedūros pabaiga
Po paleidimo gausime pranešimų seką:
3
Vasja
Petras
22

Antrasis ir trečiasis pranešimai yra ankstesniame veiksme nustatytos nuosavybės nuskaitymo rezultatas. Pirmame ir antrame pranešimuose yra paskutinio ypatybių rinkinio tipo kodas. 3 atitinka sveikojo skaičiaus reikšmę, 22 – eilutės reikšmę. Byloje nustatytas tipų ir jų kodų atitikimas tipai.h, kuris yra ITS diske.

Metodų sąrašo išplėtimas

Užduotis:
  1. Išplėskite išorinio komponento funkcionalumą šiomis funkcijomis:
  2. Ištirkite išorinių komponentų metodų diegimo būdus
  3. Pridėkite funkcijos metodą Funkcija1, kuris kaip parametras naudoja dvi eilutes („Parameter1“ ir „Parameter2“). Rezultatas yra tokia eilutė: „Tikrinimas. 1 parametras, 2 parametras
  4. Įsitikinkite, kad atlikti pakeitimai veikia.

Norėdami apibrėžti kuriamo komponento metodus, kūrėjas turi įdiegti šiuos metodus AddInNative bibliotekos kode:
GetNMethods, FindMethod, GetMethodName
Sukurta gauti atitinkamą metodų skaičių, ieškokite metodo numerio ir pavadinimo. Panašus į atitinkamus savybių metodus
GetNParams
Grąžina metodo parametrų skaičių su nurodytu eilės numeriu; jei metodo su šiuo numeriu nėra arba jis neturi parametrų, grąžina 0
GetParamDefValue
Grąžina numatytąją nurodyto metodo nurodyto parametro reikšmę
HasRetVal
Grąžina vėliavėlę, ar metodas su nurodyta eiline grąžinimo reikšme turi grąžinimo reikšmę: true metodams su grąžinimo reikšme ir klaidinga kitaip
CallAsProc
klaidinga, įvyksta vykdymo klaida ir 1C: Enterprise modulio vykdymas nutraukiamas. Atmintį parametrų masyvei skiria ir išleidžia 1C: Enterprise.
CallAsFunc
Vykdo metodą su nurodytu eilės numeriu. Jei metodas grįžta klaidinga, įvyksta vykdymo klaida ir 1C: Enterprise modulio vykdymas nutraukiamas. Atmintį parametrų masyvei skiria 1C: Enterprise. Jei grąžinama reikšmė yra eilutė arba dvejetainis duomenų tipas, komponentas priskiria atmintį funkcijai AllocMemory atminties tvarkyklę, įrašo ten duomenis ir išsaugo šį adresą atitinkamame struktūros laukelyje. 1C: Įmonė atlaisvins šią atmintį paskambinusi Laisva atmintis.
Išsamus metodų aprašymas, įskaitant parametrų sąrašą, yra išsamiai aprašytas dokumentacijoje, pateiktoje ITS diske.
Panagrinėkime aukščiau aprašytų metodų įgyvendinimą.
Komponento kode yra apibrėžti du masyvai:
static wchar_t *g_MethodNames = (L"Įgalinti", L"Išjungti", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"); static wchar_t *g_MethodNamesRu = (L "Įgalinti", L "Išjungti", L "ShowInStatusLine", L "StartTimer", L "StopTimer", L "LoadImage");
ir išvardijimas:
enum Methods ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Visada paskutinis );
Jie naudojami funkcijose GetNMethods, FindMethod Ir GetMethodName, pagal analogiją su savybių aprašymu.
Metodai GetNParams, GetParamDefValue, HasRetVal padargo jungiklis, priklausomai nuo perduodamų parametrų ir programos logikos, grąžina reikiamą reikšmę. Metodas HasRetVal jo kode yra tik metodų, galinčių grąžinti rezultatą, sąrašas. Už juos jis grįžta tiesa. Visiems plieno metodams grąžinti klaidinga.
Metodai CallAsProc Ir CallAsFunc yra tiesiogiai vykdomas metodo kodas.
Norėdami pridėti metodą, kurį galima iškviesti tik kaip funkciją, turite atlikti šiuos išorinio komponento šaltinio kodo pakeitimus:
  1. Pridėkite metodo pavadinimą prie masyvų g_MethodNames Ir g_MethodNamesRu(failas AddInNative.cpp)
  2. Pridėkite reikšmingą metodo identifikatorių prie Metodų sąrašo (failas AddInNative.h)
  3. Pakeiskite funkcijos kodą GetNParams pagal programos logiką
  4. Jei reikia, pakeiskite metodo kodą GetParamDefValue, jei norite naudoti numatytąsias metodo parametrų reikšmes.
  5. Atlikite funkcijos pakeitimus HasRetVal
  6. Pakeiskite funkcijų logiką CallAsProc arba CallAsFunc, įdėdami ten tiesiogiai vykdomą metodo kodą
Pateikiame masyvus g_MethodNames Ir g_MethodNamesRu, taip pat sąrašas Metodaiį formą:
static wchar_t *g_MethodNames = (L"Įgalinti", L"Išjungti", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"); static wchar_t *g_MethodNamesRu = (L "Įgalinti", L "Išjungti", L "ShowInStatusLine", L "StartTimer", L "StopTimer", L "LoadPicture", L "Test");

Enum metodai ( eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Visada paskutinis );
Redaguojame funkciją GetNprops kad būtų grąžintas „Test“ metodo parametrų skaičius:
long CAddInNative::GetNParams(const long lMethodNum) ( switch(lMethodNum) ( case eMethShowInStatusLine: return 1; case eMethLoadPicture: return 1; case eMethTest: return 2; default: return 0; ) return 0; )
Pakeiskime funkciją:
bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) (TV_VT(pvarParamDefValue)= VTYPE_EMPTY; switch(lMethodNum) (case: eMethIntuseLcase: MethStartTimer: atvejis eMethStopTimer: atvejis eMethTest : / / Pagal numatytuosius nustatymus nėra parametrų reikšmių: return false;
Dėl pridėtos linijos
atvejis eMethTest:
jei trūksta vieno ar daugiau argumentų, atitinkami parametrai turės tuščią reikšmę ( VTYPE_EMPTY). Jei jums reikia numatytosios parametro reikšmės, turėtumėte ją nustatyti skyriuje eMethTest funkcijų jungiklio teiginys CAddInNative::GetParamDefValue.
Kadangi bandymo metodas gali grąžinti reikšmę, turite pakeisti funkcijos kodą HasRetVal:
bool CAddInNative::HasRetVal(const long lMethodNum) ( switch(lMethodNum) ( case eMethLoadPicture: case eMethTest: return true; default: return false; ) return false; )
Ir pridėkite vykdomąjį metodo kodą prie funkcijos CallAsFunc:
bool CAddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) ( ... std::wstring s1, s2; switch(lMethodNum) ( case eMethLoadTesticture:MethLoadT; if (!lSizeArray || !paParams) return s1 = (paParams) -> pwstrVal (paParams+1) -> pwstring_to_p(std::wstring(s1+s2), pvarRetValue; ;
Sukompiliuokime komponentą ir perkelkime konfigūracijos kodą į formą:
kintamasis DemoComp; Procedūra, kai sistema paleidžiama() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); juosta = DemoComp.Test("Sveiki", "Pasaulis!"); Ataskaita(per); Procedūros pabaiga
Paleidę konfigūraciją, gausime pranešimą: "Sveikas, pasauli!", kuris rodo, kad metodas sėkmingai veikė.

Laikmatis

Užduotis:
  1. Išstudijuokite laikmačio įgyvendinimą demonstraciniame VK
  2. Modifikuokite „StartTimer“ metodą, įtraukdami į parametrus galimybę perduoti laikmačio atsako intervalą (milisekundėmis)
  3. Įsitikinkite, kad atlikti pakeitimai veikia.

WinAPI galite naudoti pranešimą, kad galėtumėte dirbti su laiku WM_TIMER. Šis pranešimas bus išsiųstas jūsų programai laiko intervalu, kurį nustatėte kurdami laikmatį.
Norėdami sukurti laikmatį, naudokite funkciją Nustatyti laikmatį:
UINT SetTimer(HWND hWnd, // lango aprašas UINT nIDevent, // laikmačio identifikatorius (skaičius) UINT nElapse, // delsa TIMERPROC lpTimerFunc); // rodyklė į funkciją
Operacinė sistema išsiųs pranešimą WM_TIMERį programą su argumente nurodytu intervalu nElapse(milisekundėmis). Paskutiniame parametre galite nurodyti funkciją, kuri bus vykdoma kiekvieną kartą, kai suveikia laikmatis. Šios funkcijos antraštė turėtų atrodyti taip (pavadinimas gali būti bet koks):
negalioja __stdcall TimerProc (HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Panagrinėkime laikmačio įgyvendinimą demonstraciniame VC.
Kadangi svarstome išorinio „Windows“ OS šeimos komponento kūrimo procesą, laikmačio diegimo kitose operacinėse sistemose nesvarstysime. Visų pirma GNU/Linux OS diegimas skirsis funkcijos sintaksė Nustatyti laikmatį Ir TimerProc.
Vykdomasis kodas iškviečia metodą Nustatyti laikmatį, kuriai perduodama funkcija MyTimerProc:
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
Sukurto laikmačio ID dedamas į kintamąjį m_uiTimer kad vėliau būtų galima jį išjungti.
Funkcija MyTimerProc taip:
VOID CALLBACK MyTimerProc(HWND hwnd, // laikmačio pranešimų lango rankena UINT uMsg, // WM_TIMER pranešimas UINT idEvent, // laikmačio identifikatorius DWORD dwTime // dabartinis sistemos laikas) (jei (!pAsyncEvent) grįžta; wchar_t *who "ComponentNative", *what = L"Laikmatis"; wchar_t *wstime = naujas wchar_t; jei , what, wstime);
Funkcijos esmė ta, kad metodas vadinamas Išorinis įvykis, kuris siunčia pranešimą į 1C: Enterprise sistemą.
Norėdami išplėsti metodo funkcionalumą StartTimer Atlikime šiuos veiksmus:
Metodo kodo keitimas GetNParams kad tai būtų skirta metodui „eMethStartTimer“. grąžinta 1 vertė:
atvejis eMethStartTimer: grįžti 1;
Čia yra metodo kodas CallAsProcį formą:
atvejis 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;
Dabar patikrinkime funkcionalumą. Norėdami tai padaryti, parašysime kodą konfigūracijos valdomame programos modulyje:
kintamasis DemoComp; Procedūra, kai sistema paleidžiama() Connect External Component("...", "DemoVK", External Component Type.Native); DemoComp = New("AddIn.DemoVK.SomeName"); DemoComp.StartTimer(2000); Procedūros pabaiga
Pradėjus konfigūraciją, programa kas 2 sekundes gaus pranešimus, kurie rodo, kad laikmatis veikia tinkamai.

Sąveika su 1C: Enterprise sistema

Norėdami sąveikauti tarp išorinio komponento ir 1C: Enterprise sistemos, IAddInDefBase klasės metodai, aprašyti faile AddInDefBase.h. Mes išvardijame dažniausiai naudojamus:
Klaidos pranešimo generavimas
virtualus bool ADDIN_API AddError (nepasirašytas trumpas wkodas, pastovus WCHAR_T* šaltinis, const WCHAR_T* aprašas, ilgas kodas)
wcode, kodą- klaidų kodai (klaidų kodų sąrašą su aprašymais galite rasti ITS diske)
šaltinis- klaidos šaltinis
descr- klaidos aprašymas
Pranešimo siuntimas į „1C: Enterprise“ sistemą
virtualus bool ADDIN_API išorinis įvykis(WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;
wszŠaltinis- pranešimo šaltinis
wszMessage- Pranešimo tekstas
wszData- perduoti duomenys
Pranešimų perėmimas atliekamas naudojant išorinio įvykių apdorojimo procedūrą
Išorinio komponento registracija sistemoje 1C: Enterprise
virtualus bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszProfileName- komponento pavadinimas.
Šių metodų pakanka pilnai VK ir 1C sąveikai. Norėdami gauti duomenis iš išorinio komponento iš 1C: Enterprise sistemos ir atvirkščiai, išorinis komponentas siunčia specialų pranešimą, kurį savo ruožtu perima 1C sistema ir, jei reikia, iškviečia išorinio komponento metodus duomenims perduoti atgal. .

tVarianto duomenų tipas

Keičiant duomenis tarp išorinio komponento ir 1C: Enterprise sistemos, naudojamas duomenų tipas tVariant. Jis aprašytas type.h faile, kurį galima rasti ITS diske:
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 uintt.3; uint16_t uintt2; _t errCode bVal; struct tmVal; pInterfaceVal __VARIANT_NAME_2/*iface*/; ) __VARIANT_NAME_1 matmenų masyvas pvarVal TYPEVAR vt);
Tipas tVariantas yra struktūra, kurią sudaro:
  • mišinys (sąjunga), skirtas tiesiogiai duomenims saugoti
  • duomenų tipo identifikatorius
Apskritai, darbas su tipo kintamaisiais tVariantas vyksta pagal šį algoritmą:
  1. Šiuo metu kintamajame saugomų duomenų tipo nustatymas
  2. Norėdami tiesiogiai pasiekti duomenis, eikite į atitinkamą mišinio lauką
Naudojant tipą tVariantasžymiai supaprastina 1C: Enterprise sistemos ir išorinių komponentų sąveiką

Taikymas

Kataloge „pavyzdžiai“ yra straipsnio pavyzdžių
examples/1 – paleiskite demonstracinį komponentą
pavyzdžiai/2 - nuosavybės sąrašo išplėtimo demonstravimas
pavyzdžiai/3 - metodų sąrašo išplėtimo demonstravimas
Kiekviename kataloge yra VS 2008 projektas ir paruošta 1C konfigūracija.