الجرس

هناك من قرأ هذا الخبر قبلك.
اشترك للحصول على أحدث المقالات.
البريد الإلكتروني
اسم
اسم العائلة
كيف تحب أن تقرأ الجرس
لا بريد مزعج

السؤال: مكون خارجي Native Api في C ++ لنظام Linux (Ubuntu x64) على 1С 8.3


أنا أكتب VK ، لا يمكنني الاتصال بـ 1s على ubuntu. حتى exapl من 1s غير متصل. إذن سؤال عنها:

1) أحاول توصيل VK من مثال VNCOMPS الوارد في المقالة

(يمكن العثور على الرابط في النهاية: "نسخ").
داخليًا ، يحتوي مشروع NativeApi على ملف makefile. باستخدامه ، أقوم ببناء مكتبة .so على Ununtu.
ولكن في "توصيل المكون الخارجي" 1 تقلع.
وبالمثل ، إذا قمت بالبناء باستخدام "build.sh" (في جذر المشروع).

في makefile نفسه ، أقوم بتغيير العلم من m32 إلى m64 ، لأن 1c ونظام x64 نفسه. (مع المعلمة m32 لا تلتقط على أي حال)
فيما يلي مثال لاستدعاء VK من 1C 8.3:
ConnectionDone = قم بتوصيل مكون خارجي("/ home / alexeyubuntux64-20 gb / Documents / VNCOMP83 / example / NativeAPI / AddInNative.so"، "AddInNative"، ExternalComponentType.Native)؛ هناك مقال فقط حول هذا الموضوع.
ولكن ، بقدر ما أستطيع أن أرى ، تم بالفعل أخذ كل هذه النقاط في الاعتبار وتصحيحها في مثال VNCOMPS.

ولكن في واقع الأمر الأعمال في معايير التجميع. يتم ربط المكون الخارجي MB 32bit حتى 32 بت 1c بشكل طبيعي ، لكني نشرت على Ubuntu x64 1c enterprise83 8.3.5-1486 amd64. وأريد أن ألتقط لها VK.

هل لدى أي شخص أي فكرة عن كيفية حل هذه المشكلة؟
يجب أن يعمل مثال VNCOMPS ، ولكن يجب تصحيح معلمات البناء ، أو أن النظام الأساسي نفسه الذي أختبر عليه غير صحيح.

إجابه:من المثير للاهتمام ، هل من الممكن كتابة مكون خارجي في Java؟

السؤال: المكون الخارجي (الأصلي) غير متصل


تم تجميع مثال مع ITS لأنظمة 64 و 32 بت.

أقوم بالاتصال مثل هذا:
ConnectionResult = ConnectExternalComponent (CDLLPath، "Comp"، ExternalComponentType.Native) ؛ جهاز كمبيوتر واحد يتصل والآخر لا. هناك اختلاف في نظام التشغيل. حيثما يذهب الاتصال ، يوجد Win7 ، حيث لا يوجد Win10. في الوقت نفسه ، تعمل المكونات القياسية على جهاز كمبيوتر حيث لا يعمل المكون الخاص بي.

تم الاختبار على منصات مختلفة (8.3.4.482 ، 8.3.6.2100 ، 8.3.11.2700 ، 8.3.12.1412).

كيف نفهم لماذا لا يتصل؟

إجابه:لم ينسى vc_redist؟

السؤال: 1C8 ومكون خارجي من النوع الأصلي


طاب مسائك.
هناك تكوين BP 3.0.50.12 ورغبة في تنفيذ الوزن من شركة Scales-Soft باستخدام UniServerAuto.
قام المطورون بتجميع المكون الأصلي لنظامي التشغيل Windows 32 و 64 ، ووضعوه في أرشيف مع ملف maifest. يوجد أيضًا مثال لـ 1C ، كيف يمكن حساب الوزن. في ذلك ، بمساعدة تخطيط مع البيانات الثنائية ، يشار إلى هذا الأرشيف ، كما أفهمه. في المثال ، كل شيء على ما يرام: تم تثبيت المكون ، وتوصيله ، ثم تم إنشاء الاتصال وقراءة الوزن.
ولكن بمجرد أن تبدأ في نقل نفسك إلى 1C ، لا تتم قراءة الوزن. يبدو أن كل شيء مكتوب ببساطة ، لكني لا أفهم أين أشعل النار.
من سيحصل على القليل من الوقت - ساعد ، ألق نظرة بعين واحدة ، ربما يكون الحل ظاهريًا ، لكنني أسير في مكان ما في المكان الخطأ وأفعل شيئًا خاطئًا. لم أعمل مطلقًا مع التكنولوجيا الأصلية من قبل ...

وفي المرفق نص معالجة بلدي

إجابه:

حسنًا ، لدي بعض الأخبار ...
لقد بدأت للتو في النظر خطوة بخطوة في أي نقطة تبدأ في الفشل. للقيام بذلك ، قمت بإنشاء قاعدة بيانات فارغة ومعالجتها باستخدام الأمر. عن طريق القياس مع مثال المورد ، قمت بنقل التصميم إلى conf جديدة - تعمل في المرة الثانية. أولئك. المرة الأولى لا ، المرة الثانية نعم. أدى ذلك إلى فكرة أنه لا يزال من الضروري في معالجتها فصل اتصال المكون والكائن وفقًا لإجراءات مختلفة.
ثم قمت بنقله إلى قاعدة البيانات الخاصة بي باستخدام اتصال تخطيط - إنه يعمل. حسنًا ، إنه جيد بالفعل .... لكني أرغب في ذلك دون إجراء تغييرات على التكوين ، لذلك دعنا ننتقل

أحاول إضافة تخطيط للمعالجة. يزداد حجمه على الفور من 10 كيلو بايت إلى 3 ميجا بايت ويلاحظ تباطؤًا كبيرًا - فهو غير مناسب. أبدأ في الحفر باتجاه اتصال مكون من خلال dll. أولئك. في الأساس نفس المكان الذي بدأت منه. ولكن هناك "BUT" واحد: من خلال البحث عن اسم dll في مجلد المستخدم ، لاحظت أن ملف dll هذا يقع حيث (كما أفهمه) تتم إضافة dlls المسجلة في 1C:
C: \ Users \ USER \ AppData \ Roaming \ 1C \ 1cv8 \ ExtCompT
وفقًا لذلك ، ليست هناك حاجة لاستخدام المسار الكامل لملف dll ، يمكنك ببساطة كتابة اسمه:
ConnectExternalComponent ("Add1CUniServerAuto32.dll" ، "UniServerAuto" ، ExternalComponentType.Native) ؛

أحاول ... أقسم عند التسجيل ، لكنني أعيد نتيجة الوزن. اتضح أن dll مسجل بالفعل ، مما يعني أنك تحتاج فقط إلى توصيله. أقوم بإزالته ويعمل كل شيء.
أنا ألخص:
1. في معالجة الوزن في الإجراء عند الفتح ، أضفت توصيل مكون خارجي والاتصال بالكائن.
2. المسار إلى dll لم أكتب ، فقط أشرت إلى اسمه.

الآن أجلس وأفكر ، متى تم تثبيت dll في 1C؟ في وقت تثبيت البرنامج؟ بالكاد ... في وقت تشغيل تكوين المطور لهذا dll ، أين يتم تعيينه عند فتح النموذج؟ لا أعلم ، لكن يبدو أنه قريب مني ... ما رأيك؟
وثانيًا ، في مكان جديد ، عندما تكون هناك حاجة لتثبيت نفس الجهاز ، ما الذي يجب فعله لجعل كل شيء يعمل؟ قم بتثبيت البرنامج بالكامل ، وقم بتشغيل تهيئة المورد للتحقق من العمل ثم (من الناحية النظرية) يجب أن تعمل المعالجة الخاصة بي؟ شيء معقد بعض الشيء ... أو بعد تثبيت البرنامج في المعالجة الخاصة بي ، هل تقوم InstallExternalComponent مرة واحدة؟

أنا أحب أن أسمع أفكارك في هذا الشأن...

السؤال: المكون الخارجي


يوم جيد للجميع.
سؤال.
مكون dll الذي يعمل بشكل جيد في 1C 7.7
في 1s 8.1 لا يريد التمهيد على الإطلاق ...
حاولت ولصقه في C: \ Program Files \ 1cv81 \ bin \ cache1c.dll
حاولت التسجيل باستخدام regsvr32 "C: \ Program Files \ 1cv81 \ bin \ cache1c.dll"
مسجل بدون مشاكل.
عندما أحاول الوصول إليه ، أتلقى رسالة خطأ:

خطأ في تحميل المكون الخارجي! cache1c.dll
زر تنفيذ الإجراء انقر (زر) محاولة تحميل مكون خارجي ( "C: \ Program Files \ 1cv81 \ bin \ cache1c.dll") ؛ تقرير الاستثناء ( "خطأ في تحميل المكون الخارجي!"+ "cache1c.dll") ؛ نهاية المحاولة محاولة // إحضار كائن المكون. // m = جديد ("cache1c.GTMcmd") ؛ m = COMObject جديد ("cache1c.GTMcmd") ؛ تقرير الاستثناء () ؛ نهاية المحاولة EndProcedure

