QO‘NG‘IROQ

Bu xabarni sizdan oldin o'qiganlar bor.
Eng so'nggi maqolalarni olish uchun obuna bo'ling.
Elektron pochta
Ism
Familiya
Qo'ng'iroqni qanday o'qishni xohlaysiz
Spam yo'q

Savol: 1C 8.3 da Linux (Ubuntu x64) uchun C++ da tashqi Native Api komponenti


Men VK yozyapman, ubuntuda 1s ga ulana olmayapman. Hatto 1 dan olingan misol ham ulanmagan. Shunday qilib, bu haqda savol:

1) Men maqolada keltirilgan VNCOMPS misolidan VK ni ulashga harakat qilaman

(havolani eng oxirida topish mumkin: "Nusxa olish").
Ichkarida NativeApi loyihasi makefilega ega. U bilan men Ununtu-da .so kutubxonasini quraman.
Ammo "Tashqi komponentni ulash" da 1 chiqadi.
Xuddi shunday, agar men "build.sh" yordamida qursam (loyihaning ildizida).

Makefile-ning o'zida men bayroqni m32 dan m64 ga o'zgartiraman, chunki 1c va x64 tizimining o'zi. (m32 parametri bilan u baribir qabul qilmaydi)
1C 8.3 dan VK ga qo'ng'iroq qilish misoli:
Ulanish tugadi = Tashqi komponentni ulang("/home/alexeyubuntux64-20 gb/Documents/VNCOMP83/example/NativeAPI/AddInNative.so", "AddInNative", ExternalComponentType.Native); Aynan shu mavzuda maqola bor.
Ammo, men ko'rib turganimdek, bu fikrlarning barchasi allaqachon VNCOMPS misolida hisobga olingan va tuzatilgan.

Ammo, aslida, kompilyatsiya parametrlarida biznes. MB 32bit tashqi komponenti odatda 32bit 1c gacha ulanadi, lekin men Ubuntu x64 1c Enterprise83 8.3.5-1486 amd64 da oʻrnatdim. Va men unga VK ni olmoqchiman.

Kimdir bu muammoni qanday hal qilish haqida biron bir fikrga egami?
VNCOMPS misoli ishlashi kerak, lekin qurish parametrlarini tuzatish kerak yoki men sinab ko'rayotgan platformaning o'zi noto'g'ri.

Javob: Qizig'i shundaki, Javada tashqi komponent yozish mumkinmi?

Savol: Tashqi komponent (Native) ulanmagan


64 va 32 bitli tizimlar uchun ITS bilan misol tuzildi.

Men shunday ulanaman:
ConnectionResult = ConnectExternalComponent(CDLLPath, "Comp", ExternalComponentType.Native); Bir kompyuter ulanadi, ikkinchisi ulanmaydi. OSda farq bor. Ulanish qayerda bo'lsa, Win7 mavjud, Win10 yo'q. Shu bilan birga, standart komponentlar mening komponentim ishlamaydigan kompyuterda ishlaydi.

Turli platformalarda sinovdan o'tgan (8.3.4.482, 8.3.6.2100, 8.3.11.2700, 8.3.12.1412).

Nima uchun u bog'lanmaganligini qanday tushunish mumkin?

Javob: vc_redist unutmadimi?

Savol: 1C8 va Native turiga ega tashqi komponent


Hayrli kun.
BP 3.0.50.12 konfiguratsiyasi va UniServerAuto yordamida Scales-Soft kompaniyasidan tortishni amalga oshirish istagi mavjud.
Ishlab chiquvchilar Windows 32 va 64 uchun Native komponentini kompilyatsiya qilishdi va uni eng muhim fayl bilan arxivga qo'yishdi. 1C uchun misol ham bor, vaznni qanday hisoblash mumkin. Unda, ikkilik ma'lumotlarga ega bo'lgan tartib yordamida, men tushunganimdek, ushbu arxiv ko'rsatilgan. Misolda, hamma narsa yaxshi: komponent o'rnatiladi, ulanadi, keyin ulanish o'rnatiladi va og'irlik o'qiladi.
Ammo siz o'zingizni 1C ga o'tkazishni boshlaganingizdan so'ng, vazn o'qilmaydi. Hamma narsa oddiygina yozilganga o'xshaydi, lekin men rake qayerda ekanligini tushunmayapman.
Kimga bir oz vaqt bo'ladi - yordam bering, bir ko'z bilan qarang, ehtimol yechim sirtda, lekin men noto'g'ri joyda yurib, noto'g'ri ish qilyapman. Men ilgari hech qachon Native texnologiyasi bilan ishlamaganman ...

Va ilovada mening qayta ishlash matnim

Javob:

Xo'sh, menda yangilik bor ...
Men faqat qaysi nuqtada muvaffaqiyatsizlikka uchraganini bosqichma-bosqich ko'rib chiqishni boshladim. Buning uchun men bo'sh ma'lumotlar bazasini yaratdim va buyruq bilan ishlov berdim. Yetkazib beruvchining misoliga o'xshab, men tartibni yangi konfiguratsiyaga o'tkazdim - u ikkinchi marta ishlaydi. Bular. Birinchi marta yo'q, ikkinchi marta ha. Bu esa, uni qayta ishlashda komponent va ob'ektning ulanishini turli xil protseduralar bo'yicha ajratish hali ham zarur bo'ladi degan fikrni uyg'otdi.
Keyin uni tartib ulanishi bilan ma'lumotlar bazasiga o'tkazdim - u ishlaydi. Fuh, bu allaqachon yaxshi .... Lekin men konfiguratsiyaga o'zgartirish kiritmasdan buni xohlardim, shuning uchun davom etamiz

Men ishlov berish uchun tartib qo'shishga harakat qilyapman. Uning o'lchami darhol 10 kb dan 3 mb gacha oshadi va sezilarli sekinlashuv seziladi - u mos kelmaydi. Men komponentni dll orqali ulashga kirishaman. Bular. asosan siz boshlagan joyingiz bilan bir xil. Ammo bitta "BUT" bor: foydalanuvchi papkasida dll nomini qidirib, men ushbu dll 1C da ro'yxatdan o'tgan dll fayllari qo'shilgan joyda joylashganligini payqadim:
C:\Users\USER\AppData\Rouming\1C\1cv8\ExtCompT
Shunga ko'ra, dll ga to'liq yo'lni ishlatishning hojati yo'q, siz shunchaki uning nomini yozishingiz mumkin:
ConnectExternalComponent("Add1CUniServerAuto32.dll", "UniServerAuto", ExternalComponentType.Native);

Men harakat qilaman ... ro'yxatga olishda qasam ichaman, lekin tortish natijasini qaytaradi. Ma'lum bo'lishicha, dll allaqachon ro'yxatdan o'tgan, ya'ni uni ulash kifoya. Men uni olib tashlayman va hamma narsa ishlaydi.
Men umumlashtiraman:
1. Ochish jarayonida tortishni qayta ishlashda men tashqi komponentning ulanishini va ob'ektga ulanishni qo'shdim.
2. Dll ga yo'lni men yozmadim, faqat uning nomini ko'rsatdim.

Endi men o'tiraman va o'ylayman, dll qachon 1C da o'rnatilgan? Dasturiy ta'minotni o'rnatish vaqtida? Qiyin... Ushbu dll ning ishlab chiquvchi konfiguratsiyasini ishga tushirish vaqtida, forma ochilganda u qayerga o'rnatiladi? Bilmadim, lekin menga yaqindek tuyuladi... Nima deb o'ylaysiz?
Ikkinchidan, yangi joyda, xuddi shu terminalni o'rnatish zarurati tug'ilganda, hamma narsa ishlashi uchun nima qilish kerak? Dasturiy ta'minotni to'liq o'rnating, ishni tekshirish uchun etkazib beruvchining konfiguratsiyasini ishga tushiring va keyin (nazariy jihatdan) mening ishlovim ishlashi kerakmi? Biroz murakkab narsa... Yoki dasturiy ta'minotni qayta ishlashimga o'rnatgandan so'ng, InstallExternalComponent-ni bir marta bajaringmi?

Bu boradagi fikringizni eshitishni istardim...

Savol: Tashqi komponent.dll


Hammaga xayrli kun.
Savol.
dll komponenti 1C 7.7 da yaxshi ishlaydi
1s 8.1 da umuman yuklashni xohlamaydi ...
Uni C:\Program Files\1cv81\bin\cache1c.dll-ga joylashtirishga harakat qildim.
Men regsvr32 "C:\Program Files\1cv81\bin\cache1c.dll" yordamida ro'yxatdan o'tishga harakat qildim.
Muammosiz ro'yxatdan o'tgan.
Unga kirishga harakat qilganimda xato xabari olaman:

Tashqi komponentni yuklashda xatolik yuz berdi! cache1c.dll
Tugmachani bosish (tugma) tashqi komponentni yuklashga urinish ( "C:\Program Files\1cv81\bin\cache1c.dll"); Istisno hisoboti( "Tashqi komponentni yuklashda xatolik yuz berdi!"+ "cache1c.dll"); Urinishning tugashi; Urinish // Komponent ob'ektini olish. // m = Yangi ("cache1c.GTMcmd" ); m = Yangi COMObject("cache1c.GTMcmd" ); Istisno hisoboti(); Urinishning tugashi; EndProcedure

Javob: Mumkin bo'lmagan darajaga qadar ...
Qo'ng'iroqlar (millisekundlar) orasidagi pauzalarni ushlab turish kerak ...
Protsedura ButtonExecuteClick(Button) urinishi // Komponent obyektini oling. m = Yangi COMObject("cache1c.GTMcmd" ); Istisno hisoboti( "Tashqi komponent ob'ektini yaratib bo'lmadi"); Urinishning tugashi; m.RemoteHost = "192.168.1.101" ; m.RemotePort = 6330; m.Connect(); m.Pauza(100); ...... va hokazo
1s 7.7 uchun - bu kerak emas, aylanish tezroq bo'lib chiqadi.

Savol: 1C serveri bilan tashqi komponentning ishlashi ...


Hayrli kun,

C ++ da yozilgan tashqi komponent mavjud bo'lib, uning vazifasi tashqi ma'lumotlar bazasidan ma'lumot olish va so'rov natijasini 1C da qiymatlar jadvali shaklida qaytarishdir.
Hozirgi vaqtda qiymatlar jadvalini shakllantirish uchun Init() funksiyasida parametr sifatida qabul qilinadigan IDispatch* pBackConnection interfeysi ishlatiladi. Bundan tashqari, men 1C funktsiyalaridan foydalanib, qiymatlar jadvalini tuzaman, uni to'ldiraman va CallAsFunc (...) ning ikkinchi parametriga qaytaraman.
Muammolar 1C nozik mijozlarga o'tish bilan boshlandi. Server tomonida tashqi komponent aslida ishga tushmaydi. Siz uni mijoz tomonida ishga tushirishingiz mumkin, ammo barchasi tayoqchaga o'xshaydi va 1Cda umumiy "mijoz-server" mantig'idan chiqib ketadi. Masalan, mijoz qiymatlar jadvali nima ekanligini, "global" o'zgaruvchilar bilan bog'liq muammolar, seanslar va boshqalarni tushunmaydi.
NativeAPI bu borada yanada qisqartirilgan.
Daf bilan raqsga tushish men 1C serveri ostida tashqi komponentni ishga tushirishimga olib keldi, LEKIN ish pBackConnection-da Invoke-ga qo'ng'iroq qilishga urinmaguncha davom etadi. Server 8.2 ning 64-bitli versiyasi kutish vaqti tugamaguncha biror narsa qilishga harakat qiladi, 32-bitli versiya (VK tabiiy ravishda 32-bit) darhol tushib ketadi.
1C serveri ushbu ish rejimiga xizmat qilmaydi deb o'ylayman.
Shunga ko'ra, savollar tug'iladi, bu vaqtinchalikmi yoki 1C mantig'i ushbu ish sxemasini bekor qilish uchun qisqartirilganmi? Agar 1C ning ichki tuzilmalarini (qiymatlar jadvali) shu tarzda yaratishning iloji bo'lmasa, uni C + da yaratishga harakat qilish uchun, printsipial jihatdan, tizim darajasida qiymatlar jadvalining tavsifi mavjudmi? +, uni to'ldiring va keyin faqat qaytish parametri sifatida 1C ni siljiting? Men hech bo'lmaganda qaysi yo'nalishda qazish kerakligini aniqlamoqchiman.

Rahmat.

Javob:

Siz bir narsani yozasiz va boshqa narsani nazarda tutasiz.
1C muhitida turli seanslarda ko'rinadigan o'zgaruvchilarni e'lon qilish hozir imkonsiz emas va ilgari ham mumkin emas edi. Boshqa seans jismoniy jihatdan boshqacha jarayondir.
Sessiya ma'lumotlar bazasiga ulanish seansidir, ya'ni. foydalanuvchi sessiyasi. Yoki o'zingizning biror narsangizni va bu kontseptsiyani qo'yasizmi?

Bitta seans ichida seans modulida turli joylarda yashaydigan va ko'rinadigan o'zgaruvchilarni e'lon qilish mumkin edi va hozir ham mumkin ... aslida ulardan 4 tasi bor.
- sessiya moduli;
- oddiy dastur moduli;
- Boshqariladigan dastur moduli;
- Tashqi ulanish moduli.

Va, albatta, siz kontekst haqida eslashingiz kerak. Server konteksti mijoz tomonida bevosita mavjud emas va aksincha.