إجابه:تافهة لدرجة الاستحالة ...
من الضروري الحفاظ على فترات التوقف المؤقت بين المكالمات (مللي ثانية) ...
الإجراء ButtonExecuteClick (Button) Attempt // الحصول على كائن المكون. m = COMObject جديد ("cache1c.GTMcmd") ؛ تقرير الاستثناء ( "تعذر إنشاء كائن مكون خارجي") ؛ نهاية المحاولة m.RemoteHost = "192.168.1.101" ؛ م RemotePort = 6330 ؛ م كونيكت () ؛ م وقفة (100) ؛ ...... إلخ
بالنسبة لـ 1s 7.7 - هذا ليس ضروريًا ، اتضح أن الدورة الدموية أسرع.

سؤال: عمل مكون خارجي مع سيرفر 1C ...


طاب مسائك،

يوجد مكون خارجي مكتوب بلغة C ++ ، وتتمثل مهمته في تلقي المعلومات من قاعدة بيانات خارجية وإرجاع نتيجة الاستعلام في شكل جدول قيم في 1C.
لتشكيل جدول قيم في الوقت الحالي ، يتم استخدام واجهة IDispatch * pBackConnection ، والتي يتم تلقيها كمعامل في دالة Init (). علاوة على ذلك ، أنا ببساطة ، باستخدام وظائف 1C ، أقوم بتكوين جدول للقيم ، وأملأه وأعيده إلى المعلمة الثانية في CallAsFunc (...).
بدأت المشاكل مع الانتقال إلى العملاء الرقيقين 1C. على جانب الخادم ، لا يبدأ المكون الخارجي بالفعل. يمكنك تشغيله من جانب العميل ، ولكن كل شيء يبدو وكأنه عكازات ويخرج من منطق "خادم العميل" العام في 1C. على سبيل المثال ، لا يفهم العميل ماهية جدول القيم ، أو المشكلات المتعلقة بالمتغيرات "العامة" ، أو الجلسات ، إلخ.
NativeAPI هو أكثر اقتطاعًا في هذا الصدد.
أدى الرقص باستخدام الدف إلى حقيقة أنني تمكنت من تشغيل مكون خارجي تحت خادم 1C ، ولكن يحدث العمل حتى تتم محاولة استدعاء Invoke on pBackConnection. يحاول الإصدار 64 بت من الخادم 8.2 القيام بشيء ما حتى يتم إيقاف تشغيله في مهلة ، الإصدار 32 بت (VK هو أيضًا 32 بت بشكل طبيعي) يسقط على الفور.
أفترض أن خادم 1C لا يخدم وضع التشغيل هذا.
وفقًا لذلك ، تثار أسئلة ، هل هو مؤقت أم أن منطق 1C مختزل لإلغاء مخطط العمل هذا؟ إذا كان من المستحيل إنشاء هياكل داخلية من 1C (جدول القيم) بهذه الطريقة ، فهل هناك ، من حيث المبدأ ، وصف لما هو جدول القيم على مستوى النظام لمحاولة إنشائه في C + + ، املأه ، ثم انزلق 1C فقط كمعامل إرجاع؟ أود على الأقل الحصول على الاتجاه الذي يجب أن أحفر فيه.

شكرًا لك.

إجابه:

أنت تكتب شيئًا وتعني شيئًا آخر.
في بيئة 1C ، لم يعد الإعلان عن المتغيرات التي ستكون مرئية في جلسات مختلفة أمرًا مستحيلًا الآن ، ولم يكن ذلك ممكنًا من قبل. الجلسة المختلفة هي عملية مختلفة جسديًا.
الجلسة هي جلسة اتصال بقاعدة البيانات ، أي جلسة المستخدم. أم أنك تضع شيئًا خاصًا بك وهذا المفهوم؟

خلال جلسة واحدة كان من الممكن ، ويمكن الآن ، الإعلان عن المتغيرات في وحدة الجلسة ، والتي ستعيش وتكون مرئية داخل الجلسة من أماكن مختلفة ... في الواقع ، هناك 4 متغيرات.
- وحدة الجلسة ؛
- وحدة التطبيق العادية ؛
- وحدة التطبيق المدارة.
- وحدة اتصال خارجية.

وبالطبع ، عليك أن تتذكر السياق. لا يمكن الوصول إلى سياق الخادم مباشرة من جانب العميل والعكس صحيح.

بشكل عام ، توفر بنية 1C استمرار تبادل البيانات:
- عن طريق البارامترات / إرجاع الإجراءات / الوظائف ؛
- عن طريق ما يسمى معلمات الجلسة (لا يمكن أن تكون كائنات ، يمكنك رؤيتها بالفعل في اللوحة).

الجدول الموجود في النموذج ... وهو متصل بأي جدول كائن (عمليات مثلا)؟ أم لا. إذا كانت الإجابة بنعم ، فهو متاح أيضًا على الخادم (& AtServer) وتعديله هناك ....

ونعم ، لا يتوفر ValueTable في UV من جانب العميل. حسنًا ، قررت شركة 1C ذلك.

هيا! هنا يعمل مع Excel ، إنه يعمل مع FSO ومجموعة من كل شيء آخر ، لكن هنا لا يعمل. التقط الخطأ وحلل ....

محاولة
...
أفعالك
...
استثناء
str = DescriptionError () ؛
نهاية المحاولة

مع قدرات الأجهزة الحديثة ، هذه ليست حجة على الإطلاق.

بحت رأيك الشخصي. لا علاقة له بالواقع. ليس بأي حال من الأحوال. أكرر مرة أخرى ، 1C يعمل بشكل رائع مع COM. على حد سواء مع in-proc و out-proc.

أعط الكود الذي تقوم بتحميله وتطبيقه على VK.

بالمناسبة ، VK ... في حالتك ، هل هو COM أو Native API؟
إذا كان COM ، ثم قمت بتسجيله كـ ... من خلال regsvr32 ... فكيف "تحل" مشكلة عمق البت؟

السؤال: تركيب مكون خارجي


من فضلك قل لي كيفية تثبيت مكون خارجي. عند تنفيذ الكود التالي ، حدث خطأ. ابحث عن NameDecl.dll في التخطيط

محاولة SetExternalComponent ("GeneralLayout.Layout") ؛ EndTry استثناء ؛
خطأ: فشل تثبيت البرنامج المساعد!

إجابه: ()
يُرجع ConnectExternalComponent ("GeneralLayout.Layout" و "NameDecl" و ExternalComponentType.Native) القيمة FALSE ،
جديد ("AddIn.NameDecl.CNameDecl" ، غير محدد) = (()): النوع غير محدد (AddIn.NameDecl.NameDecl)

السؤال: Native dll غير متصل بـ 1s 8.1 (fptrwin32_fz54_9_11_0_5549.dll)


مرحبًا.
قام 1C بتحديث dll لسجلات النقد عبر الإنترنت atol لـ fdd 1.05 (مضمن في معالجة صيانة fptrwin32_fz54_9_11_0_5549.dll).
لدي قديم 1C 8.1. على عكس 8.2 ، فهو لا يدعم العمل مع المعدات الخارجية بنفس طريقة 8.2 ، لذلك تحتاج أولاً إلى تسجيل dll في windows ، ثم توصيله بـ 1C فقط؟

ProgID = "AddIn.IntegrationComponent.ATOL_KKT_1C83_V9" ؛ LoadExternalComponent ("C: \ fptrwin32_fz54_9_11_0_5549.dll") ؛ ConnectExternalComponent (ProgID) ، سائق = جديد (ProgID) ؛

ومع ذلك ، تمت كتابة المعالجة القديمة في "التكنولوجيا" com ، والموطن الجديد. وفقًا لذلك ، عند التسجيل ، يعطي regsvr32 خطأ:
تم تحميل الوحدة النمطية ، ولكن لم يتم العثور على نقطة إدخال DllRegisterServer. ويقترح التحقق من أن هذا الملف هو ملف dll أو OCX الصحيح.
من واجه وضعا مشابها ، كيف خرجت؟ أفهم أن مشكلة مماثلة ستكون في 7.7.
الكود 8.2:

Layout = GetLayout ("IntegrationComponent") ؛ العنوان = PlaceInTempStorage (تخطيط) ، ConnectExternalComponent (العنوان ، "IntegrationComponent" ، ExternalComponentType.Native) ؛ برنامج التشغيل = جديد ("AddIn.IntegrationComponent.ATOL_KKT_1C83_V9") ؛

1 ج 8.2:
توصيل المكون الخارجي (<Местоположение>, <Имя>, <Тип>)
1C 8.1:
توصيل المكون الخارجي (<Идентификатор объекта>)
خيارات:
<Идентификатор объекта>(مطلوب)
النوع: سلسلة. ProgID (معرف برمجي) لكائن المكون الخارجي. يجب أن تتطابق مع المعلومات الموجودة في قاعدة بيانات تسجيل النظام (التسجيل).
وصف:
يربط كائنات المكونات الخارجية بـ 1C: Enterprise.
غير متاح على 1C: خادم Enterprise. لا تستخدم في وحدة الاتصال الخارجية.
ملحوظة:
المكونات الخارجية متوافقة مع مكونات 1C: Enterprise 7.7.
مثال:
محاولة
ConnectExternalComponent ("AddinObject.Scanner") ؛
تنبيه ("تم تحميل مكون ماسح الباركود") ؛
استثناء
تنبيه ("لم يتم تحميل مكون ماسح الباركود") ؛
إنهاء المحاولات

هل هناك أي طريقة لربط هذا dll بـ 8.1 أم لا؟

شكرًا لك!

إجابه:

لقد واجهت هذه المشكلة مؤخرًا. لم يكن من الممكن التحويل إلى إصدار أحدث من 1s. dll الذي يعمل به هذا التكوين ببساطة توقف عن العمل وسقط 1c بخطأ.
تم حل المشكلة بالطريقة التالية:
لقد أنشأت قاعدة بيانات فارغة 8.3 عالجت فيها تهيئة المكون ثم من 8.1 عبر اتصال COM ، وصلت إلى قاعدة البيانات التي تم إنشاؤها مسبقًا وقمت بتهيئة المكون هناك. ثم ، بالفعل في 8.1 ، اتصلت بأساليب هذا المكون.
بالطبع ، هذا عكاز ، لكنني لم أجد مخرجًا آخر بعد (

مثال التعليمات البرمجية 8.3:
تصدير برنامج التشغيل العيني ؛
وظيفة ConnectionComponentsCCP () Export
محاولة

Layout = GetLayout ("IntegrationComponent") ؛
العنوان = PlaceInTempStorage (تخطيط) ،
ConnectExternalComponent (العنوان ، "IntegrationComponent" ، ExternalComponentType.Native) ؛
برنامج التشغيل = جديد ("AddIn.IntegrationComponent.SMDrvFR1C20") ؛
النتيجة = صحيح ؛

استثناء

النتيجة = خطأ ؛

نهاية المحاولة
نتيجة العودة
وظائف النهاية

مثال رمز 8.1

الوظيفة CreateDriverObject (Driver) Export

النتيجة = صحيح ؛

محاولة

ConnectionString = "File =" "" مسار قاعدة البيانات "" "؛
ComObject = COMObject جديد ("V83.ComConnector") ؛
Connect = ComObject.Connect (ConnectionString) ؛

معالجة = Connect.Processing.ConnectingExternalComponent.Create () ،
ConnectionResult = Processing.ConnectingKKT مكونات () ،
إذا تم توصيل النتيجة بعد ذلك
السائق = Processing.Driver ؛
EndIf ؛

استثناء
أي شخص قام بهذا أو واجه مشكلات مماثلة ، يرجى توضيح ذلك. مثال بسيطالمبدأ نفسه. يبدو أن كل شيء واضح فيما يتعلق بتوصيل المكونات الخارجية.

// مثال لملء جدول القيم TK.Clear () ؛ طلب = طلب جديد ؛ Query.Text = "حدد | التسمية. ارتباط كيف التسمية | من | Directory.Nomenclature AS Nomenclature "؛ QueryResult = Query.Execute ()؛ Sampling = QueryResult.Select ()؛ while Sampling.Next () Loop Str = TK.Add ()؛ FillPropertyValues ​​(Pr، Sampling)؛ EndCycle؛
هل يمكن أن توضح بهذا المثال أي جزء من الكود يتم أخذه عادةً. سيكون من المنطقي إخراج الجزء مع الطلب ، ولكن بعد ذلك كيف يمكننا الوصول إلى قاعدة البيانات من المكون الخارجي من المكون الخارجي ، متجاوزًا النظام الأساسي؟ النص لا معنى له. أو قم بإخراج تشكيل الجزء الجدولي. يرجى مشاركة تجربتك مع هذا.

إجابه:وأن كلمة "غير متوافق" تعني دائماً كلمة "سيئة"؟ نعم ، يبدو لي أنني إذا أطلقت على أسلوبي "1C: أسوأ برمجة على محرك البرمجة النصية هذا موجودة في الطبيعة (مترجمة إلى لغة أدبية)!" ومن المؤكد أنه سيكون هناك من يريدون التحقق من هذا الوحش. ويبدو أنه كلاسيكي: "لم أقرأ باسترناك ، لكنني أختلف معه تمامًا!" :)

السؤال: توصيل مكون خارجي في 1s 8.3.6 و Win8


من الضروري توصيل المكون الخارجي vk_rs232.dll بالتكوين المكتوب ذاتيًا. مثل مسجلة من خلال regsvr32.exe. "يبدو" لأنني تلقيت رسالة مفادها "تم تسجيل المكون ، ولكن هناك خطأ ما في جدار الحماية." بالاعتماد على النصف الأول من الرسالة ، أكتب الكود في 1 ثانية
AfterConnection = New NotificationDescription ("AfterConnectionVK"، ThisForm) ؛ StartExternalComponentInstallation (، "C: \ Controller \ vk_rs232.dll") ؛ StartConnectingExternalComponent (بعد الاتصال ، "C: \ Controller \ vk_rs232.dll" ، "DLL_Scales") ؛
وأحصل على الخطأ
"فشل تثبيت المكون الخارجي! قد يكون مكون تطبيق العميل الذي تستخدمه مفقودًا!".

والآن أنا لا أفهم
1. ربما لم يتم تسجيل المكون في التسجيل - كيف يمكنني التحقق منه هناك؟
2. ربما لا تعمل "نسخته" تحت Win8 ، على الرغم من أنني أمتلكها 32 بت.
3. ربما تكون الآحاد نفسها جديدة جدًا ، أي وفقا لذلك لا يمكن العمل مع هذا dll؟
4. حسنًا ، إنه أمر عادي - أنا أكتب شيئًا خاطئًا.

إجابه:وكل هذا قادني إلى المشكلة التالية. تم تثبيت VneshComp ، الآن تحتاج إلى توصيله. وهنا كلا الخيارين.
ConnectExternalComponent ("C: \ Controller \ vk_rs232.dll"، "Scales")
ConnectExternalComponent ("GeneralLayout.Layout"، "Scales")

خيار بناء الجملة: بالاسم والموقع

بناء الجملة:

توصيل المكون الخارجي (<Местоположение>, <Имя>, <Тип>)
خيارات:

<Местоположение>(مطلوب)

النوع: سلسلة.
موقع المكون الخارجي.
يمكن استخدام الموقع:
المسار إلى ملف المكون الخارجي في نظام الملفات (غير متوفر على عميل الويب) ، وليس أرشيف ZIP ؛
الاسم الكاملتخطيط يخزن البيانات الثنائية أو أرشيف ZIP ؛
عنوان URL للمكون الخارجي ، في شكل بيانات ثنائية أو أرشيف مضغوط ، بشكل مشابه لـ GetNaviLink.
<Имя>(مطلوب)

النوع: سلسلة.
الاسم الرمزي للمكون الخارجي القابل للتوصيل.
يجب أن يتبع الاسم اصطلاحات التسمية للغة المضمنة.
<Тип>(اختياري)

النوع: نوع المكون الخارجي.
نوع المكون الخارجي المراد توصيله.
لا يتم استخدامه إذا كان المكون محزمًا في أرشيف بتنسيق ZIP.
وصف متغير الطريقة:

يربط المكونات المصنوعة باستخدام تقنية Native و COM.
يمكن تخزين المكون في قاعدة معلومات أو تخطيط تكوين كبيانات ثنائية أو في أرشيف مضغوط.
بالنسبة لأوضاع التشغيل "العميل الرقيق" و "عميل الويب" ، يجب تثبيت المكون مسبقًا باستخدام طريقة تثبيت المكون الخارجي.
خيار بناء الجملة: بواسطة المعرف

بناء الجملة:

توصيل المكون الخارجي (<ИдентификаторОбъекта>)
خيارات:

<ИдентификаторОбъекта>(مطلوب)

النوع: سلسلة.
معرف كائن مكون خارجي في شكل ProgID (معرف برمجي) لتسجيل MS Windows (على سبيل المثال: "AddIn.Scanner").
يجب أن تتطابق مع المعلومات الموجودة في قاعدة بيانات تسجيل النظام (التسجيل).
وصف متغير الطريقة:

يجب تنفيذ المكون باستخدام تقنية COM وتسجيله في سجل MS Windows.
هذه المكونات متوافقة مع مكونات 1C: Enterprise 7.7.
انتباه! متغير الأسلوب لا يعمل على الخادم وفي الاتصال الخارجي.
قيمة الإرجاع:

النوع: منطقي.
صحيح - كان الاتصال ناجحًا.
وصف:

يربط مكونًا خارجيًا بـ 1C: Enterprise.
يمكن تخزين المكونات الخارجية في قاعدة المعلومات أو تخطيطات التكوين كأرشيف ZIP أو كبيانات ثنائية أو في ملف نظام الملفات.
عند العمل على عميل رفيع وعميل ويب ، يجب تثبيت المكون مسبقًا.