Umuman olganda, 1C arxitekturasi ma'lumotlar almashinuvi davom etishini ta'minlaydi:
- protseduralar/funksiyalar parametrlari/qaytishi orqali;
- sessiya parametrlari orqali (ular ob'ekt bo'la olmaydi, siz uni aslida palitrada ko'rishingiz mumkin).

Shakldagi jadval... va u ob'ektning har qanday jadvali (masalan, ishlov berish) bilan bog'langanmi? yoki yo'q. Ha bo'lsa, u serverda ham mavjud (&AtServer) va u erda tahrirlang....

Va ha, ValueTable mijoz tomonida UVda mavjud emas. Xo'sh, 1C shunday qaror qildi.

Kel! Bu erda u Excel bilan ishlaydi, FSO va boshqa barcha narsalar bilan ishlaydi, lekin bu erda u ishlamaydi. Xatoni toping va tahlil qiling....

Urinish
...
sizning harakatlaringiz
...
Istisno
str = DescriptionError();
Urinishning tugashi;

Zamonaviy apparat imkoniyatlari bilan bu umuman argument emas.

To'g'ri shaxsiy fikringiz. Haqiqatga hech qanday aloqasi yo'q. Hech qanday tarzda emas. Yana bir bor takrorlayman, 1C COM bilan ajoyib ishlaydi. In-proc va out-proc bilan ham.

O'zingiz yuklagan kodni bering va VK-ga qo'llang.

Aytgancha, VK... sizning holatingizda bu COM yoki Native APImi?
Agar COM bo'lsa, uni regsvr32 orqali... sifatida ro'yxatdan o'tkazsangiz, bit chuqurligi muammosini qanday "hal qilasiz"?

Savol: Tashqi komponentni o'rnatish


Iltimos, menga tashqi komponentni qanday o'rnatishni ayting. Quyidagi kodni bajarishda xatolik yuzaga keladi. Tartibda NameDecl.dll ni toping

SetExternalComponent ("GeneralLayout.Layout") ga urinish; Istisno EndTry ;
Xato: plaginni o'rnatib bo'lmadi!

Javob: ()
ConnectExternalComponent("GeneralLayout.Layout", "NameDecl", ExternalComponentType.Native) FALSE ni qaytaradi,
New("AddIn.NameDecl.CNameDecl", Undefined) = (()): Tur aniqlanmagan (AddIn.NameDecl.NameDecl)

Savol: Native dll 1s 8.1 (fptrwin32_fz54_9_11_0_5549.dll) ga ulanmagan


Salom.
1C fdd 1.05 uchun atol onlayn kassa apparatlari uchun dll-ni yangiladi (fptrwin32_fz54_9_11_0_5549.dll-ga texnik xizmat ko'rsatishga kiritilgan).
Menda eski 1C 8.1 bor. 8.2 dan farqli o'laroq, u 8.2 bilan bir xil tarzda tashqi uskunalar bilan ishlashni qo'llab-quvvatlamaydi, shuning uchun avval dll-ni Windows-da ro'yxatdan o'tkazishingiz kerak va keyin uni faqat 1C ga ulashingiz kerakmi?

ProgID = "AddIn.IntegrationComponent.ATOL_KKT_1C83_V9"; LoadExternalComponent("C:\fptrwin32_fz54_9_11_0_5549.dll"); ConnectExternalComponent (ProgID); Haydovchi = Yangi (ProgID);

Biroq, eski qayta ishlash "texnologiya" com da yozilgan va yangi mahalliy. Shunga ko'ra, ro'yxatdan o'tishda regsvr32 xato beradi:
Modul yuklandi, lekin DllRegisterServer kirish nuqtasi topilmadi. Va bu fayl to'g'ri DLL yoki OCX fayli ekanligini tekshirishni taklif qiladi.
Kim shunga o'xshash vaziyatga duch keldi, qanday qilib chiqdingiz? Men shunga o'xshash muammo 7.7 da bo'lishini tushunaman.
Kod 8.2:

Layout = GetLayout ("IntegrationComponent"); Manzil = PlaceInTempStorage(Layout); ConnectExternalComponent(Manzil, "IntegrationComponent", ExternalComponentType.Native); Haydovchi = Yangi("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9");

1C 8.2:
Tashqi komponentni ulash(<Местоположение>, <Имя>, <Тип>)
1C 8.1:
Tashqi komponentni ulash(<Идентификатор объекта>)
Variantlar:
<Идентификатор объекта>(majburiy)
Turi: String. Tashqi komponent ob'ektining ProgID (Dastur identifikatori). Tizimni ro'yxatga olish ma'lumotlar bazasidagi ma'lumotlarga mos kelishi kerak (Ro'yxatga olish kitobi).
Tavsif:
Tashqi komponent ob'ektlarini 1C: Enterprise ga ulaydi.
1C: Enterprise serverida mavjud emas. Tashqi ulanish modulida ishlatilmaydi.
Eslatma:
Tashqi komponentlar 1C: Enterprise 7.7 komponentlari bilan mos keladi.
Misol:
Urinish
ConnectExternalComponent("AddinObject.Scanner");
alert("Shtrix-kod skaneri komponenti yuklangan");
Istisno
alert("Shtrix-kod skaneri komponenti yuklanmagan");
Urinishlarni tugatish

Ushbu dll ni 8.1 ga ulashning biron bir usuli bormi yoki yo'qmi?

Rahmat!

Javob:

Men ham yaqinda bu muammoga duch keldim. 1s ning keyingi versiyasiga aylantirish mumkin emas edi. Ushbu konfiguratsiya ishlaydigan dll oddiygina ishlashni to'xtatdi va 1c xatolik bilan ishdan chiqdi.
Muammo quyidagi tarzda hal qilindi:
Men bo'sh 8.3 ma'lumotlar bazasini yaratdim, unda men komponentni ishga tushirishni qayta ishladim va keyin 8.1 dan COM ulanishi orqali avval yaratilgan ma'lumotlar bazasiga kirdim va u erda komponentni ishga tushirdim. Keyin, allaqachon 8.1 da, men ushbu komponentning usullarini chaqirdim.
Albatta, bu qo'ltiq, lekin men hali boshqa yo'l topa olmadim (

Kod misoli 8.3:
Rem drayverini eksport qilish;
Funktsiya ConnectionComponentsCCP() eksporti
Urinish

Layout = GetLayout ("IntegrationComponent");
Manzil = PlaceInTempStorage(Layout);
ConnectExternalComponent(Manzil, "IntegrationComponent", ExternalComponentType.Native);
Drayv = Yangi ("AddIn.IntegrationComponent.SMDrvFR1C20");
natija = rost;

Istisno

natija = noto'g'ri;

Urinishning tugashi;
Natijani qaytarish
EndFunctions

Kod misoli 8.1

Funktsiya CreateDriverObject(Driver) eksporti

natija = rost;

Urinish

ConnectionString="File="""Ma'lumotlar bazasiga yo'l""";
ComObject= Yangi COMObject("V83.ComConnector");
Ulanish = ComObject.Connect(ConnectionString);

Qayta ishlash = Connect.Processing.ConnectingExternalComponent.Create();
ConnectionResult = Processing.ConnectingKKT Components();
Agar natija ulansa
Driver = Processing.Driver;
EndIf;

Istisno
Kim buni qilgan yoki shunga o'xshash muammolarni boshdan kechirgan bo'lsa, iltimos tushuntiring. oddiy misol printsipning o'zi. Tashqi komponentlarning ulanishi bilan hamma narsa aniq ko'rinadi.

// Qiymatlar jadvalini to'ldirishga misol TK.Clear(); So'rov = Yangi so'rov; Query.Text = "SELECT | Nomenklatura Havola QANDAY Nomenklatura | FROM | Directory.Nomenclature AS Nomenklatura"; QueryResult = Query.Execute(); Sampling = QueryResult.Select(); While Sampling.Next() Loop Str = TK.Add(); FillPropertyValues(Pr, Sampling); EndCycle;
Ushbu misol bilan kodning qaysi qismi odatda olib tashlanishini tushuntirib bera olasizmi? So'rovi bo'lgan qismni olib tashlash mantiqan to'g'ri bo'lar edi, lekin keyin platformani chetlab o'tib, tashqi komponentdan ma'lumotlar bazasiga qanday kirishimiz mumkin? Matn ma'nosiz. Yoki jadval qismining shakllanishini olib tashlang. Iltimos, bu boradagi tajribangizni o'rtoqlashing.

Javob: Va "Mos kelmaydigan" so'zi har doim "Yomon" so'zini anglatadimi? Ha, menimcha, agar men o'z uslubimni "1C: Tabiatda mavjud bo'lgan ushbu skript dvigatelidagi eng yomon dasturlash (adabiy tilga tarjima qilingan)!" va keyin, albatta, bu hayvonni tekshirishni xohlaydiganlar bo'ladi. Va bu klassikaga o'xshaydi: "Men Pasternakni o'qimaganman, lekin men u bilan mutlaqo rozi emasman!" :)

Savol: 1s 8.3.6 va Win8 da tashqi komponentni ulash


Vk_rs232.dll ExternalComponent-ni o'z-o'zidan yozilgan konfiguratsiyaga ulash kerak. Regsvr32.exe orqali ro'yxatdan o'tgan kabi. "Ko'rinishidan", chunki men "komponent ro'yxatdan o'tgan, ammo xavfsizlik devorida nimadir noto'g'ri" degan xabarni oldim. Xabarning birinchi yarmiga tayanib, kodni 1 soniyada yozaman
AfterConnection = New NotificationDescription("AfterConnectionVK",ThisForm); StartExternalComponentInstallation(,"C:\Controller\vk_rs232.dll"); StartConnectingExternalComponent(AfterConnecting,"C:\Controller\vk_rs232.dll","DLL_Scales");
va men bu xatoni olaman
"Tashqi komponentni o'rnatish amalga oshmadi! Siz foydalanayotgan mijoz ilovasi uchun komponent etishmayotgan bo'lishi mumkin!".

Va endi men tushunmayapman
1. Ehtimol, komponent registrda ro'yxatdan o'tmagandir - u erda uni qanday tekshirish mumkin?
2. Balki uning "versiyasi" Win8 ostida ishlamaydi, garchi menda 32 bitli bo'lsa ham.
3. Balki 1 ning o'zi juda yangi, ya'ni. Shunga ko'ra, bu DLL bilan ishlay olmaysizmi?
4. Xo'sh, bu banal - men noto'g'ri narsa yozyapman.

Javob: Va bularning barchasi meni keyingi muammoga olib keldi. VneshComp o'rnatilgan, endi siz uni ulashingiz kerak. Va bu erda ikkala variant ham mavjud.
ConnectExternalComponent("C:\Controller\vk_rs232.dll", "Tarozilar")
ConnectExternalComponent("GeneralLayout.Layout", "Scales")

Sintaksis varianti: nomi va joylashuvi bo'yicha

Sintaksis:

Tashqi komponentni ulash(<Местоположение>, <Имя>, <Тип>)
Variantlar:

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

Turi: String.
Tashqi komponentning joylashuvi.
Joylashuvdan foydalanish mumkin:
fayl tizimidagi tashqi komponent fayliga yo'l (veb-mijozda mavjud emas), ZIP arxivi emas;
to'liq nomi ikkilik ma'lumotlarni yoki ZIP arxivini saqlaydigan tartib;
Tashqi komponentning URL manzili, ikkilik ma'lumotlar yoki ZIP arxivi ko'rinishida, GetNaviLink ga o'xshash.
<Имя>(majburiy)

Turi: String.
Ulanadigan tashqi komponentning ramziy nomi.
Ism o'rnatilgan tilning nomlash qoidalariga muvofiq bo'lishi kerak.
<Тип>(ixtiyoriy)

Turi: Tashqi komponent turi.
Ulanadigan tashqi komponent turi.
Agar komponent ZIP arxiviga o'rnatilgan bo'lsa, foydalanilmaydi.
Usul variantining tavsifi:

Native va COM texnologiyasidan foydalangan holda tayyorlangan komponentlarni ulaydi.
Komponent ma'lumotlar bazasida yoki konfiguratsiya tartibida ikkilik ma'lumotlar yoki ZIP arxivida saqlanishi mumkin.
"Yupqa mijoz" va "Veb mijoz" ishga tushirish rejimlari uchun komponent tashqi komponentni o'rnatish usuli yordamida oldindan o'rnatilgan bo'lishi kerak.
Sintaksis varianti: ID bo'yicha

Sintaksis:

Tashqi komponentni ulash(<ИдентификаторОбъекта>)
Variantlar:

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

Turi: String.
MS Windows registrining ProgID (Dastur identifikatori) ko'rinishidagi tashqi komponent ob'ekt identifikatori (masalan: "AddIn.Scanner").
Tizimni ro'yxatga olish ma'lumotlar bazasidagi ma'lumotlarga mos kelishi kerak (Ro'yxatga olish kitobi).
Usul variantining tavsifi:

Komponent COM texnologiyasidan foydalangan holda amalga oshirilishi va MS Windows reestrida ro'yxatdan o'tkazilishi kerak.
Ushbu komponentlar 1C: Enterprise 7.7 komponentlari bilan mos keladi.
Diqqat! Usulning varianti serverda va tashqi ulanishda ishlamaydi.
Qaytish qiymati:

Turi: mantiqiy.
To'g'ri - ulanish muvaffaqiyatli bo'ldi.
Tavsif:

Tashqi komponentni 1C: Enterprise ga ulaydi.
Tashqi komponentlar ma'lumotlar bazasida yoki konfiguratsiya sxemalarida ZIP arxivi yoki ikkilik ma'lumotlar sifatida yoki fayl tizimi faylida saqlanishi mumkin.
Yupqa mijoz va veb-mijoz ustida ishlaganda komponentni oldindan o'rnatish kerak.

Mavjudligi:

Yupqa mijoz, veb-mijoz, server, tashqi ulanish.
Eslatma:

Tashqi komponentlar Native API yoki COM texnologiyasi yordamida amalga oshirilishi mumkin. COM texnologiyasidan foydalangan holda tayyorlangan komponentlar 1C: Enterprise 7.7 komponentlari bilan mos keladi.
Veb-mijoz faqat arxivga joylashtirilgan infobazadagi komponentlar bilan ishlashi mumkin.
Yupqa mijoz infobazadagi, arxivga joylashtirilgan komponentlar va fayl tizimida joylashgan komponentlar bilan ishlashi mumkin.
Qalin mijoz komponentlar uchun barcha saqlash imkoniyatlari bilan ishlashi mumkin. Bunday holda, agar komponent InstallExternalComponent usuli yordamida o'rnatilgan bo'lsa, u holda o'rnatilgan komponent ishlatiladi, agar u o'rnatilmagan bo'lsa, u holda komponent ulanish vaqtida qabul qilinadi.
Server barcha komponentlar bilan ishlashi mumkin. Komponent server seansi uchun keshlangan.
Misol:

ConnectExternalComponent("AddinObject.Scanner") bo'lsa
alert("Shtrix-kod skaneri komponenti yuklangan");
Aks holda
alert("Shtrix-kod skaneri komponenti yuklanmagan");
EndIf;

  • darslik

Kirish

Ushbu maqola 1C: Enterprise tizimida tashqi komponentlar qanday ishlashi haqida fikr beradi.
Ishning fayl versiyasi bilan Windows operatsion tizimi ostida ishlaydigan 1C: Enterprise 8.2 versiyasi tizimi uchun tashqi komponentni ishlab chiqish jarayoni ko'rsatiladi. Ushbu parametr kichik biznes uchun mo'ljallangan ko'pgina echimlarda qo'llaniladi. VC C++ dasturlash tilida amalga oshiriladi.

"1C: Enterprise" tashqi komponentlari

"1C: Enterprise" kengaytiriladigan tizimdir. Kengaytirish uchun funksionallik tizim tashqi komponentlardan (VC) foydalanadi. Ishlab chiquvchi nuqtai nazaridan, VC tashqi ob'ekt bo'lib, u xususiyatlar va usullarga ega, shuningdek, 1C: Enterprise tizimi tomonidan qayta ishlash uchun hodisalarni yaratishi mumkin.
Tashqi komponentlar 1C: Enterprise-ga o'rnatilgan dasturlash tilidan foydalangan holda amalga oshirish qiyin yoki hatto imkonsiz bo'lgan vazifalar sinfini hal qilish uchun ishlatilishi mumkin. Xususan, bu sinf operatsion tizim bilan past darajadagi shovqinni talab qiladigan vazifalarni o'z ichiga oladi, masalan, muayyan apparat bilan ishlash.
1C: Enterprise tizimi tashqi komponentlarni yaratish uchun ikkita texnologiyadan foydalanadi:
  • Native API yordamida
  • COM texnologiyasidan foydalanish
Yuqoridagi ikkita texnologiya o'rtasidagi cheklovlarni hisobga olsak, farq unchalik katta emas, shuning uchun biz Native API yordamida VK-ni ishlab chiqishni ko'rib chiqamiz. Agar kerak bo'lsa, amalga oshirilgan ishlanmalar COM texnologiyasidan foydalangan holda VC-ni ishlab chiqishda qo'llanilishi mumkin, shuningdek, kichik o'zgartirishlar bilan 1C: Enterprise tizimida faylning ishlash rejimidan tashqari boshqa operatsion variantlari bilan foydalanish uchun qo'llanilishi mumkin.
VK tuzilishi
1C: Enterprise tizimining tashqi komponenti DLL kutubxonasi sifatida taqdim etilgan. Kutubxona kodi IComponentBase olingan sinfini tavsiflaydi. Yaratilayotgan sinfda tashqi komponentning funksiyalarini amalga oshirish uchun mas'ul bo'lgan usullar aniqlanishi kerak. Bekor qilingan usullar keyinchalik materialni taqdim etish jarayonida batafsilroq tavsiflanadi.

VK demo-ni ishga tushirish

Vazifa:
  1. ITS obunasi bilan ta'minlangan va 1C da tashqi komponent mexanizmining asosiy imkoniyatlarini namoyish qilish uchun mo'ljallangan tashqi komponentni yig'ing.
  2. Namoyish komponentini 1C konfiguratsiyasiga ulang
  3. E'lon qilingan funktsiyalar to'g'ri ishlashiga ishonch hosil qiling
Jamlama
Demo VC ITS obuna diskida "/VNCOMP82/example/NativeAPI" katalogida joylashgan.
Biz VK demosini yig'ish uchun Microsoft Visual Studio 2008 dasturidan foydalanamiz. Ushbu mahsulotning boshqa versiyalari ishlatilgan Visual Studio loyiha formatini qo'llab-quvvatlamaydi.


AddInNative loyihasini oching. Loyiha sozlamalarida biz katalogni loyihani yaratish uchun zarur bo'lgan sarlavha fayllari bilan bog'laymiz. Odatiy bo'lib, ular katalogdagi ITS diskida joylashgan /VNCOMP82/include.
Qurilish natijasi fayldir /bind/AddInNative.dll. Bu 1C konfiguratsiyasiga ulanish uchun tuzilgan kutubxona.
VK ni 1C konfiguratsiyasiga ulash
Keling, 1C bo'sh konfiguratsiyasini yarataylik.
Quyida boshqariladigan dastur moduli uchun kod keltirilgan.
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...\bind\AddInNative.dll", "DemoVK", ExternalComponentType.Native); DemoComp = Yangi ("AddIn.DemoVK.AddInNativeExtension"); EndProcedure
Agar 1C konfiguratsiyasini ishga tushirishda xatolik haqida xabar berilmagan bo'lsa, u holda VK muvaffaqiyatli ulangan.
Yuqoridagi kodning bajarilishi natijasida konfiguratsiyaning global ko'rinishida ob'ekt paydo bo'ladi. DemoComp Tashqi fasol kodida aniqlangan xususiyatlar va usullarga ega.
O'rnatilgan funksionallikni namoyish qilish
Keling, demo VK ning ishlashini tekshiramiz. Buning uchun ba'zi xususiyatlarni o'rnatish va o'qish, ba'zi VK usullarini chaqirish, shuningdek, VK xabarini qabul qilish va qayta ishlashga harakat qilaylik.
ITS diskida taqdim etilgan hujjatlar demo VC ning quyidagi funksiyalarini bildiradi:
  1. Komponent ob'ektining holatini boshqarish
    Usullari: Yoqish; ishga tushirish, O'chiring
    Xususiyatlari: Kiritilgan
  2. Taymerni boshqarish
    Har soniyada komponent 1C: Enterprise tizimiga parametrlari bilan xabar yuboradi Komponent, taymer va tizim soati hisoblagich qatori.
    Usullari: Taymerni ishga tushirish, Stoptaymer
    Xususiyatlari: Taymer bor
  3. Usul ShowInStatusLine, u holat satrida parametr sifatida usulga o'tkazilgan matnni ko'rsatadi
  4. Usul Rasm yuklash. Belgilangan fayldan rasmni yuklaydi va uni ikkilik ma'lumotlar sifatida 1C: Enterprise tizimiga o'tkazadi.
Keling, ushbu funktsiyalar ishlayotganiga ishonch hosil qilaylik. Buning uchun biz quyidagi kodni bajaramiz:
var DemoComp; SystemStart() Protsedura ConnectExternalComponent(...); DemoComp = Yangi ("AddIn.DemoVK.AddInNativeExtension"); DemoComp.Disable(); Xabar berish (DemoComp. Yoqilgan); DemoComp.Enable(); Xabar berish (DemoComp. Yoqilgan); DemoComp.StartTimer(); EndProcedure ProcedureExternalEventHandler(Manba, Voqea, Ma'lumotlar) Hisoboti (Manba + " " + Voqea + " " + Ma'lumotlar); EndProcedure
Konfiguratsiyani ishga tushirish natijasi rasmda ko'rsatilgan


Usul chaqiruvlari natijalari "Xabarlar" panelida ko'rsatiladi DemoComp.Disable() va Demo.Comp.Enable(). Xuddi shu paneldagi keyingi qatorlar VK dan olingan xabarlarni qayta ishlash natijalarini o'z ichiga oladi - Manba, Tadbir va Ma'lumotlar mos ravishda.

Ixtiyoriy tashqi komponent nomi

Vazifa: tashqi komponent nomini o'zboshimchalik bilan o'zgartiring.
Oldingi bo'limda identifikator ishlatilgan AddInNativeExtension, uning ma'nosi tushuntirilmagan. Ushbu holatda AddInNativeExtension kengaytmaning nomi.
VC kodi usulni belgilaydi RegisterExtensionAs, bu nomni 1C: Enterprise tizimiga qaytaradi, bu tizimda VCni keyinchalik ro'yxatdan o'tkazish uchun zarurdir. Tashqi komponentning mohiyatini ma'lum darajada ochib beradigan identifikatorni ko'rsatish tavsiya etiladi.
Mana usulning to'liq kodi RegisterExtensionAs kengaytma nomi o'zgartirilganda:
bool CAddInNative::RegisterExtensionAs(WCHAR_T** wsExtensionName) ( wchar_t *wsExtension = L"SomeName"; int iActualSize = ::wcslen(wsExtension) + 1; WCHAR_T* dest = 0; agar (hay_haymay) ((void**)wsExtensionName, iActualSize * sizeof(WCHAR_T))) ::convToShortWchar(wsExtensionName, wsExtension, iActualSize); rost qaytaradi; ) noto'g'ri qaytaradi; )
Yuqoridagi misolda VK nomi o'zgartirildi Ba'zi ism. Keyin, VK-ni ulashda siz yangi nomni ko'rsatishingiz kerak:
DemoComp = Yangi ("AddIn.DemoVK.SomeName");

VK xususiyatlari ro'yxatini kengaytirish

Vazifa:
  1. VC xususiyatlarini amalga oshirishni o'rganish
  2. Satr tipidagi o'qish-yozish xususiyatini qo'shing
  3. Oxirgi to'plamning ma'lumotlar turini saqlaydigan o'qish/yozish qatori xususiyatini qo'shing. Mulk qiymatini belgilashda hech qanday chora ko'rilmaydi

Yaratilayotgan komponentning xususiyatlarini aniqlash uchun dasturchi AddInNative.cpp kutubxonasi kodida quyidagi usullarni amalga oshirishi kerak:
GetNProps
Ushbu kengaytma uchun xossalar sonini qaytaradi, agar xususiyat bo'lmasa 0
FindProp
Parametrlarda nomi berilgan xususiyatning tartib raqamini qaytaradi
GetPropName
Mulk nomini tartib va ​​o'tkazilgan til identifikatori bo'yicha qaytaradi
GetPropVal
Belgilangan tartib bilan xususiyat qiymatini qaytaradi
SetPropVal
Belgilangan tartib bilan xususiyat qiymatini o'rnatadi
IsPropReadable
Belgilangan tartib bilan xususiyatning o'qilishi bayrog'ini qaytaradi
IsPropWritable
Belgilangan tartib raqami bilan xususiyatning yozilishi bayrog'ini qaytaradi


Yuqoridagi sinf usullarini amalga oshirishni ko'rib chiqing CADdInNative.
Demo VC ikkita xususiyatni belgilaydi: Kiritilgan va Taymer bor (Yoqilgan va IsTimerPresent).
Kutubxona kodining global miqyosida ikkita massiv belgilangan:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent"); static wchar_t *g_PropNamesRu = (L"Yoqilgan", L"Taymer bor");
mulklarning ruscha va inglizcha nomlarini saqlaydi. Sarlavha faylida AddInNative.h enum aniqlanadi:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropLast // Har doim oxirgi );
ePropIsEnabled va ePropIsTimerPresent, mos ravishda 0 va 1 qiymatlariga ega bo'lgan xususiyatlarning tartib raqamlarini mazmunli identifikatorlar bilan almashtirish uchun ishlatiladi. Xususiyatlar sonini olish uchun 2 qiymatiga ega ePropLast ishlatiladi (GetNProps usuli yordamida). Bu nomlar faqat komponent kodi ichida qo'llaniladi va ularga tashqaridan kirish imkoni yo'q.
FindProp va GetPropName usullari massivlar bo'ylab izlaydi g_PropNames va g_PropNames.
Kutubxona modulidagi maydonlar qiymatini saqlash uchun CADdInNative klassi komponent xususiyatlarining qiymatini saqlaydigan xususiyatlarga ega. Usullari GetPropVal va SetPropVal mos ravishda qaytaring va ushbu xususiyatlarning qiymatini o'rnating.
Usullari IsPropReadable va IsPropWritable va qaytish rost yoki yolg'on, ilova mantig'iga ko'ra xususiyatning o'tgan tartibiga qarab.
Maxsus xususiyatni qo'shish uchun:

  1. Massivlarga qo'shiladigan xususiyat nomini qo'shing g_PropNames va g_PropNames(fayl AddInNative.cpp)
  2. Ro'yxatga olish uchun rekvizitlar(fayl AddInNative.h) oldin ePropLast qo'shiladigan xususiyatni noyob tarzda aniqlaydigan nom qo'shing
  3. Xususiyat qiymatlarini saqlash uchun xotirani tashkil qiling (tegishli qiymatlarni saqlaydigan komponent modul maydonlarini yarating)
  4. Usullarga o'zgartirishlar kiriting GetPropVal va SetPropVal oldingi bosqichda ajratilgan xotira bilan ishlash uchun
  5. Ilova mantig'iga muvofiq usullarga o'zgartirishlar kiriting IsPropReadable va IsPropWritable
1, 2, 5-bandlar tushuntirishga muhtoj emas. Ushbu bosqichlarni amalga oshirish tafsilotlarini maqolaning ilovasida topish mumkin.
Test xususiyatlarini nomlaylik Sinov va Tekshirish turi mos ravishda. Keyin, 1-band natijasida bizda:
static wchar_t *g_PropNames = (L"IsEnabled", L"IsTimerPresent", L"Test", L"TestType"); static wchar_t *g_PropNamesRu = (L"Enabled", L"HasTimer", L"Test", L"CheckType");
Ro'yxatga olish rekvizitlar quyidagicha ko'rinadi:
enum Props ( ePropIsEnabled = 0, ePropIsTimerPresent, ePropTest1, ePropTest2, ePropLast // Har doim oxirgi );
Kodni sezilarli darajada soddalashtirish uchun biz STL C++ dan foydalanamiz. Xususan, torlar bilan ishlash uchun WCHAR, kutubxonani ulang wstring.
Usul qiymatini saqlash uchun Sinov, sinfda aniqlang CADdInNative xususiy sohada:
string test1;
1C: Enterprise va tashqi komponent o'rtasida satr parametrlarini uzatish uchun 1C: Enterprise xotira menejeri ishlatiladi. Keling, uning ishini batafsil ko'rib chiqaylik. Xotirani ajratish va bo'shatish uchun mos ravishda funktsiyalardan foydalaning AllocMemory va Bepul xotira, faylda belgilangan MemoryManager.h. Agar 1C: Enterprise tizimiga satr parametrini o'tkazish kerak bo'lsa, tashqi komponent funktsiyani chaqirish orqali unga xotira ajratishi kerak. AllocMemory. Uning prototipi quyidagicha ko'rinadi:
virtual bool ADDIN_API AllocMemory (void** pMemory, unsigned long ulCountByte) = 0;
qayerda pXotira- ajratilgan xotira manzili joylashtiriladigan ko'rsatgichning manzili,
ulCountByte- ajratilgan xotira maydoni hajmi.
Satr uchun xotira ajratishga misol:
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);
String ma'lumotlar turlari bilan ishlash qulayligi uchun biz funktsiyani tasvirlaymiz wstring_to_p. U parametr sifatida wstring satrini oladi. Funktsiyaning natijasi to'ldirilgan strukturadir tVariant. Funktsiya kodi:
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(); rostni qaytaring;)
Keyin usulning switch bayonotining mos keladigan holat bo'limi GetPropVal shaklni oladi:
case ePropTest1: wstring_to_p(test1, pvarPropVal); sindirish;
usul SetPropVal:
case ePropTest1: agar (TV_VT(varPropVal) != VTYPE_PWSTR) false qaytarsa; test1 = std::wstring((wchar_t*)(varPropVal -> pstrVal)); sindirish;
Ikkinchi xususiyatni amalga oshirish uchun biz sinf maydonini aniqlaymiz CaddInNative
uint8_t last_type;
unda biz oxirgi o'tgan qiymatning turini saqlaymiz. Buning uchun CaddInNative::SetPropVal usuliga quyidagi buyruqni qo'shing:
oxirgi_tur = TV_VT(varPropVal);
Endi, ikkinchi xususiyatning qiymatini o'qishni so'raganda, biz qiymatni qaytaramiz oxirgi_turi, bu belgilangan vazifa tomonidan talab qilinadi.
Keling, kiritilgan o'zgarishlarning ishlashini tekshiramiz.
Buning uchun biz taqdim etamiz tashqi ko'rinish ko'rinishga 1C konfiguratsiyasi:
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = Yangi ("AddIn.DemoVK.SomeName"); DemoComp.CheckType = 1; Hisobot(String(DemoComp.TypeCheck)); DemoComp.Test = "Vasya"; Hisobot (String(DemoComp.Test)); DemoComp.Test = "Petya"; Hisobot (String(DemoComp.Test)); Hisobot(String(DemoComp.TypeCheck)); EndProcedure
Ishga tushirish natijasida biz xabarlar ketma-ketligini olamiz:
3
Vasya
Petya
22

Ikkinchi va uchinchi xabarlar oldingi bosqichda o'rnatilgan xususiyatni o'qish natijasidir. Birinchi va ikkinchi xabarlar oxirgi xususiyat to'plamining tip kodini o'z ichiga oladi. 3 butun son qiymatiga, 22 - satr qiymatiga mos keladi. Turlarning muvofiqligi va ularning kodlari faylda o'rnatiladi turlari.h, ITS diskida joylashgan.

Usullar ro'yxatini kengaytirish

Vazifa:
  1. Quyidagi funksiyalar bilan tashqi komponentning funksionalligini kengaytiring:
  2. Tashqi komponent usullarini qanday amalga oshirishni o'rganing
  3. Metod-funksiya qo'shing Funktsiya 1, u ikkita satrni ("Parameter1" va "Parameter2") parametr sifatida oladi. Natijada, forma qatori qaytariladi: “Tekshirish. Parametr 1, Parametr 2"
  4. Kiritilgan o'zgarishlar ishlayotganligini tekshiring.

Yaratilayotgan komponentning usullarini aniqlash uchun ishlab chiquvchi AddInNative kutubxonasi kodida quyidagi usullarni amalga oshirishi kerak:
GetNMethods, Find Method, GetMethodName
Tegishli ravishda usullar sonini olish, usulning raqami va nomini qidirish uchun mo'ljallangan. Xususiyatlar uchun mos keladigan usullarga o'xshash
GetNParams
Belgilangan tartib raqami bilan usul parametrlari sonini qaytaradi; agar bu raqam bilan hech qanday usul bo'lmasa yoki parametrlari bo'lmasa, 0 ni qaytaradi
GetParamDefValue
Belgilangan usulning belgilangan parametrining standart qiymatini qaytaradi
HasRetVal
Belgilangan qaytish qiymati tartibli usulga ega bo'lgan bayroqni qaytaradi: qaytariladigan qiymatga ega usullar uchun true va yolg'on aks holda
CallAsProc
yolg'on, ish vaqtida xatolik yuzaga keladi va 1C: Enterprise modulining bajarilishi to'xtaydi. Parametrlar massivi uchun xotira 1C: Enterprise tomonidan ajratiladi va chiqariladi.
CallAsFunc
Usulni belgilangan tartib bilan bajaradi. Agar usul qaytsa yolg'on, ish vaqtida xatolik yuzaga keladi va 1C: Enterprise modulining bajarilishi to'xtaydi. Parametrlar massivi uchun xotira 1C: Enterprise tomonidan ajratilgan. Qaytish qiymati string yoki ikkilik ma'lumotlar turi bo'lsa, komponent xotirani funksiya bilan ajratadi AllocMemory xotira menejeri, u erda ma'lumotlarni yozadi va ushbu manzilni strukturaning tegishli maydonida saqlaydi. 1C: Korxona ushbu xotirani qo'ng'iroq qilish orqali chiqaradi Bepul xotira.
Usullarning to'liq tavsifi, jumladan, parametrlar ro'yxati ITS diskida taqdim etilgan hujjatlarda batafsil tavsiflangan.
Yuqorida tavsiflangan usullarni amalga oshirishni ko'rib chiqing.
Komponent kodida ikkita massiv aniqlanadi:
static wchar_t *g_MethodNames = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture"); static wchar_t *g_MethodNamesRu = (L"Enable", L"O'chirish", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage");
va enum:
enum usullari (eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethLast // Har doim oxirgi);
Ular funktsiyalarda qo'llaniladi GetNMethods, Find Method va GetMethodName, xususiyatlar tavsifiga o'xshash.
Usullari GetNParams, GetParamDefValue, HasRetVal o'tkazilgan parametrlar va dastur mantig'iga qarab amalga oshirish kaliti kerakli qiymatni qaytaradi. Usul HasRetVal uning kodida faqat natijani qaytaradigan usullar ro'yxati mavjud. Ular uchun bu qaytadi rost. Barcha po'lat usullari uchun qaytib keladi yolg'on.
Usullari CallAsProc va CallAsFunc to'g'ridan-to'g'ri bajariladigan usul kodini o'z ichiga oladi.
Faqat funktsiya sifatida chaqirilishi mumkin bo'lgan usulni qo'shish uchun siz tashqi komponentning manba kodiga quyidagi o'zgarishlarni kiritishingiz kerak:
  1. Massivlarga usul nomini qo'shing g_Usul nomlari va g_Usul nomlari(fayl AddInNative.cpp)
  2. Methods raqamiga mazmunli usul identifikatorini qo'shing (fayl AddInNative.h)
  3. Funktsiya kodiga o'zgartirishlar kiriting GetNParams dastur mantig'iga ko'ra
  4. Agar kerak bo'lsa, usul kodiga o'zgartirishlar kiriting GetParamDefValue agar siz usul parametrlarining standart qiymatlaridan foydalanmoqchi bo'lsangiz.
  5. Funktsiyaga o'zgartirishlar kiriting HasRetVal
  6. Funktsiyalar mantig'iga o'zgartirishlar kiriting CallAsProc yoki CallAsFunc, u erda usulning to'g'ridan-to'g'ri bajariladigan kodini joylashtirish orqali
Keling, massivlarni keltiraylik g_Usul nomlari va g_Usul nomlari, shuningdek, ro'yxatga olish usullari ko'rinishga:
static wchar_t *g_MethodNames = (L"Enable", L"Disable", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadPicture", L"Test"); static wchar_t *g_MethodNamesRu = (L"Enable", L"O'chirish", L"ShowInStatusLine", L"StartTimer", L"StopTimer", L"LoadImage", L"Test");

Raqamlash usullari (eMethEnable = 0, eMethDisable, eMethShowInStatusLine, eMethStartTimer, eMethStopTimer, eMethLoadPicture, eMethTest, eMethLast // Har doim oxirgi );
Funktsiyani tahrir qilaylik GetNProps Shunday qilib, u "Test" usuli parametrlari sonini qaytaradi:
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; )
Funktsiyaga o'zgartirish kiritamiz:
bool CAddInNative::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) (TV_VT(pvarParamDefValue)= VTYPE_EMPTY; switch(lMethodNum) ( case eMeth : eMeth : case Meth : case Meth : e Meth : case Meth : e : caseMeth : eMeth : caseMeth : eMeth : case Meth : eMeth :S . : case / Sukut bo'yicha tanaffus bo'yicha parametr qiymatlari yo'q; sukut bo'yicha: false qaytariladi; ) noto'g'ri qaytariladi; )
Qo'shilgan qator uchun rahmat
eMethTest holati:
bir yoki bir nechta argumentlar bo'lmasa, mos keladigan parametrlar bo'sh qiymatga ega bo'ladi ( VTYPE_EMPTY). Agar parametr uchun standart qiymat kerak bo'lsa, uni bo'limda ko'rsatishingiz kerak eMethTest funktsiyani almashtirish bayonoti CAddInNative::GetParamDefValue.
"Test" usuli qiymatni qaytarishi mumkinligi sababli, siz funktsiya kodiga o'zgartirish kiritishingiz kerak HasRetVal:
bool CAddInNative::HasRetVal(const long lMethodNum) ( switch(lMethodNum) ( case eMethLoadPicture: case eMethTest: return true; default: return false; ) return false; )
Va funktsiyaga usulning bajariladigan kodini qo'shing CallAsFunc:
bool CAddInNative::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) ( ... std::wstring s1, s2; switch(lMethodNum) ( case eMethodNum: case eMethodPic; agar (!lSizeArray || !paParams) false qaytarsa; s1 = (paParams) -> pwstrVal; s2 = (paParams+1) -> pwstrVal; wstring_to_p(std::wstring(s1+s2), pvarRetValue); ret = true ; sindirish; ) qaytish; )
Komponentni kompilyatsiya qilamiz va konfiguratsiya kodini formaga keltiramiz:
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = Yangi ("AddIn.DemoVK.SomeName"); lane = DemoComp.Test("Salom, ", "Dunyo!"); Xabar berish (trans); EndProcedure
Konfiguratsiyani boshlaganimizdan so'ng, biz "Salom, dunyo!" xabarini olamiz, bu usul muvaffaqiyatli ishlaganligini ko'rsatadi.

Taymer

Vazifa:
  1. VK demosida taymerni amalga oshirishni o'rganing
  2. Parametrlarga taymer oralig'ini (millisekundlarda) o'tkazish qobiliyatini qo'shish orqali "StartTimer" usulini o'zgartiring.
  3. Kiritilgan o'zgarishlar ishlayotganligini tekshiring.

WinAPI-da vaqt bilan ishlash uchun siz xabardan foydalanishingiz mumkin WM_TIMER. Ushbu xabar taymerni yaratishda siz belgilagan vaqt oralig'ida dasturingizga yuboriladi.
Taymer yaratish uchun funksiyadan foydalaning Taymerni sozlash:
UINT SetTimer(HWND hWnd, // oyna dastagi UINT nIDevent, // taymer identifikatori (raqam) UINT nElapse, // kechikish TIMERPROC lpTimerFunc); // funktsiya ko'rsatkichi
Operatsion tizim xabar yuboradi WM_TIMER argumentda belgilangan interval bilan dasturga nElapse(millisekundlarda). Oxirgi parametrda siz taymer har safar ishga tushganda bajariladigan funksiyani belgilashingiz mumkin. Ushbu funktsiyaning sarlavhasi quyidagicha ko'rinishi kerak (nomi har qanday bo'lishi mumkin):
bekor __stdcall TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Taymerni VK demosida amalga oshirishni ko'rib chiqing.
Biz Windows OS oilasi uchun tashqi komponentni ishlab chiqish jarayonini ko'rib chiqayotganimiz sababli, biz taymerni boshqa dasturlarda amalga oshirishni ko'rib chiqmaymiz. operatsion tizimlar. GNU/Linux OS uchun, xususan, amalga oshirish funksiya sintaksisida farqlanadi. Taymerni sozlash va TimerProc.
Usul bajariladigan kodda chaqiriladi Taymerni sozlash, funksiya uzatiladigan MyTimerProc:
m_uiTimer = ::SetTimer(NULL,0,100,(TIMERPROC)MyTimerProc);
Yaratilgan taymerning identifikatori o'zgaruvchiga joylashtiriladi m_uiTimer keyin uni o'chirib qo'yishingiz mumkin.
Funktsiya MyTimerProc quyidagicha:
VOID QO'NG'IROQ MyTimerProc(HWND hwnd, // taymer xabarlari uchun oyna dastasi UINT uMsg, // WM_TIMER xabar UINT idEvent, // taymer identifikatori DWORD dwTime // joriy tizim vaqti) ( agar (!pAsyncEvent) qaytish; wchar_t *who L = "ComponentNative", *what = L"Taymer"; wchar_t *wstime = new wchar_t; if (wstime) ( wmemset(wstime, 0, TIME_LEN); ::_ultow(dwTime, wstime, 10); pAsyncEvent->ExternalEvent(kim , nima, wstime); wstimeni o'chirish; ))
Funktsiyaning mohiyati shundaki, usul chaqiriladi Tashqi hodisa, bu 1C: Enterprise tizimiga xabar yuboradi.
Usulning funksionalligini kengaytirish uchun Taymerni ishga tushirish keling, quyidagilarni bajaramiz:
Usul kodini o'zgartirish GetNParams shunday qilib, u usul uchun eMethStartTimer Qaytgan qiymat 1:
case eMethStartTimer: qaytish 1;
Mana usul kodi CallAsProc ko'rinishga:
case eMethStartTimer: agar (!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;
Endi funksionallikni tekshiramiz. Buning uchun konfiguratsiyaning boshqariladigan ilovasi modulida biz kodni yozamiz:
var DemoComp; SystemStartup Procedure() ConnectExternalComponent("...", "DemoVK", ExternalComponentType.Native); DemoComp = Yangi ("AddIn.DemoVK.SomeName"); DemoComp.StartTimer (2000); EndProcedure
Konfiguratsiyani ishga tushirgandan so'ng, dastur 2 soniya oralig'ida xabarlarni oladi, bu taymerning to'g'ri ishlashini ko'rsatadi.

1C: Enterprise tizimi bilan o'zaro aloqa

Tashqi komponent va 1C: Enterprise tizimi o'rtasida o'zaro ta'sir qilish uchun faylda tasvirlangan IAddInDefBase sinfining usullari. AddInDefBase.h. Biz eng ko'p ishlatiladiganlarni sanab o'tamiz:
Xato xabarini yaratish
virtual bool ADDIN_API AddError(imzosiz qisqa kod, const WCHAR_T* manba, const WCHAR_T* tavsif, uzun kod)
wcode, kod- xato kodlari (tavsif bilan xato kodlari ro'yxatini ITS diskida topish mumkin)
manba- xato manbai
tavsif- xato tavsifi
1C: Enterprise tizimiga xabar yuborish
virtual bool ADDIN_API tashqi hodisasi (WCHAR_T* wszSource, WCHAR_T* wszMessage, WCHAR_T* wszData) = 0;
wszSource- xabar manbai
wszMessage- Xabar matni
wszData- uzatilgan ma'lumotlar
Xabarni ushlash HandlingExternalEvent protsedurasi orqali amalga oshiriladi
1C: Enterprise tizimida tashqi komponentni ro'yxatdan o'tkazish
virtual bool ADDIN_API RegisterProfileAs(WCHAR_T* wszProfileName)
wszProfileName- komponent nomi.
Ushbu usullar VK va 1C ning to'liq o'zaro ta'siri uchun etarli. 1C: Enterprise tizimidan tashqi komponent tomonidan ma'lumotlarni olish uchun va aksincha, tashqi komponent maxsus xabarni yuboradi, bu esa o'z navbatida 1C tizimi tomonidan ushlanadi va agar kerak bo'lsa, yuborish uchun tashqi komponentning usullarini chaqiradi. ma'lumotlarni orqaga qaytarish.

tVariant ma'lumotlar turi

Tashqi komponent va 1C: Enterprise tizimi o'rtasida ma'lumot almashishda tVariant ma'lumotlar turi qo'llaniladi. U ITS diskida joylashgan type.h faylida tasvirlangan:
String _tvyt (intonimyum_union) (int16_t rforval; int14_t ulval); int64_t ulval; int64_t Ulval; INT32_T ULLVAL; ST32_T ULVAL; bVal; char chVal; wchar_t wchVal; DATE sana; IID IDVal; struct _tVariant *pvarVal; struct tm tmVal; _ANONYMOUS_STRUCT tuzilmasi ( void* pInterfaceVal; IID InterfaceID; ) __strucet* NAME_TRUS2; /baytlar soni ) __VARIANT_NAME_3/*str*/; _ANONYMOUS_STRUCT tuzilmasi ( WCHAR_T* pwstrVal; uint32_t wstrLen; //belgilar soni ) __VARIANT_NAME_4/*wstr*/; ) __VARIANT_NAME_2 uchun bir o‘lchov; pvarVal TYPEVAR vt da; );
turi tVariant tarkibiga quyidagilar kiradi:
  • to'g'ridan-to'g'ri ma'lumotlarni saqlash uchun mo'ljallangan aralash (birlashma).
  • ma'lumotlar turi identifikatori
Umuman olganda, turdagi o'zgaruvchilar bilan ishlash tVariant quyidagi algoritm bo'yicha sodir bo'ladi:
  1. O'zgaruvchida hozirda saqlangan ma'lumotlar turini aniqlash
  2. Ma'lumotlarga to'g'ridan-to'g'ri kirish uchun aralashmaning tegishli maydoniga kirish
Foydalanish turi tVariant 1C: Enterprise tizimi va tashqi komponentning o'zaro ta'sirini sezilarli darajada soddalashtiradi

Ilova

"Misollar" katalogida maqola uchun misollar mavjud
misollar/1 - demo komponentni ishga tushiring
misollar/2 - mulk ro'yxati kengaytmasi demosi
misollar/3 - usullar ro'yxatini kengaytirishni ko'rsatish
Har bir katalogda VS 2008 loyihasi va oldindan tuzilgan 1C konfiguratsiyasi mavjud.

Ko'pincha, foydalanuvchilar serverga terminal orqali ulanish orqali 1C bilan ishlaganda, dasturchilar tashqi komponentlarni (masalan, tijorat uskunalari drayverlarini) ulashda muammolarga duch kelishadi.

Shu bilan birga, foydalanuvchilar, masalan, maqolaning e'lonida keltirilgan rasmni ko'rishadi.

Mahalliy kompyuterlardan ishlaganda, tashqi komponentlarni ulashda hech qanday muammo bo'lmaydi.

Bu nima bilan bog'liq? Buning sababi, foydalanuvchilar Terminal Server orqali ishlaganda, ular mahalliy kompyuterda ishlashga qaraganda kamroq huquqlarga ega.

Agar siz ma'muriy huquqlarga ega hisob qaydnomasi ostida terminal serveriga kirsangiz, buni tekshirish oson.

Bu farqning sababi shundaki, foydalanuvchi terminalda normal huquqlar ostida ishlaganda 1C tashqi komponentni ro'yxatga olish kitobida ro'yxatdan o'tkaza olmaydi, chunki oddiy foydalanuvchi tizim ro'yxatga olish kitobi bo'limiga yozish ruxsatiga ega emas HKEY_CLASSES_ROOT.

Terminalda tashqi komponentlarni ulash mavzusidagi nashrlarda ushbu muammoni hal qilishning turli usullari taklif etiladi.

Masalan, bular:

1. Ma'muriy huquqlar ostida birinchi marta 1C-ni ishga tushiring.

Bu variant har doim ham ishlamaydi. Buning sababini quyida tushuntiraman.

2. Terminalning oddiy foydalanuvchilariga tizim registrlari bo'limiga yozish huquqini bering HKEY_CLASSES_ROOT.

Etarlicha "ilg'or" foydalanuvchilar buni qilmasliklari kerak, aks holda muammolar bo'lishi mumkin.

3. Turli xil "gadjetlar" yordamida VK-ni to'liq huquqlarga ega bo'lgan foydalanuvchi nomidan ro'yxatdan o'tkazing.

Ovqatlanish ham yaxshi emas.

Xo'sh, bu vaziyatdan chiqishning eng yaxshi yo'li qanday?

Men bu muammoga o'z yechimimni taklif qilaman. Menimcha - oddiy va chiroyli, ilgari infostartda taklif qilinmagan.

Ushbu muammoni o'rganib chiqib, men hayron bo'ldim - nega 1C VKni yangi yo'lda ro'yxatdan o'tkazishga harakat qilmoqda? Axir, u allaqachon tizimda ro'yxatdan o'tgan.

Gap shundaki, odatiy 1C konfiguratsiyalarida (masalan, "Savdoni boshqarish") global kontekst usulining quyidagi sintaksisi qo'llaniladi. ConnectExternalComponent() :

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

Ko'rib turganingizdek, VK drayveri "Ulangan uskunalar" katalogining "DriverATOLScannerBarcode" tartibidan ulangan.

Keyin nima bo'ladi?

1C komponentni foydalanuvchining vaqtinchalik papkasida saqlaydi, masalan, "C:\Documents and Settings\User\Local Settings\Temp\1032\v8_4_12.tmp"

va uni HKEY_CLASSES_ROOT ro'yxatga olish bo'limida ushbu yo'lda ro'yxatdan o'tkazishga harakat qiladi.

Terminalda oddiy foydalanuvchilar ushbu ro'yxatga olish bo'limini o'zgartirish huquqiga ega emaslar, shuning uchun komponent ular uchun ulanmagan.

Endi bu vaziyatdan qanday chiqish haqida.

Global kontekst usuli ConnectExternalComponent() bir nechta sintaksis parametrlariga ega. Bu biz foydalanadigan narsadir.

Shunday qilib, bosqichma-bosqich:

1. 32-bitli OT uchun C:\WINDOWS\SYSTEM32 papkasida yoki papkada terminal serveridagi regsvr32.exe yordam dasturidan foydalanib tashqi komponentni ro'yxatdan o'tkazing. 64-bitli OT uchun C:\WINDOWS\SYSWOW64.

2. ConnectExternalComponent() usuli uchun ikkita qo‘shimcha sintaksis opsiyalaridan birini ishlating:

Variant 1:

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

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

Variant 2:

ProgID = "AddIn.Scanner45";

Tashqi komponentni ulash (ProgID);

DriverObject = Yangi (ProgID);

Menimcha, №2 variant afzalroq.

Shu bilan birga, 1C VCni ro'yxatga olish kitobida yangi yo'l bo'ylab qayta ro'yxatdan o'tkazishga urinmaydi va shu bilan barcha muammolar hal qilinadi.

Xo'sh, hammasi shu. Ishda omad!

Misol uchun, agar siz uning muallifi bo'lmasangiz va manba kodlari bo'lmasa, komponentni qayta yozish mumkin bo'lmaydi. Yoki Native API texnologiyasi tomonidan qo'llab-quvvatlanadigan eng oddiy turlar (raqam, string, mantiqiy, sana) uning ishlashi uchun etarli bo'lmasa.

Fayl bazasi bilan ishlashda maxsus muammolar yo'q. Rejalashtirilgan vazifa oddiy foydalanuvchining fon jarayonida chaqiriladi. Shuning uchun, mijoz qo'ng'iroqlari unga mavjud. Rejalashtirilgan vazifa boshlanganda server ma'lumotlar bazasida mijoz konteksti yo'q, shuning uchun qo'ng'iroq ConnectExternalComponent() mavjud emas.

Bunday holda siz komponentni mijozga chaqirishingiz mumkin. Buning uchun mijozga kerakli harakatlarni bajarish uchun serverdagi rejalashtirilgan vazifadan yana 1C seansini ishga tushirish kifoya. Xo'sh, yugurish seansini keyinroq tugatishni unutmang.

Aytaylik, rejalashtirilgan vazifamizda biz to'liq ismni rad etish uchun tashqi MAQOMOTI NameDeclension.dll komponentidan foydalanadigan hisobotni yaratamiz va saqlaymiz. Fayl bazasida bunday rejalashtirilgan vazifa to'g'ri ishlaydi, lekin u server komponentida ishlamaydi.

Muammoni hal qilish uchun rejalashtirilgan vazifa moduliga server rejimida yana bir seansni boshlaydigan protsedura qo'shamiz va unda tashqi ishlov berishdan mijozga hisobot yaratish chaqiruvini bajaradi.

#If Client Keyin Procedure ExecuteFormationAndSavingReport() Export If ConnectExternalComponent("CommonLayout.NAMEDECL","Cl",ExternalComponentType.COM) Keyin Component = New ("AddIn.Cl.NameDeclension"); //Mana bu hisobotni yaratish va saqlash uchun kod ElseJoinLogRecord("RegTask", LogLogLevel.Error, "Mijozda tashqi komponentni ulab bo'lmadi"); EndIf; Protseduraning oxiri #Otherwise Protsedura ExecuteFormationAndSavingReport() Export ExecuteOperationOnClient("RegularTasks.ExecuteFormationAndSavingReport()"); EndProcedure Procedure PerformOperationOnClient(ParameterToExecute) ExportUserName = ""; UserPassword = ""; PathToExternalProcessing = "c:/temp/Autostart.epf"; Iqtibos = """"; DirectoryBIN = DirectoryProgram(); PathToConfiguration = InfoBase ConnectionString(); ConfigurationPath = StrReplace(ConfigurationPath, Quote, Quote + Quote); StartString = Quote + Bin Directory + "1cv8.exe" + Quote + " ENTERPRISE" + " /IBConnectionString " + Quote + ConfigurationPath + Quote + " /N " + Quote + Username + Quote + " /P " + Quote + UserPassword + Quote + " /Execute " + Quote + PathToExternalProcessing + Quote + " /C " + Quote + ParameterToExecute + Quote; Ilovani ishga tushirish (StartString); EndProcedure #EndIf

Tashqi ishlov berish kodi, bu oddiygina mijoz kontekstidan rejalashtirilgan ishlar modulidan kerakli hisobotni chop etishiga sabab bo'ladi va hisobot yaratilgandan keyin sessiyani tugatadi.

Amalga oshirishga urinish (StartupParameter); Exception EndTry; O'chirish tizimi (noto'g'ri);

Yechimning qulayligi shundaki, rejalashtirilgan vazifalarni o'rnatishda vazifa qaysi rejimda ishga tushirilishi muhim emas. Agar ma'lumotlar bazasi fayl bo'lsa, kerakli protsedura darhol boshlanadi. Agar ma'lumotlar bazasi server tomonida bo'lsa va ishga tushirishda mijoz konteksti bo'lmasa, yangi seans ishga tushiriladi va protsedura mijoz kontekstida to'g'ri ishlaydi.

Oddiy dastur uchun kod. Nazariy jihatdan, u boshqariladigan rejimda mutlaqo o'xshash tarzda ishlaydi.

p.s. Shuningdek, ushbu yondashuv rejalashtirilgan ishlarda har qanday mijoz protseduralarini bajarish uchun ishlatilishi mumkin.

QO‘NG‘IROQ

Bu xabarni sizdan oldin o'qiganlar bor.
Eng so'nggi maqolalarni olish uchun obuna bo'ling.
Elektron pochta
Ism
Familiya
Qo'ng'iroqni qanday o'qishni xohlaysiz
Spam yo'q