التوفر:

عميل رفيع ، عميل ويب ، خادم ، اتصال خارجي.
ملحوظة:

يمكن تنفيذ المكونات الخارجية باستخدام Native API أو تقنية COM. المكونات المصنوعة باستخدام تقنية COM متوافقة مع مكونات 1C: Enterprise 7.7.
لا يمكن لعميل الويب العمل إلا مع المكونات الموجودة في قاعدة معلومات معبأة في أرشيف.
يمكن للعميل الرقيق العمل مع المكونات الموجودة في قاعدة المعلومات ، معبأة في أرشيف ، والمكونات الموجودة في نظام الملفات.
يمكن للعميل السميك العمل مع جميع خيارات التخزين للمكونات. في هذه الحالة ، إذا تم تثبيت المكون باستخدام طريقة InstallExternalComponent ، فسيتم استخدام المكون المثبت ، وإذا لم يتم تثبيته ، فسيتم استلام المكون في وقت الاتصال.
يمكن للخادم العمل مع جميع المكونات. المكون مخزن مؤقتا لجلسة عمل الخادم.
مثال:

إذا كان ConnectExternalComponent ("AddinObject.Scanner") ثم
تنبيه ("تم تحميل مكون ماسح الباركود") ؛
خلاف ذلك
تنبيه ("لم يتم تحميل مكون ماسح الباركود") ؛
إنهاء إذا؛

  • الدورة التعليمية

مقدمة

تعطي هذه المقالة فكرة عن كيفية عمل المكونات الخارجية في 1C: نظام المؤسسة.
عملية تطوير مكون خارجي لـ 1C: سيتم عرض نظام الإصدار 8.2 للمؤسسات الذي يعمل تحت نظام التشغيل Windows مع إصدار ملف للعمل. يستخدم هذا الخيار في معظم الحلول المصممة للشركات الصغيرة. سيتم تنفيذ VC بلغة البرمجة C ++.

المكونات الخارجية "1C: Enterprise"

"1C: Enterprise" هو نظام قابل للتوسيع. للتوسع وظائفيستخدم النظام مكونات خارجية (VC). من وجهة نظر المطور ، يعد VC كائنًا خارجيًا له خصائص وطرق ، ويمكنه أيضًا إنشاء أحداث للمعالجة بواسطة 1C: نظام المؤسسة.
يمكن استخدام المكونات الخارجية لحل فئة من المهام التي يصعب أو حتى من المستحيل تنفيذها باستخدام لغة البرمجة المدمجة في 1C: Enterprise. على وجه الخصوص ، تتضمن هذه الفئة المهام التي تتطلب تفاعلًا منخفض المستوى مع نظام التشغيل ، على سبيل المثال ، للعمل مع أجهزة معينة.
1C: يستخدم نظام المؤسسة تقنيتين لإنشاء مكونات خارجية:
  • باستخدام واجهة برمجة التطبيقات الأصلية
  • باستخدام تقنية COM
نظرًا للقيود بين التقنيتين المذكورتين أعلاه ، فإن الاختلاف غير مهم ، لذلك سننظر في تطوير VK باستخدام Native API. إذا لزم الأمر ، يمكن تطبيق التطورات المنفذة على تطوير VC باستخدام تقنية COM ، وأيضًا ، مع تعديلات طفيفة ، مطبقة للاستخدام في 1C: نظام المؤسسة مع خيارات تشغيل أخرى غير وضع ملف التشغيل.
هيكل VK
المكون الخارجي لـ 1C: يتم تقديم نظام المؤسسة كمكتبة DLL. يصف رمز المكتبة الفئة المشتقة من IComponentBase. في الفصل الذي يتم إنشاؤه ، يجب تحديد الطرق المسؤولة عن تنفيذ وظائف المكون الخارجي. سيتم وصف الطرق التي تم تجاوزها بمزيد من التفصيل لاحقًا في سياق عرض المواد.

إطلاق الإصدار التجريبي من VK

مهمة:
  1. قم بتجميع المكون الخارجي المزود باشتراك ITS والمصمم لإظهار القدرات الرئيسية لآلية المكونات الخارجية في 1C
  2. قم بتوصيل مكون العرض التوضيحي بتكوين 1C
  3. تأكد من أن الوظائف المعلنة تعمل بشكل صحيح
التحويل البرمجي
يوجد VC التجريبي على قرص اشتراك ITS في دليل "/ VNCOMP82 / example / NativeAPI".
سوف نستخدم Microsoft Visual Studio 2008 لتجميع العرض التوضيحي VK. لا تدعم الإصدارات الأخرى من هذا المنتج تنسيق مشروع Visual Studio المستخدم.


افتح مشروع AddInNative. في إعدادات المشروع ، نقوم بتوصيل الدليل بملفات الرأس اللازمة لبناء المشروع. بشكل افتراضي ، تكون موجودة على قرص ITS في الدليل / VNCOMP82 / تضمين.
نتيجة البناء هي ملف /bind/AddInNative.dll. هذه هي المكتبة المترجمة للاتصال بتكوين 1C.
توصيل VK بتكوين 1C
لنقم بإنشاء تكوين فارغ 1C.
فيما يلي رمز وحدة التطبيق المدارة.
فار ديموكومب. SystemStartup Procedure () ConnectExternalComponent ("... \ bind \ AddInNative.dll"، "DemoVK"، ExternalComponentType.Native) ؛ DemoComp = جديد ("AddIn.DemoVK.AddInNativeExtension") ؛ EndProcedure
إذا لم يتم الإبلاغ عن أي خطأ عند بدء تكوين 1C ، فقد تم توصيل VK بنجاح.
نتيجة لتنفيذ الكود أعلاه ، يظهر كائن في الرؤية العالمية للتكوين ديموكومبالذي يحتوي على الخصائص والطرق التي تم تحديدها في كود الفول الخارجي.
عرض الوظيفة المضمنة
دعنا نتحقق من أداء VK التجريبي. للقيام بذلك ، دعنا نحاول تعيين بعض الخصائص وقراءتها ، واستدعاء بعض طرق VK ، وكذلك تلقي رسالة VK ومعالجتها.
توضح الوثائق المتوفرة على قرص ITS الوظائف التالية للعرض التوضيحي VC:
  1. إدارة حالة كائن المكون
    طُرق: شغله, اطفيء
    الخصائص: متضمن
  2. التحكم بالمؤقت
    كل ثانية ، يرسل المكون رسالة إلى 1C: نظام المؤسسة مع المعلمات مكون, جهاز ضبط الوقتوسلسلة عداد ساعة النظام.
    طُرق: StartTimer, StopTimer
    الخصائص: هناك جهاز توقيت
  3. طريقة ShowInStatusLine، والذي يعرض في شريط الحالة النص الذي تم تمريره إلى الطريقة كمعلمات
  4. طريقة تحميل الصور. يقوم بتحميل صورة من الملف المحدد ونقلها إلى 1C: نظام Enterprise كبيانات ثنائية.
دعونا نتأكد من أن هذه الوظائف تعمل. للقيام بذلك ، سنقوم بتنفيذ الكود التالي:
فار ديموكومب. SystemStart () إجراء ConnectExternalComponent (...) ؛ DemoComp = جديد ("AddIn.DemoVK.AddInNativeExtension") ؛ DemoComp.Disable () ، إعلام (DemoComp. ممكّن) ؛ DemoComp.Enable () ، إعلام (DemoComp. ممكّن) ؛ DemoComp.StartTimer () ، تقرير EndProcedure ProcedureExternalEventHandler (المصدر والحدث والبيانات) (المصدر + "" + Event + "" + Data) ؛ EndProcedure
تظهر نتيجة تشغيل التكوين في الصورة


يتم عرض نتائج استدعاءات الأسلوب في لوحة "الرسائل" DemoComp.Disable ()و Demo.Comp.Enable (). تحتوي الأسطر التالية في نفس اللوحة على نتائج معالجة الرسائل المستلمة من VK - مصدر, حدثو بياناتعلى التوالى.

اسم مكون خارجي تعسفي

المهمة: قم بتغيير اسم المكون الخارجي إلى اسم تعسفي.
استخدم القسم السابق المعرف AddInNativeExtensionالتي لم يتم شرح معانيها. في هذه الحالة AddInNativeExtensionهو اسم الامتداد.
يحدد رمز VC طريقة RegisterExtensionAs، والذي يعيد الاسم إلى 1C: نظام المؤسسة ، وهو أمر ضروري للتسجيل اللاحق لـ VC في النظام. يوصى بتحديد معرّف يكشف ، إلى حد ما ، جوهر المكون الخارجي.
هذا هو الكود الكامل للطريقة RegisterExtensionAsمع تغيير اسم الامتداد:
منطقي CAddInNative :: RegisterExtensionAs (WCHAR_T ** wsExtensionName) (wchar_t * wsExtension = L "SomeName" ؛ int iActualSize = :: wcslen (wsExtension) + 1 ؛ WCHAR_T * dest = 0 ؛ if (m_iMemory) (if (m_iMemory-> ((void **) wsExtensionName، iActualSize * sizeof (WCHAR_T))) :: convToShortWchar (wsExtensionName، wsExtension، iActualSize)؛ إرجاع صحيح؛) إرجاع خطأ؛)
في المثال أعلاه ، تم تغيير اسم VK إلى بعض الاسم. بعد ذلك ، عند توصيل VK ، يجب عليك تحديد اسم جديد:
DemoComp = جديد ("AddIn.DemoVK.SomeName") ؛

توسيع قائمة خصائص VK

مهمة:
  1. دراسة تنفيذ خصائص رأس المال الاستثماري
  2. إضافة خاصية القراءة والكتابة لنوع سلسلة
  3. قم بإضافة خاصية نوع سلسلة القراءة / الكتابة التي تخزن نوع بيانات الخاصية التي تم تعيينها مؤخرًا. لم يتم اتخاذ أي إجراء عند تحديد قيمة الخاصية

لتحديد خصائص المكون الذي يتم إنشاؤه ، يحتاج المطور إلى تنفيذ الطرق التالية في كود مكتبة AddInNative.cpp:
GetNProps
لعرض عدد الخصائص لهذا الامتداد ، 0 في حالة عدم وجود خصائص
FindProp
إرجاع الرقم الترتيبي للخاصية التي تم تمرير اسمها في المعلمات
GetPropName
تُرجع اسم الخاصية بترتيبها ومعرف اللغة الذي تم تمريره
GetPropVal
ترجع قيمة الخاصية بالترتيب الترتيبي المحدد
SetPropVal
يضبط قيمة الخاصية بالترتيب المحدد
IsPropReadable
تُرجع علامة قابلية القراءة للخاصية بترتيب محدد
IsPropWritable
تُرجع علامة قابلية الكتابة للخاصية برقم التسلسل المحدد


ضع في اعتبارك تنفيذ طرق الفصل المذكورة أعلاه CAddInative.
يحدد VC التجريبي خاصيتين: متضمنو هناك جهاز توقيت (ممكنو الحاضر).
تم تعريف صفيفتين في النطاق العام لرمز المكتبة:
ثابت wchar_t * g_PropNames = (L "IsEnabled" ، L "IsTimerPresent") ؛ ثابت wchar_t * g_PropNamesRu = (L "ممكّن" ، L "يوجد مؤقت") ؛
التي تخزن أسماء العقارات الروسية والإنجليزية. في ملف الرأس AddInNative.hيتم تعريف التعداد:
Enum Props (ePropIsEnabled = 0 ، ePropIsTimerPresent ، ePropLast // Always last) ؛
ePropIsEnabledو ePropIsTimerPresent، التي تحتوي على القيمتين 0 و 1 على التوالي ، تُستخدم لاستبدال الأرقام الترتيبية للخصائص بمعرفات ذات معنى. يتم استخدام ePropLast ، الذي له قيمة 2 ، للحصول على عدد الخصائص (باستخدام طريقة GetNProps). تُستخدم هذه الأسماء فقط داخل رمز المكون ولا يمكن الوصول إليها من الخارج.
تبحث أساليب FindProp و GetPropName خلال المصفوفات g_PropNamesو g_PropNames.
لتخزين قيمة الحقول في وحدة المكتبة ، فإن فئة CAddInNative لها خصائص تخزن قيمة خصائص المكون. طُرق GetPropValو SetPropValعلى التوالي إرجاع وتعيين قيمة هذه الخصائص.
طُرق IsPropReadableو IsPropWritableوالعودة حقيقيأو خاطئة، اعتمادًا على ترتيبي تم تمريره للخاصية وفقًا لمنطق التطبيق.
لإضافة خاصية مخصصة:

  1. أضف اسم الخاصية المراد إضافتها إلى المصفوفات g_PropNamesو g_PropNames(ملف AddInNative.cpp)
  2. لتعداد الدعائم(ملف AddInNative.h) قبل ePropLastأضف اسمًا يعرّف بشكل فريد الخاصية المراد إضافتها
  3. تنظيم الذاكرة لتخزين قيم الخصائص (إنشاء حقول وحدة مكون تخزن القيم المقابلة)
  4. قم بإجراء تغييرات على الأساليب GetPropValو SetPropValللتفاعل مع الذاكرة المخصصة في الخطوة السابقة
  5. وفقًا لمنطق التطبيق ، قم بإجراء تغييرات على الأساليب IsPropReadableو IsPropWritable
البنود 1 و 2 و 5 لا تحتاج إلى شرح. يمكن العثور على تفاصيل تنفيذ هذه الخطوات في ملحق المقالة.
دعنا نسمي خصائص الاختبار اختبارو اكتب التحققعلى التوالى. بعد ذلك ، نتيجة للفقرة 1 ، لدينا:
ثابت wchar_t * g_PropNames = (L "IsEnabled" ، L "IsTimerPresent" ، L "Test" ، L "TestType") ؛ ثابت wchar_t * g_PropNamesRu = (L "Enabled"، L "HasTimer"، L "Test"، L "CheckType") ؛
تعداد الدعائمسيبدو مثل:
enum Props (ePropIsEnabled = 0، ePropIsTimerPresent، ePropTest1، ePropTest2، ePropLast // Always last) ؛
لتبسيط الشفرة بشكل كبير ، سنستخدم STL C ++. على وجه الخصوص ، للعمل مع السلاسل WCHAR، قم بتوصيل المكتبة wstring.
لتخزين قيمة الطريقة اختبار، حدد في الفصل CAddInativeفي المجال الخاص:
اختبار السلسلة 1 ؛
لنقل معلمات السلسلة بين 1C: Enterprise ومكون خارجي ، يتم استخدام 1C: Enterprise memory manager. دعونا نلقي نظرة فاحصة على عمله. لتخصيص الذاكرة وتحريرها ، على التوالي ، استخدم الوظائف AllocMemoryو ذاكرة متاحةالمحدد في الملف MemoryManager.h. إذا كان من الضروري تمرير معلمة سلسلة إلى 1C: نظام المؤسسة ، يجب أن يخصص المكون الخارجي ذاكرة له عن طريق استدعاء الوظيفة AllocMemory. يبدو نموذجها الأولي كما يلي:
منطقي ظاهري ADDIN_API AllocMemory (باطل ** pMemory ، ulCountByte طويل بدون توقيع) = 0 ؛
أين pMemory- عنوان المؤشر الذي سيوضع فيه عنوان الذاكرة المخصصة ،
أولكونت بايت- حجم مساحة الذاكرة المخصصة.
مثال على تخصيص ذاكرة لسلسلة:
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) ؛
لراحة العمل مع أنواع بيانات السلسلة ، نحن نصف الوظيفة wstring_to_p. يأخذ سلسلة wstring كمعامل. نتيجة الوظيفة هي بنية ممتلئة t متغير. كود الوظيفة:
منطقي 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 () ؛ العودة صحيح؛)
ثم قسم الحالة المقابل من بيان التبديل للطريقة GetPropValسوف يأخذ النموذج:
حالة ePropTest1: wstring_to_p (test1 ، pvarPropVal) ؛ فترة راحة؛
طريقة SetPropVal:
حالة ePropTest1: إذا كانت (TV_VT (varPropVal)! = VTYPE_PWSTR) ترجع خطأ ؛ test1 = الأمراض المنقولة جنسيا :: wstring ((wchar_t *) (varPropVal -> pstrVal)) ؛ فترة راحة؛
لتنفيذ الخاصية الثانية ، نحدد حقل فئة العلبة الأصلية
uint8_t last_type ؛
حيث سنخزن نوع آخر قيمة تم تمريرها. للقيام بذلك ، أضف الأمر التالي إلى أسلوب CaddInNative :: SetPropVal:
last_type = TV_VT (varPropVal) ،
الآن ، عند طلب قراءة قيمة الخاصية الثانية ، سنعيد القيمة النوع_الأخير، وهو ما تتطلبه المهمة المعينة.
دعنا نتحقق من أداء التغييرات التي تم إجراؤها.
لهذا نقدم مظهر خارجيالتكوين 1C للعرض:
فار ديموكومب. SystemStartup Procedure () ConnectExternalComponent ("..."، "DemoVK"، ExternalComponentType.Native) ؛ DemoComp = جديد ("AddIn.DemoVK.SomeName") ؛ DemoComp.CheckType = 1 ، تقرير (سلسلة (DemoComp.TypeCheck)) ؛ DemoComp.Test = "Vasya" ؛ تقرير (سلسلة (DemoComp.Test)) ؛ DemoComp.Test = "بيتيا" ؛ تقرير (سلسلة (DemoComp.Test)) ؛ تقرير (سلسلة (DemoComp.TypeCheck)) ؛ EndProcedure
نتيجة الإطلاق ، نحصل على سلسلة من الرسائل:
3
فاسيا
بيتيا
22

الرسالتان الثانية والثالثة هما نتيجة قراءة الخاصية المعينة في الخطوة السابقة. تحتوي الرسالة الأولى والثانية على رمز نوع مجموعة الخصائص الأخيرة. 3 يتوافق مع قيمة عدد صحيح ، 22 - إلى قيمة سلسلة. يتم إنشاء مراسلات الأنواع ورموزها في الملف أنواع، الموجود على قرص ITS.

توسيع قائمة الأساليب

مهمة:
  1. توسيع وظائف المكون الخارجي بالوظائف التالية:
  2. تعلم كيفية تنفيذ طرق المكونات الخارجية
  3. أضف طريقة الوظيفة وظيفة 1، والتي تأخذ سلسلتين ("Parameter1" و "Parameter2") كمعامل. نتيجة لذلك ، يتم إرجاع سلسلة من النموذج: "تحقق. المعلمة 1 ، المعلمة 2 "
  4. تحقق من أن التغييرات التي تم إجراؤها تعمل.

لتحديد طرق المكون الذي يتم إنشاؤه ، يحتاج المطور إلى تنفيذ الطرق التالية في كود مكتبة AddInNative:
GetNMethods, FindMethod, GetMethodName
مصمم للحصول على عدد الطرق ، على التوالي ، والبحث عن رقم واسم الطريقة. على غرار الأساليب المقابلة للخصائص
GetNParams
إرجاع عدد معلمات الأسلوب برقم التسلسل المحدد ؛ إذا لم تكن هناك طريقة بهذا الرقم أو لا تحتوي على معلمات ، يتم إرجاع 0
GetParamDefValue
إرجاع القيمة الافتراضية للمعلمة المحددة للطريقة المحددة
HasRetVal
ترجع إشارة إلى أن الطريقة ذات القيمة المرجعة المحددة لها ترتيبي: صحيح للأساليب ذات القيمة المرجعة و خاطئةخلاف ذلك
CallAsProc
خاطئة، حدث خطأ في وقت التشغيل وتوقف تنفيذ الوحدة النمطية 1C: Enterprise. يتم تخصيص الذاكرة الخاصة بمصفوفة المعلمات وإصدارها بواسطة 1C: Enterprise.
CallAsFunc
ينفذ الطريقة بالترتيب المحدد. إذا عادت الطريقة خاطئة، حدث خطأ في وقت التشغيل وتوقف تنفيذ الوحدة النمطية 1C: Enterprise. يتم تخصيص ذاكرة صفيف المعلمات بواسطة 1C: Enterprise. إذا كانت قيمة الإرجاع من نوع سلسلة أو بيانات ثنائية ، يخصص المكون ذاكرة مع الوظيفة AllocMemoryمدير الذاكرة ، يكتب البيانات هناك ويخزن هذا العنوان في المجال المقابل للهيكل. 1С: ستقوم المؤسسة بتحرير هذه الذاكرة عن طريق الاتصال ذاكرة متاحة.
وصف كامل للطرق ، بما في ذلك قائمة المعلمات ، موصوف بالتفصيل في الوثائق المتوفرة على قرص ITS.
ضع في اعتبارك تنفيذ الطرق الموضحة أعلاه.
في كود المكون ، تم تعريف صفيفتين:
ثابت wchar_t * g_MethodNames = (L "Enable"، L "Disable"، L "ShowInStatusLine"، L "StartTimer"، L "StopTimer"، L "LoadPicture") ؛ ثابت wchar_t * g_MethodNamesRu = (L "Enable"، L "Disable"، L "ShowInStatusLine"، L "StartTimer"، L "StopTimer"، L "LoadImage") ؛
و عد:
طرق التعداد (eMethEnable = 0 ، eMethDisable ، eMethShowInStatusLine ، eMethStartTimer ، eMethStopTimer ، eMethLoadPicture ، eMethLast // دائمًا الأخير) ؛
يتم استخدامها في الوظائف GetNMethods, FindMethodو GetMethodNameقياسا على وصف الخصائص.
طُرق GetNParams, GetParamDefValue, HasRetValتنفيذ التبديل ، اعتمادًا على المعلمات التي تم تمريرها ومنطق التطبيق ، قم بإرجاع القيمة المطلوبة. طريقة HasRetValفي الكود الخاص به قائمة بالطرق الوحيدة التي يمكنها إرجاع نتيجة. بالنسبة لهم يعود حقيقي. لجميع طرق إرجاع الصلب خاطئة.
طُرق CallAsProcو CallAsFuncتحتوي على رمز طريقة قابلة للتنفيذ مباشرة.
لإضافة طريقة لا يمكن استدعاؤها إلا كدالة ، تحتاج إلى إجراء التغييرات التالية في التعليمات البرمجية المصدر للمكون الخارجي:
  1. أضف اسم الأسلوب إلى المصفوفات g_MethodNamesو g_MethodNames(ملف AddInNative.cpp)
  2. أضف معرف أسلوب ذي معنى إلى تعداد الأساليب (ملف AddInNative.h)
  3. قم بإجراء تغييرات على رمز الوظيفة GetNParamsحسب منطق البرنامج
  4. إذا لزم الأمر ، قم بإجراء تغييرات على رمز الطريقة GetParamDefValueإذا كنت تريد استخدام القيم الافتراضية لمعلمات الطريقة.
  5. قم بإجراء تغييرات على وظيفة HasRetVal
  6. قم بإجراء تغييرات على منطق الوظائف CallAsProcأو CallAsFunc، عن طريق وضع الكود القابل للتنفيذ المباشر للطريقة هناك
دعونا نحضر المصفوفات g_MethodNamesو g_MethodNamesوكذلك العد طُرقللعرض:
ثابت wchar_t * g_MethodNames = (L "Enable"، L "Disable"، L "ShowInStatusLine"، L "StartTimer"، L "StopTimer"، L "LoadPicture"، L "Test") ؛ ثابت wchar_t * g_MethodNamesRu = (L "Enable"، L "Disable"، L "ShowInStatusLine"، L "StartTimer"، L "StopTimer"، L "LoadImage"، L "Test") ؛

طرق التعداد (eMethEnable = 0 ، eMethDisable ، eMethShowInStatusLine ، eMethStartTimer ، eMethStopTimer ، eMethLoadPicture ، eMethTest ، eMethLast // دائمًا الأخير) ؛
دعنا نعدل الوظيفة GetNPropsبحيث تعرض عدد معلمات طريقة "الاختبار":
long CAddInNative :: GetNParams (const long lMethodNum) (التبديل (lMethodNum) (الحالة eMethShowInStatusLine: return 1 ؛ case eMethLoadPicture: return 1 ؛ case eMethTest: return 2 ؛ default: return 0 ؛) return 0 ؛)
دعنا نجري تغييرات على الوظيفة:
bool CAddInNative :: GetParamDefValue (const long lMethodNum، const long lParamNum، tVariant * pvarParamDefValue) (TV_VT (pvarParamDefValue) = VTYPE_EMPTY ؛ التبديل (lMethodNum) (caseTodNum) : حالة / لا توجد قيم معلمات بواسطة فاصل افتراضي ؛ افتراضي: إرجاع خطأ ؛) إرجاع خطأ ؛)
بفضل الخط المضاف
اختبار حالة eMethTest:
في حالة عدم وجود وسيطة واحدة أو أكثر ، سيكون للمعلمات المقابلة قيمة فارغة ( VTYPE_EMPTY). إذا كنت بحاجة إلى قيمة افتراضية للمعلمة ، فيجب عليك تحديدها في القسم eMethTestبيان وظيفة التبديل CAddInNative :: GetParamDefValue.
نظرًا لأن طريقة "الاختبار" يمكنها إرجاع قيمة ، فأنت بحاجة إلى إجراء تغييرات على رمز الوظيفة HasRetVal:
bool CAddInNative :: HasRetVal (const long lMethodNum) (switch (lMethodNum) (case eMethLoadPicture: case eMethTest: return true ؛ افتراضي: return false ؛) إرجاع خطأ ؛)
وإضافة الكود القابل للتنفيذ للطريقة إلى الوظيفة CallAsFunc:
bool CAddInNative :: CallAsFunc (const long lMethodNum، tVariant * pvarRetValue، tVariant * paParams، const long lSizeArray) (... std :: wstring s1، s2؛ switch (lMethodNum) (case eMethLoadPicture: ... break: case إذا كانت (! lSizeArray ||! paParams) تُرجع خطأ ؛ s1 = (paParams) -> pwstrVal ؛ s2 = (paParams + 1) -> pwstrVal ؛ wstring_to_p (std :: wstring (s1 + s2) ، pvarRetValue) ؛ ret = true ؛ كسر؛) عودة ret؛)
لنقم بتجميع المكون وإحضار كود التكوين إلى النموذج:
فار ديموكومب. SystemStartup Procedure () ConnectExternalComponent ("..."، "DemoVK"، ExternalComponentType.Native) ؛ DemoComp = جديد ("AddIn.DemoVK.SomeName") ؛ lane = DemoComp.Test ("مرحبًا ،" ، "العالم!") ؛ يخطر (عبر) ؛ EndProcedure
بعد بدء التكوين ، سوف نتلقى رسالة: "مرحبًا ، أيها العالم!" ، والتي تشير إلى أن الطريقة قد نجحت.

الموقت

مهمة:
  1. دراسة تنفيذ الموقت في العرض التوضيحي VK
  2. تعديل طريقة "StartTimer" عن طريق إضافة القدرة على تمرير المعلمات فاصل المؤقت (بالمللي ثانية)
  3. تحقق من أن التغييرات التي تم إجراؤها تعمل.

في WinAPI ، للعمل مع الوقت ، يمكنك استخدام الرسالة WM_TIMER. سيتم إرسال هذه الرسالة إلى برنامجك في الفترة الزمنية التي تحددها عند إنشاء العداد.
لإنشاء مؤقت استخدم الوظيفة توقيت مجموعة:
UINT SetTimer (HWND hWnd، // window handle UINT nIDevent، // timer ID (number) UINT nElapse، // delay TIMERPROC lpTimerFunc) ؛ // مؤشر الوظيفة
سيرسل نظام التشغيل رسالة WM_TIMERإلى البرنامج مع الفاصل الزمني المحدد في الوسيطة nElapse(بالمللي ثانية). في المعلمة الأخيرة ، يمكنك تحديد وظيفة سيتم تنفيذها في كل مرة ينطلق فيها العداد. يجب أن يبدو رأس هذه الوظيفة كما يلي (يمكن أن يكون الاسم أي شيء):
باطل __stdcall TimerProc (HWND hwnd ، UINT uMsg ، UINT_PTR idEvent ، DWORD dwTime)
ضع في اعتبارك تنفيذ المؤقت في العرض التوضيحي VK.
نظرًا لأننا ندرس عملية تطوير مكون خارجي لعائلة نظام التشغيل Windows ، فلن نفكر في تنفيذ المؤقت في أخرى أنظمة التشغيل. بالنسبة لنظام التشغيل GNU / Linux ، على وجه الخصوص ، سيختلف التنفيذ في تركيب الوظيفة توقيت مجموعةو الموقت.
يتم استدعاء الطريقة في الكود القابل للتنفيذ توقيت مجموعة، التي يتم تمرير الوظيفة إليها MyTimerProc:
m_uiTimer = :: SetTimer (NULL، 0،100، (TIMERPROC) MyTimerProc) ؛
يتم وضع معرف المؤقت الذي تم إنشاؤه في متغير m_uiTimerحتى تتمكن من إيقاف تشغيله لاحقًا.
دور MyTimerProcكالآتي:
VOID CALLBACK MyTimerProc (HWND hwnd، // مقبض نافذة رسائل المؤقت UINT uMsg، // WM_TIMER message UINT idEvent، // timer identifier DWORD dwTime // وقت النظام الحالي) (إذا (! pAsyncEvent) يعود ؛ wchar_t * who = L "ComponentNative"، * what = L "Timer"؛ wchar_t * wstime = new wchar_t؛ if (wstime) (wmemset (wstime، 0، TIME_LEN)؛ :: _ ultow (dwTime، wstime، 10)؛ pAsyncEvent-> ExternalEvent (who ، what، wstime)؛ حذف wstime؛))
جوهر الوظيفة هو أن الطريقة تسمى حدث خارجي، والذي يرسل رسالة إلى 1C: نظام المؤسسة.
لتوسيع وظائف الطريقة StartTimerلنفعل ما يلي:
تعديل كود الطريقة GetNParamsبحيث يكون للطريقة eMethStartTimerتم إرجاع القيمة 1:
حالة eMethStartTimer: إرجاع 1 ؛
هذا هو رمز الطريقة CallAsProcللعرض:
حالة 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;
الآن دعنا نتحقق من الوظيفة. للقيام بذلك ، في الوحدة النمطية للتطبيق المُدار للتكوين ، سنكتب الكود:
فار ديموكومب. SystemStartup Procedure () ConnectExternalComponent ("..."، "DemoVK"، ExternalComponentType.Native) ؛ DemoComp = جديد ("AddIn.DemoVK.SomeName") ؛ DemoComp.StartTimer (2000) ؛ EndProcedure
بعد بدء التكوين ، سيتلقى البرنامج رسائل بفاصل زمني مدته ثانيتان ، مما يشير إلى التشغيل الصحيح للمؤقت.

التفاعل مع 1C: نظام المؤسسة

للتفاعل بين المكون الخارجي و 1 C: نظام المؤسسة ، طرق فئة IAddInDefBase الموضحة في الملف AddInDefBase.h. نحن ندرج الأكثر استخدامًا:
توليد رسائل الخطأ
منطقي ظاهري ADDIN_API AddError (رمز WCHAR_T * قصير بدون إشارة ، مصدر WCHAR_T * ، const WCHAR_T * descr ، سكود طويل)
wcode, الشفرة- رموز الخطأ (يمكن العثور على قائمة برموز الخطأ مع وصف على قرص ITS)
مصدر- مصدر الخطأ
ديسر- وصف خاطئ
إرسال رسالة إلى 1C: نظام المؤسسة
منطقي ظاهري ADDIN_API ExternalEvent (WCHAR_T * wszSource ، WCHAR_T * wszMessage ، WCHAR_T * wszData) = 0 ؛
المصدر- مصدر الرسالة
رسالة- رسالة نصية
wszData- البيانات المرسلة
يتم اعتراض الرسالة بواسطة الإجراء HandlingExternalEvent
تسجيل مكون خارجي في 1C: نظام المؤسسة
منطقي ظاهري ADDIN_API RegisterProfileAs (WCHAR_T * wszProfileName)
wszProfileName- اسم المكون.
هذه الطرق كافية للتفاعل الكامل بين VK و 1 C. لتلقي البيانات عن طريق مكون خارجي من 1C: نظام المؤسسة والعكس صحيح ، يرسل المكون الخارجي رسالة خاصة ، والتي بدورها ، يتم اعتراضها بواسطة نظام 1C ، وإذا لزم الأمر ، تستدعي طرق المكون الخارجي للإرسال عودة البيانات.

نوع البيانات المتغير

عند تبادل البيانات بين مكون خارجي و 1 C: نظام مؤسسي ، يتم استخدام نوع البيانات المتغير. يتم وصفه في ملف type.h ، والذي يمكن العثور عليه على قرص ITS:
Struct _tVariant (_ANONYMOUS_UNION union (int8_t i8Val؛ int16_t shortVal؛ int32_t lVal؛ int intVal؛ unsigned int uintVal؛ int64_t llVal؛ uint8_t ui8Val؛ uint16_t ushortVal؛ uint32_t ulVal؛ uint64؛ bVal؛ char chVal؛ wchar_t wchVal؛ DATE date؛ IID IDVal؛ Struct _tVariant * pvarVal؛ Struct tm tmVal؛ _ANONYMOUS_STRUCT Struct (void * pInterfaceVal؛ IID InterfaceID؛) __VARIANT_NAME_2 / * iface * /؛ __STRIANT_NAME_2 / * iface * /؛ _STRIAN / عدد البايتات) __VARIANT_NAME_3 / * str * / ؛ _ANONYMOUS_STRUCT هيكل (WCHAR_T * pwstrVal ؛ uint32_t wstrLen ؛ // عدد الرموز) __VARIANT_NAME_4 / * wstr * / ؛) __VARIANT_NAME_1 ؛ uint32_t مصفوفة عناصر واحدة ؛ // الأبعاد في pvarVal TYPEVAR vt ؛) ؛
نوع من t متغيرعبارة عن هيكل يتضمن:
  • خليط (اتحاد) مخصص مباشرة لتخزين البيانات
  • معرّف نوع البيانات
بشكل عام ، العمل مع متغيرات النوع t متغيريحدث وفقًا للخوارزمية التالية:
  1. تحديد نوع البيانات المخزنة حاليا في متغير
  2. الوصول إلى الحقل المقابل للخليط ، للوصول المباشر إلى البيانات
اكتب الاستخدام t متغيريبسط إلى حد كبير تفاعل 1C: نظام المؤسسة ومكون خارجي

طلب

يحتوي دليل "الأمثلة" على أمثلة لهذه المقالة
أمثلة / 1 - قم بتشغيل المكون التجريبي
أمثلة / 2 - عرض ملحق لقائمة الخصائص
أمثلة / 3 - عرض لتمديد قائمة الطريقة
يحتوي كل دليل على مشروع VS 2008 وتكوين 1C تم إنشاؤه مسبقًا.

غالبًا ما يواجه المبرمجون مشكلات في توصيل المكونات الخارجية (على سبيل المثال ، برامج تشغيل المعدات التجارية) عندما يعمل المستخدمون مع 1C من خلال الاتصال بالخادم من خلال الجهاز.

في الوقت نفسه ، يرى المستخدمون ، على سبيل المثال ، الصورة المعروضة في إعلان المقال.

أثناء العمل من أجهزة الكمبيوتر المحلية ، لا توجد مشاكل في توصيل المكونات الخارجية.

بماذا ترتبط؟ هذا لأنه عندما يعمل المستخدمون من خلال Terminal Server ، فإن لديهم حقوقًا أقل مما كانت عليه عندما يعملون على الكمبيوتر المحلي.

من السهل التحقق من ذلك إذا قمت بتسجيل الدخول إلى الخادم الطرفي تحت حساب له حقوق إدارية.

سبب هذا الاختلاف هو أن 1C لا يمكنه تسجيل مكون خارجي في السجل عندما يعمل المستخدم في الجهاز بموجب الحقوق العادية ، لأنه المستخدم العادي ليس لديه أذونات الكتابة إلى فرع تسجيل النظام HKEY_CLASSES_ROOT.

في المنشورات حول موضوع توصيل المكونات الخارجية في الجهاز ، يتم تقديم مجموعة متنوعة من الطرق لحل هذه المشكلة.

على سبيل المثال ، هذه:

1. قم بتشغيل 1C لأول مرة بموجب حقوق إدارية.

هذا الخيار لا يعمل دائمًا. سأشرح لماذا أدناه.

2. امنح المستخدمين العاديين للجهاز الحق في الكتابة إلى فرع تسجيل النظام HKEY_CLASSES_ROOT.

يجب على المستخدمين "المتقدمين" بشكل غير كافٍ عدم القيام بذلك ، وإلا فقد تكون هناك مشاكل.

3. باستخدام "أدوات ذكية" مختلفة ، قم بتسجيل VK نيابة عن مستخدم يتمتع بكامل الحقوق.

ليس من الجيد تناول الطعام أيضًا.

إذن ما هي أفضل طريقة للخروج من هذا الموقف؟

أقدم حل لهذه المشكلة. في رأيي - بسيطة وجميلة ، لم يتم عرضها مسبقًا في infostart.

عند التحقيق في هذه المشكلة ، تساءلت - لماذا تحاول 1C حتى تسجيل VK على طول مسار جديد؟ بعد كل شيء ، تم تسجيله بالفعل في النظام.

اتضح أنه في تكوينات 1C النموذجية (على سبيل المثال ، "إدارة التجارة") يتم استخدام البنية التالية لطريقة السياق العام ConnectExternalComponent () :

ConnectExternalComponent ("Reference.ConnectedEquipment.Layout.DriverATOLBarcodeScanner"، "ATOLScanner") ؛

كما ترى ، يتم توصيل برنامج تشغيل VK من تخطيط "DriverATOLScannerBarcode" الخاص بدليل "الأجهزة المتصلة".

ماذا سيحدث بعد ذلك؟

يحفظ 1C المكون في المجلد المؤقت للمستخدم ، على سبيل المثال "C: \ Documents and Settings \ User \ Local Settings \ Temp \ 1032 \ v8_4_12.tmp"

ويحاول تسجيله في فرع التسجيل HKEY_CLASSES_ROOT على طول هذا المسار.

في الجهاز الطرفي ، لا يملك المستخدمون العاديون حقوقًا لتغيير فرع التسجيل هذا ، وبالتالي فإن المكون غير متصل بهم.

الآن حول كيفية الخروج من هذا الموقف.

طريقة السياق العام ConnectExternalComponent () له العديد من خيارات بناء الجملة. هذا ما سنستخدمه.

لذلك ، خطوة بخطوة:

1. قم بتسجيل المكون الخارجي باستخدام الأداة المساعدة regsvr32.exe على الخادم الطرفي في المجلد C: \ WINDOWS \ SYSTEM32 لنظام التشغيل 32 بت أو في المجلد C: \ WINDOWS \ SYSWOW64 لنظام تشغيل 64 بت.

2. استخدم أحد خياري بناء الجملة الإضافيين لأسلوب ConnectExternalComponent ():

الخيار 1:

ConnectExternalComponent ("C: \ WINDOWS \ SysWOW64 \ Scaner1C.dll" ، "ATOLScanner" ، ExternalComponentType.COM) ؛

DriverObject = جديد ("AddIn.ATOLScanner.Scanner45") ؛

الخيار 2:

ProgID = "AddIn.Scanner45" ؛

توصيل المكون الخارجي (ProgID) ؛

DriverObject = جديد (ProgID) ،

في رأيي ، الخيار رقم 2 هو الأفضل.

في الوقت نفسه ، لا تحاول 1C إعادة تسجيل VC على طول مسار جديد في السجل ، وبالتالي ، يتم حل جميع المشكلات.

حسنا هذا كل شيء. حظا سعيدا في العمل!

على سبيل المثال ، لن يكون من الممكن إعادة كتابة أحد المكونات إذا لم تكن مؤلفه ولا توجد أكواد مصدر. أو إذا كانت أبسط الأنواع التي تدعمها تقنية Native API (رقم ، سلسلة ، منطقية ، تاريخ) غير كافية لتشغيلها.

لا توجد مشاكل خاصة عند العمل مع قاعدة الملفات. يتم استدعاء المهمة المجدولة في عملية الخلفية للمستخدم العادي. لذلك ، مكالمات العميل متاحة له. لا يوجد سياق العميل في قاعدة بيانات الخادم عند بدء مهمة مجدولة ، وبالتالي فإن المكالمة ConnectExternalComponent ()غير متوفر.

في هذه الحالة ، يمكنك استدعاء المكون على العميل. للقيام بذلك ، يكفي بدء جلسة 1C أخرى من المهمة المجدولة على الخادم حيث يتم تنفيذ الإجراءات اللازمة على العميل. حسنًا ، لا تنس إنهاء جلسة الجري لاحقًا.

لنفترض أنه في مهمتنا المجدولة ، نقوم بإنشاء وحفظ تقرير يستخدم مكون COM الخارجي NameDeclension.dll لرفض الاسم الكامل. في قاعدة الملف ، ستعمل مثل هذه المهمة المجدولة بشكل صحيح ، لكنها لن تعمل على مكون الخادم.

لإصلاح المشكلة ، دعنا نضيف إجراءً إلى وحدة المهام المجدولة التي ستبدأ جلسة أخرى في وضع الخادم وفيها ستنفذ مكالمة إنشاء تقرير على العميل من المعالجة الخارجية.

#If Client ثم الإجراء ExecuteFormationAndSavingReport () تصدير إذا ConnectExternalComponent ("CommonLayout.NAMEDECL"، "Cl"، ExternalComponentType.COM) ثم المكون = جديد ("AddIn.Cl.NameDeclension") ؛ // هنا هو رمز إنشاء وحفظ التقرير ElseJoinLogRecord ("RegTask"، LogLogLevel.Error، "فشل توصيل المكون الخارجي على العميل")؛ إنهاء إذا؛ نهاية الإجراء #Otherwise إجراء ExecuteFormationAndSavingReport () تصدير ExecuteOperationOnClient ("RegularTasks.ExecuteFormationAndSavingReport ()")؛ إجراء EndProcedure PerformOperationOnClient (ParameterToExecute) ExportUserName = ""؛ UserPassword = "" ؛ PathToExternalProcessing = "c: /temp/Autostart.epf"؛ اقتباس = "" "" ؛ DirectoryBIN = DirectoryProgram () ، PathToConfiguration = InfoBase ConnectionString () ، ConfigurationPath = StrReplace (ConfigurationPath، Quote، Quote + Quote) ؛ StartString = اقتباس + دليل سلة + "1cv8.exe" + اقتباس + "ENTERPRISE" + "/ IBConnectionString" + اقتباس + مسار التكوين + اقتباس + "/ N" + اقتباس + اسم مستخدم + اقتباس + "/ P" + اقتباس + كلمة مرور المستخدم + اقتباس + "/ تنفيذ" + اقتباس + PathToExternalProcessing + اقتباس + "/ C" + اقتباس + ParameterToExecute + اقتباس ؛ StartApplication (StartString) ؛ EndProcedure #EndIf

رمز المعالجة الخارجية الذي يتسبب ببساطة في قيام سياق العميل بطباعة التقرير المطلوب من وحدة المهام المجدولة وإنهاء الجلسة بعد إنشاء التقرير.

محاولة التنفيذ (StartupParameter) ؛ EndTry استثناء ؛ ShutdownSystem (خطأ) ؛

تكمن الراحة في الحل في أنه عند إعداد المهام المجدولة ، لا يهم الوضع الذي سيتم تشغيل المهمة فيه. إذا كانت قاعدة البيانات عبارة عن ملف واحد ، فسيبدأ الإجراء اللازم على الفور. إذا كانت قاعدة البيانات من جانب الخادم ولم يكن هناك سياق عميل عند بدء التشغيل ، فسيتم حينها تهيئة جلسة جديدة وسيعمل الإجراء بشكل صحيح في سياق العميل.

رمز لتطبيق نموذجي. من الناحية النظرية ، ستعمل بطريقة مشابهة تمامًا في طريقة مُدارة.

ملاحظة.أيضًا ، يمكن استخدام هذا النهج لتنفيذ أي إجراءات للعميل في الوظائف المجدولة.

الجرس

هناك من قرأ هذا الخبر قبلك.
اشترك للحصول على أحدث المقالات.
البريد الإلكتروني
اسم
اسم العائلة
كيف تحب أن تقرأ الجرس
لا بريد مزعج