Три кити роботи з COM-об'єктами. Працювати через COM-з'єднання простіше, ніж ви вважаєте

)Все вірно

Водночас я бачив не раз, коли просто "злітали" публікації, які не тягнули навіть на 10 балів.
Чому так сталося? Мабуть тому, що комусь вони явно припали до душі.


Я про це і кажу, що було б непогано не читаючи статтю з рейтингу зрозуміти наскільки вона тобі потрібна, або оцінити її не так просто +/-. Щодо припала до душі я б скоригував так: вона так багато набрала через те, що так зірки склалися і на сайті зібралося багато народу і багатьом сподобалося, самі розумієте цю справу випадку. як тільки стаття йде з головної сторінки, то її вже можна знайти тільки за запитом, а так голосують всі, хто проходить. І підтримувати на головній, наскільки я розумію, дозволяють постійні коментарі = розкрутка статті.
Саме для цього і ставлять магазини на прохідних вулицях - адже часто важлива не якість та актуальність товару, а прохідність місця, люди гуляючи часто купують те, що викинуть наступного дня, просто заради процесу. Це давно всім відома хвороба – шопоманія. Або просто збільшення потоку збільшує ймовірність потрібного покупця.

А плюси та мінуси... - це всього лише якийсь "дякую" за витрачений час і працю


Тобто. мінус теж вважається за "дякую"? Я ось і хотів дізнатися ваше ставлення до того, чи потрібно ставити в таких випадках його, і як цікаво вважають інші? Чи ставити його колись стаття шкідлива/погана або коли вона тобі просто марна/порожня.
На мій погляд стаття схожа на просто підвищення рейтингу, тому що:
1. Наведені мною проблема з типами взагалі проігнорована автором, хоча він не полінувався написати купу коментів.
2. У статті явна неточність: сказано, що можна тільки так

V82 = Новий COMоб'єкт("V82.ComConnector"); Код = КонтрагентСОМ.Code;


а ось я спокійно роблю за допомогою обробки ось так:

Повідомити(База.Довідники.Контрагенти.ЗнайтиЗа найменуванням("ТОВ").Код);


і все нормально! А підключення вибираю V82.ComConnector
Дивно якось, що авторові зовсім начхати на те, що його стаття містить такі проблеми на які вказали, а він не реагує ніяк.
3. Адже є ще проблема коли вискакує помилка "Клас не існує"
4. А є проблема коли встановлена ​​8.2, а потім встановлена ​​8.1 - спробуйте обмінятися по ОЛЕ/COM типовим обміном УТ-БП!
5. Могли б вказати основні обробки на сайті, які дозволяють універсально підключатися по ОЛЕ/COM, щоб новачки не витрачали часу, ви ж для них пишіть! Та ж до речі її картинка чомусь у вас красується, з чого б? А в результаті 2 слова по суті та ще 6 за кадром.

Загалом, я не поливаю брудом, а вказую на конкретні прогалини, але реакції нуль. Якщо це той досвід, яким ви ділитеся, то він якийсь помилковий і неповний.
Я до того що якби автор мав бажання зібрати всі глюки, то він би міг хоча б прислухатися до чужого досвіду, а не огризатися на коментарі. Тут же складається ситуація, коли той хто прочитав її знають більше ніж автор, кажуть йому (іноді й некоректно), а він ще й відбивається. У результаті вся інформація не у статті, а у коментах! Смішно! Так часто буває, але не потрібно при цьому наголошувати на тому, що хотіли як краще - я ж показую як краще, і інші показують! Включіть це в статтю і вона буде варта, не всім цікаво читати цю перепалку.

Один із варіантів обміну даними між базами 1С це обмін через COM з'єднання.

За допомогою COM з'єднання можна з однієї бази 1С підключитися до іншої та прочитати або записати дані. Користуватися цим методом можна як клієнт-серверних варіантах баз, і у файлових базах. У цій статті розберемо приклади такого роду сполук. У прикладах використовується платформа 8.2.

Можна створити два види COM об'єктів для 1С. Це V82.Applicationі V82.COMConnector. У випадку з V82.Applicationзапускається практично повноцінний екземпляр додатка 1С. у разі використання V82.COMConnectorзапускається невелика серверна частина.
Швидкість роботи в цьому випадку вища, але деякі функції можуть бути недоступними. Зокрема робота з формами та із загальними модулями для яких не встановлено властивість роботи із зовнішніми з'єднаннями. Переважно треба використовувати V82.COMConnectorі лише у разі нестачі функціоналу V82.Application. Особливо дуже різниця у швидкості роботи може бути помітна на базах великого обсягу.

Отже, приступимо

  1. Створимо COM об'єкт
    • для V82.ApplicationЗ'єднання = Новий COMОб'єкт ("V82.Application");
    • для V82.COMConnectorЗ'єднання = Новий COMОб'єкт ("V82.COMConnector");
  2. Сформуємо рядок підключення
    • для серверного варіанта бази РядокСполуки = "Srvr = " "Ім'яСервера" ";Ref = " "Ім'яБази" ;
    • для файлового варіанта бази РядокСполуки = "File = " "; Usr = Ім'я Користувача; Pwd = Пароль";
  3. Виконуємо підключення до базиСпроба Підключення = З'єднання. Connect(Рядок З'єднання) ;
  4. Виняток Повідомлення = Новий Повідомлення Користувачеві;Повідомлення. Текст = + ОписПомилки() ;

    Повідомлення. Повідомити() ; V82.ApplicationКінецьСпроби; V82.COMConnectorРозриваємо з'єднання з базою

    З'єднання = Невизначено;

Для об'єкту

виконувати розрив з'єднання обов'язково, інакше залишиться висіти незавершений сеанс, який потім доведеться видаляти вручну. У випадку з з'єднання розривається автоматично при завершенні процедури, в якій виконувалося підключення. І є ще один маленький момент.Для користувача під яким виконується підключення повинен бути вимкнений прапорець «Запитувати підтвердження під час закриття програми» у його налаштуваннях. А тепер зберемо весь код у купуЗ'єднання = Новий COMОб'єкт ("V82.Application"); //Сполука = Новий COMОб'єкт("V82.COMConnector");РядокСполуки = "Srvr = " "Server1C" ";Ref = " "MyBase" "; Usr = Петя; Pwd = 123" ;

//РядокСполуки = "File = ""С:\MyBase""; Usr = Петя; Pwd = 123"; V82.ApplicationСпроба Підключення = З'єднання. Connect(Рядок З'єднання) ; V82.COMConnectorВиняток Повідомлення = Новий Повідомлення Користувачеві;

Повідомлення. Текст = "Не вдалося підключитися до бази" V82.COMConnector + ОписПомилки() ; "Не вдалося підключитися до бази" V82.Application Повідомлення. Повідомити() ; КінецьСпроби; З'єднання = Невизначено;Для виду підключення метод застосовується для COM об'єкта, який створювався спочатку, а дляметод застосовується до підключення. далі робота із запитом йде стандартними засобами 1С. у коді це виглядає так:

Запит = Підключення. NewObject("Запит"); // дляЗапит = З'єднання. NewObject("Запит"); Запит. Текст = "ВИБРАТИ.

| Посади Організацій.Код,

| Посади Організацій. Найменування

| Довідник.Посади Організацій ЯК Посади Організацій" ; і com з'єднання V83.COMConnector . У випадку з ;запускається практично повноцінний екземпляр додатка 1С. У разі використання V83.COMConnectorзапускається невелика серверна частина. Швидкість роботи в цьому випадку вища, але деякі функції можуть бути недоступними. Зокрема робота з формами та із загальними модулями для яких не встановлено властивість роботи із зовнішніми з'єднаннями. Переважно треба використовувати V83.COMConnectorі лише у разі нестачі функціоналу ;. Особливо дуже різниця у швидкості роботи може бути помітна на базах великого обсягу. Для платформи 8.2 використовується V82.Application або V82.COMConnector

Встановити з'єднання OLE

З'єднання = Новий COMОб'єкт ( "V83.Application");

Встановити COM з'єднання

З'єднання = Новий COMОб'єкт (“V83.COMConnector”);

Рядок підключення

//Для варіанту клієнт-сервер
РядокЗ'єднання= "Srvr = ""Ім'яСервера" ";Ref = ""Ім'яБази";
//Для варіанта файлового режиму:
РядокЗ'єднання= “File = “ “ШляхКБазі” “; Usr = Ім'я Користувача; Pwd = Пароль”;
Спроба
Підключення = З'єднання . Connect(Рядок З'єднання) ;
Виняток
Повідомлення = Новий ПовідомленняКористувачеві;
Повідомлення . Текст = "Не вдалося підключитися до бази" + ОписПомилки(); Повідомлення;
. Повідомити()

КінецьСпроби;

Розрив з'єднання
З'єднання = Невизначено; ;КінецьСпроби; V83.COMConnectorДля об'єкту

з'єднання розривається автоматично при завершенні процедури, в якій виконувалося підключення. І є ще один маленький момент. Для користувача під яким виконується підключення повинен бути вимкнений прапорець «Запитувати підтвердження під час закриття програми» у його налаштуваннях.

Метод NewObject()

для V83.COMConnector

Для створення нового об'єкта можна скористатися методом NewObject(), наприклад: Запит COM = Підключення. NewObject() ;
"Запит" Запит COM Таблиця COM) ;
"ТаблицяЗначень"

Масив COM = Підключення. NewObject("Масив");

УїдCOM = Підключення. NewObject ;

для ЗапитOLE = З'єднання. NewObject(“) ;
Запит “(Таблиця COM) ;
Таблиця OLE = З'єднання. NewObjectМасив OLE = З'єднання. NewObject
("Масив");УїдCOM = З'єднання. NewObject

(“Унікальний Ідентифікатор”,РядокУІД); Запит COM. Текст =
КінецьСпроби;
З'єднання = Невизначено;
“ВИБРАТИ
| Довідник.Посади Організацій;

ЯК Посади Організацій” Результат = Запит COM.
Виконати (); Вибірка = Результат.
Вибрати ();Поки що Вибірка. Наступний()
Цикл
Кінець циклу;
Також можна використовувати менеджери об'єктів конфігурації:
Довідник COM = Підключення. Довідники. Ім'я Довідника; ДокументCOM
= Підключення. документи. Ім'я Документу; Реєстр COM = Підключення.РеєстриВідомостей

. Ім'яРегістра;

Для порівняння значень елементів перерахувань, визначених конфігурації, необхідно здійснити перетворення цих елементів до одного з примітивних типів, порівняння яких не викликає труднощів. Такими типами можуть бути чисельний, або рядковий тип. Перетворити значення елемента перерахування до числового типу можна так

ЕлементПерерахування = Підключення.Довідники.Довідник1.ЗнайтиПоКоду(1).Реквізит1;

МожливіЗначення = ЕлементПерерахування.Метадані().ЗначенняПерерахування;

НомерЕлементиПерерахування = МожливіЗначення.Індекс(МожливіЗначення.Знайти(З'єднання.XMLString(ЕлементПерерахування)));

Якщо НомерЕлементаПерерахування = 0 Тоді Повідомити( “ЗначенняПеречисления1”);

ІнакшеЯкщо НомерЕлементаПерерахування = 1 ТодіПовідомити (“Значення Перерахування2”);

КінецьЯкщо;

Отримання об'єкта через COM за ідентифікатором

Через менеджери об'єктів конфігурації отримуємо com об'єкт, наприклад:
ДокументCOM = З'єднання. документи. Ім'я Документу;

Потім отримуємо рядок унікального ідентифікатора:

РядокУІД =З'єднання.string ( ДокументCOM.УнікальнийІдентифікатор())

Ідентифікатор = Новий У нікальнийІдентифікатор(РядокУІД);
З посиланняПоІдентифікатору = Документи[Ім'яДокументу].ОтриматиПосилання(Ідентифікатор);

Якщо потрібно знайти com об'єкт за документом по ідентифікатору, то тоді потрібно написати так:

УїдCOM = З'єднання.(“Унікальний Ідентифікатор”, Рядок УІД);
ПосиланняПоІдентифікатору = З'єднання.Документи[Ім'яДокумента].ОтриматиПосилання(УїдCOM);

Привіт хабравчанам!

У цій статті я хочу розповісти про те, як налагоджено інтеграцію з платформою 1С у моїй організації. Я спонукав мене зробити практично повну відсутність технічної інформації на цю тему. Читаючи різні статті та доповіді на тему зв'язки 1С з будь-якою інформаційною системою, щоразу переконуєшся, що всі вони носять маркетинговий, демонстраційний характер, і ніколи – технічний, що відображає проблему та суть її вирішення.

Попереджаю, що спосіб у жодному разі не претендує на універсальність. Оскільки самих конфігурацій 1С існує чимало, а інформаційних систем, мов і платформ - ще більше, кількість можливих комбінацій величезна. Моя мета – продемонструвати одне з можливих рішень.


Як мову, яка інтегруватиметься з 1С, я вибрав Пітон. Він дуже добре підходить для автоматизації процесів. Цьому сприяють мінімалістичність синтаксису (код набирається дуже швидко), багата стандартна бібліотека (менша потреба у сторонніх модулях), кросплатформність - з великою ймовірністю, код, написаний в ОС Linix, успішно запрацює у Windows.

Для початку окреслюю дані, з якими працюватимемо. Організація - енергозбутова компанія у далекосхідному регіоні - обслуговує приблизно 400 тис. абонентів, база 1С самописної конфігурації. Для кожного абонента зберігаються його платежі, нарахування, послуги та схеми розрахунку, прилади обліку, показання та безліч інших даних.

Колись в організації стояла програма, написана на Дельфі, яка використовувала як БД MSSQL/Firebird. У ті славні часи можна було підключитися до бази за допомогою будь-якої мови і зробити безліч дій - вибрати абонентів-боржників, рознести оплати, що надійшли, зафіксувати показання приладів. Не дивно, що колекція скриптів, що автоматизують рутину, постійно зростала. Програмісти могли виконувати будь-які дії, не відкриваючи саму програму.

На жаль, із переходом на 1С халява скінчилася - не стало можливості з'єднуватися з базою безпосередньо. Взагалі, платформа 1С сама собою неподільна і погано йде на інтеграцію з іншими системами. Вона, як кажуть, річ у собі. Завантажуючи дані в 1С, слід пам'ятати, що витягти їх звідти буде непросто. Але через те, що організації потрібно впроваджувати платіжні системи та індивідуальний кабінет, необхідно було знайти якесь рішення.

Основні завдання, що стояли переді мною - це можливість швидкого отримання даних по конкретному особовому рахунку - ПІБ, адреса, прилади обліку, показання приладів, платежі, нарахування. Плюс формування документів – акта звірки, платіжної квитанції. Отже, можливість прямого з'єднання з БД відсутня - кожен, хто переглядав базу 1С SQL-сервері, бачив, що у масі таблиць виду aaa1, aaa2 розібратися важко. А будувати запити з такими назвами таблиць і полів просто неможливо. До того ж, багато таблиць 1С (особливо найважливіші, на кшталт зрізу останніх, залишків та оборотів) є віртуальними і розкидані за різними фізичними таблицями, збираючись множинними джоїнами. Це спосіб не підходить.

Платфома 1С надає можливість з'єднуватись з нею через COM-з'єднання. Подібно до багатьох windows-програм, під час установки 1С в системі реєструються два COM-об'єкти - Automation Server і COM Connector. З обома об'єктами можна працювати, використовуючи мову, в якій передбачено підтримку COM-технології.

Об'єкт Automation Server - це додаток 1С, що майже нічим не відрізняється від звичайної клієнтської програми. Різниця в тому, що додатково з'являється можливість програмного керування екземпляром програми. При роботі з об'єктом COM Connector запускається полегшений варіант 1С-додатка, в якому недоступні форми, а також функції та методи, що стосуються інтерфейсу та візуальних ефектів. Сама програма запускається в режимі «Зовнішнє з'єднання». Ініціалізація глобальних змінних (наприклад, визначення поточного користувача та його налаштувань) повинна виконуватись у модулі зовнішнього з'єднання 1С. Якщо в режимі зовнішнього з'єднання в коді буде викликана функція, не доступна в цьому режимі, то буде викликано виняток (який буде передано в наш пітон-скрипт). Виклик небезпечних функцій слід обрамляти конструкціями виду

#Якщо НЕ ЗовнішнєЗ'єднання Тоді Попередження("Привіт!"); #КінецьЯкщо

Оскільки робота з COM-об'єктами - технологія виключно windows-only, то не дивно, що у стандартному постачанні Пітона вона відсутня. Потрібно встановити розширення - набір модулів, що надають весь необхідний функціонал для програмування під Windows на Пітоні. Його можна завантажити у вигляді вже зібраного exe-установника. Саме розширення надає доступ до реєстру, служб, ODBC, COM-об'єктів тощо. Як альтернатива можна відразу поставити дистрибутив ActiveState Python, в якому розширення Win32 поставляється з коробки.

Деякий час я експериментував із COM-з'єднанням у розробці веб-додатків, зокрема особистого кабінету. Були виявлені такі мінуси:

COM-з'єднання працює повільно. Низька продуктивність – відомий мінус COM-технології.
- Процес встановлення з'єднання з 1С залежно від конфігурації може тривати від 1 до 8 секунд (у моєму випадку – 6 секунд). Чи варто говорити, що встановлення з'єднання на кожен запит призведе до того, кожна сторінка буде завантажуватися 8 секунд.
- Оскільки веб-програми на пітоні працюють як самостійні сервери, то попередній пункт можна компенсувати зберіганням з'єднання в деякій глобальній змінній і у разі помилки відновлювати його. Як підтримувати з'єднання на PHP, я, щиро кажучи, ще не думав.
- Втрачається кросплатформність веб-додатку.

Виходячи з перерахованих вище пунктів, було вирішено змінити принцип взаємодії, розділивши його на 2 частини - першу платформозалежну (виндову), що вивантажує дані 1С в будь-який зручний формат, і другу, не залежну від платформи, здатну працювати з даними, нічого не підозрюючи про 1С у принципі.

Стратегія дій полягає в наступному: пітон-скрипт з'єднується з 1С, виконує необхідні запити та вивантажує дані в SQLite базу. До цієї бази можна підключитися з Пітона, PHP, Джави. Більшість наших проектів працює на пітоні, і так як я не виношу писати сирі SQL-запити руками, вся робота з базою SQLite виконується через ORM SQLAlchemy. Потрібно було лише описати структуру даних бази в декларативному стилі:

З sqlalchemy.ext.declarative import declarative_base з sqlalchemy import Column, Integer, Numeric, DateTime, Unicode, Boolean, LargeBinary, ForeignKey Base = declarative_base() class Abonent(Base): __tablename__ = "abonents" = True) account = Column(Unicode(32), index=True) code = Column(Unicode(32)) address = Column(Unicode(512)) fio = Column(Unicode(256)) source = Column(Unicode(16) ) psu = Column(Unicode(256)) tso = Column(Unicode(256)) np = Column(Unicode(256)) street = Column(Unicode(256)) house = Column(Integer) flat = Column(Integer) mro = Column(Unicode(256)) class Payment(Base): __tablename__ = "payments" # і так далі...

Тепер достатньо імпортувати цей модуль у будь-який пітон-проект, і можна працювати з даними.

Передбачаю ваше запитання – «а чому SQLite»? Головна причина – база потрібна лише для читання, тому проблеми із записом у SQLite нас хвилювати не повинні. По-друге, формат цієї СУБД зручний - її зручніше переглядати (існуємо безліч безкоштовних утиліт, у тому числі супер-розширення для FireFox). По-третє, в деяких випадках потрібно отримати доступ до абонентів з тих машин, на яких немає з'єднання з MySQL-сервером. У такому разі достатньо скопіювати файл SQLite-бази, і на цій машині буде доступ до всієї інформації.

Вивантаження відбувається щодня вночі. Занесення даних до 1С можна автоматизувати так само. Наприклад, потрібно фіксувати свідчення, надані абонентами на сайті особистого кабінету. У цьому випадку знову з'єднуємося з 1С та програмним методом створюємо та проводимо документ «Акт зняття показань». Код я наведу трохи нижче.

Робота з COM-об'єктами в Пітон трохи незвична. По-перше, втрачається «пітонічність» коду - правила іменування змінних і функцій в 1С, м'яко кажучи, не відповідають Дзену Пітона. По-друге, всім відомо, що об'єкти 1С найчастіше іменуються кириличними символами, що викликає проблеми при розробці на Пітоні... але вони можна вирішити. Пропоную ознайомитись з кодом:

Import pythoncom import win32com.client V82_CONN_STRING = "Srvr=v8_server;Ref=v8_db;Usr=username;Pwd=megapass;" pythoncom.CoInitialize() V82 = win32com.client.Dispatch("V82.COMConnector").Connect(V82_CONN_STRING)

Як видно з коду, клієнт ініціалізується для роботи з 1С. Визначення COM-об'єкта відбувається під назвою «V82.COMConnector». Зверніть увагу, що ця назва справедлива для платформи V8.2, якщо у вас версія 8.1, то ім'я буде V81.COMConnector.

У ініціалізованого клієнта ми викликаємо метод Сonnect(), передаючи рядок підключення. Рядок складається з імені сервера, бази, користувача та пароля. Отриманий об'єкт V82 зберігає з'єднання з додатком 1С. У нього немає методу Disconnect() або чогось такого роду. Щоб вимкнути базу, достатньо видалити об'єкт з пам'яті функцією del() або присвоїти змінної None.

Маючи об'єкт, можна звертатися до будь-яких полів та методів глобального контексту 1С, оперувати універсальними об'єктами типу ТабличнийДокумент, ТаблицяЗначень та ін. Важливо врахувати, що під час роботи через COM-з'єднання 1С працює у режимі «Зовнішнє з'єднання». У ньому недоступні будь-які функції для інтерактивної роботи, наприклад, спливаючі діалоги, сповіщення та, що найголовніше, форми. Впевнений, що ви не раз проклянете розробників конфігурації, які містять найважливіший функціонал у процедурі Кнопка1Натискання() в модулі форми документа.

Давайте поговоримо про таку важливу річ, як кирилицькі атрибути. Не дивлячись те що, що 1С - двомовне середовище й у кожного російського методу є англомовний аналог, рано чи пізно потрібно звернутися до кириличному атрибуту. Якщо на мовах PHP або VBSCript це не викликає жодних проблем,

Set Con = CreateObject("v81.COMConnector") Set v8 =Con.Connect("рядокПідключення") Set РахункиМенеджер = v8.Документи.Рахунки.... Set РахункиЗапис= РахункиМенеджер. .... РахункиЗапис.Записати()

То код на пітон просто вилетить з помилкою Syntax Error. Що ж робити? Правити конфігурацію? Ні, достатньо скористатися методами getattr та setattr. Передаючи в ці функції COM-об'єкт та кириличне ім'я аттрибута, можна відповідно отримувати та встановлювати значення:

#coding=cp1251 catalog = getattr(V82.Catalogs, "Особисті Рахунки")

Важливо таке: імена реквізитів, а також параметри функцій та методів повинні передаватися в кодуванні CP1251. Тому, щоб заздалегідь уникнути путіниці з кодуванням, є сенс оголосити її на початку файлу: #coding=cp1251. Після цього можна передавати рядки, не хвилюючись про їхнє кодування. Але! Усі рядки, отримані з 1С (результати виклику функцій, запитів), будуть кодовані UTF-8.

Приклад коду, який виконує в середовищі 1С запит, перебирає результат і зберігає в базі SQLite:

#coding=cp1251 q = """ ВИБРАТИ ЛицьовіРахунки.Код ЯК code, ЛицьовіРахунки.Будова.НаселенийПункт.Найменування + ", " + ЛицьовіРахунки.КороткийАдрес ЯК address, ЛицьовіРахункиКонфіденційна назва , ВИРАЗИТИ(ХарактеристикиЛицевіРахункиЗрезОстанніх.Значення ЯК Довідник.ТериторіальноМережевіОрганізації).Найменування ЯК tso, ЛицьовіРахунки.Будова.НаселенийПункт.Найменування ЯК np,ЛицевіРахунки.Струкування. Будинок ЯК house, ЛицьовіРахунки.ОсновнеПриміщення.НомерПриміщення ЯК flat , ЛицьовіРахунки.Дивізіон.Батьківщина.Найменування ЯК mro З Довідник.ЛицевіРахунки ЯК ЛицьовіРахунки ЛІВОЕ З'ЄДНАННЯ РеєстрЗведень.ХарактеристикиЛицевіРахунки. етеваОрганізація)) ЯК ХарактеристикиОсобисті РахункиЗріз Останніх ПЗ Особові Рахунки. = V82.NewObject("Query", q) selection = query.Execute().Choose() CONN = db.connect() CONN.query(models.Abonent).delete() while selection.Next(): abonent = models.Abonent() abonent.account = selection.code.strip() abonent.code = selection.code abonent.fio = selection.fio abonent.address = selection.address abonent.psu = selection.psu abonent.tso = selection. tso abonent.source = u"ASRN" abonent.np = selection.np abonent.street = selection.street abonent.house = selection.house abonent.flat = selection.flat abonent.mro = selection.mro CONN.add(abonent) CONN.commit()

Тут CONN - це сесія з'єднання із SQLite-базою. Створюється об'єкт запиту query, заповнюється його текст. Як було помічено вище, текст запиту повинен бути в CP1251, для чого спочатку оголошено кодування. Після виконання запиту в базі видаляються всі абоненти, щоб не додати дублі, потім додаються в циклі і слідує фінальний коміт.

Працюючи із запитами я виявив такі правила.

Вибираючи поля, призначайте їм назви латиницею, набагато зручніше звертатися до них через селектор (точку), замість getattr().
- Вибирайте тільки типи даних: рядки, числа, дату і булеве. Ніколи не вибирайте посилання на об'єкт (документ, довідник)! У цьому контексті посилання вам абсолютно не потрібні і навіть шкідливі, тому що будь-яке звернення до реквізиту чи методу посилання призведе до запиту через COM-з'єднання. Якщо звертатися до атрибутів посилання у циклі, це буде вкрай повільно.
- Якщо ви вибираєте поле типу Дата, воно буде повернено як об'єкт PyTime. Це спеціальний тип даних передачі дати-часу в COM-з'єднанні. З ним не так зручно працювати, як зі звичним часом. Якщо передати цей об'єкт в int(), то повернеться timestamp, з якого потім можна отримати datetime методом fromtimestamp().

Наразі розглянемо, як формуються друковані документи. Справа в тому, що споживачеві потрібно надавати можливість завантажувати заздалегідь підготовлені документи, наприклад платіжну квитанцію або акт звірки. Ці документи формуються в 1С відповідно до встановлених вимог, їх реалізація на Пітоні займе багато часу. Тому краще згенерувати документи в 1С і зберігати їх у форматі Excel.

Так, документ акта звіряння генерується спеціальною зовнішньою обробкою. Для тих, хто не знайомий із термінологією 1С: обробка - це автономна програма, що має свій модуль, форми, шаблони, призначена для запуску в середовищі 1С. Необхідно ініціалізувати обробку, заповнити її реквізити та викликати функцію, яка поверне нам табличний документ, призначений для перегляду в 1С. Цей документ потрібно зберегти у форматі Excel і скопіювати на сервер або записати в базу.

Link = getattr(V82.Catalogs, "ЗвітиСистеми").FindByDescription("Акт Звірки Елен") nav_url = V82.GetURL(link, "Звіт") name = V82. (name) setattr(ExternalReport, "Лицевий Рахунок", reference) table_doc = ExternalReport.GetDoc() path = V82.GetTempFileName("xls") table_doc.Write(path, V82 .SpreadsheetDocumentFileType.XLS) report = models. .account = reference.Code.strip() report.type = u"act" report.document = open(path, "rb").read() CONN.add(report)

У наведеному фрагменті виконується таке. Підключається обробка, яка формує документ. Обробка може бути вбудована в конфігурацію, зберігатися на диску або базі даних 1С (у якомусь довіднику). Оскільки обробки часто змінюються, то щоб кожен раз не оновлювати конфігурацію, найчастіше змінюються обробки зберігаються в довіднику «ЗвітиСистеми», в реквізиті типу «сховище значення» з ім'ям Звіт. Обробку можна ініціалізувати, вивантаживши її з бази на диск і підвантаживши, або методом GetURL(), який потрібно передати посилання на елемент довідника та ім'я реквізиту. Отриманому об'єкту обробки ми призначаємо значення реквізитів, викликаємо функцію GetDoc(), що експортується, отримуємо табличний документ, який зберігається в тимчасовий Excel-файл. Вміст цього файлу записується в базу SQlite.

Останнє, що залишається розглянути – це програмне занесення даних до 1С. Припустимо, що потрібно занести свідчення від абонентів. Для цього достатньо створити та провести документ «Акт зняття показань»:

#coding=cp1251 acts = getattr(V82.Documents, "АктЗняття Показів") act = acts.CreateDocument() setattr(act, "Показання", 1024.23) setattr(act, "Абонент", "Іванов") # Заповн. .. act.Write()
Тепер занесення даних є автоматизованим.

Отже, я виклав спосіб, який ґрунтується на програмному вивантаженні та завантаженні даних з використанням COM-з'єднання. Цей метод успішно функціонує у моїй організації майже рік. База, що формується з 1С, обслуговує 3 платіжні системи, інтернет-еквайринг (оплата картками через інтернет), а також особистий кабінет. Крім цього, до бази підключаються різні скрипти для автоматизації рутини.

Незважаючи на недоліки методу (повільна швидкість COM-з'єднання), загалом він функціонує стабільно. У нас є дані в платформонезалежному вигляді (SQLite), з якими можна працювати з будь-якої мови. І основна частина коду написана на Пітоні, а отже, доступні безліч засобів та прийомів, про які навіть не можна мріяти у 1С.

Це один із можливих способів взаємодії з 1С. Я впевнений, що він не новий і, напевно, вже був кимось випробуваний, оптимізований. Однак, я постарався викласти максимум деталей процесу, щоб уберегти вас від підводного каміння, на яке сам наступав.

Бажаю всім удачі, і пам'ятайте, що не такий страшний 1С, як його малюють!

Для взаємообміну інформацією між двома інформаційними базами без сторонніх вивантажень і файлів обміну немає нічого кращого за COM-з'єднання. І з цим важко посперечатися, тому що використовувати цей вид з'єднання достатньо просто і стабільно. Але в і в даному механізмі є одне вузьке і неприємне місце. Йдеться про час встановлення з'єднання з іншою базою. Воно може деяких випадках досягати досить великих значень, тобто. бути дуже довгим.

У чому ж справа?

У момент з'єднання COM-з'єднання, база, що підключається, повністю підвантажує конфігурацію бази, до якої ми підключаємося. Спробувавши, наприклад, підключиться до бази "Бухгалтерія підприємства", нати очікування тривали досить довго, оскільки обсяг конфігурації обчислюється сотнями мегабайт. Стає зрозумілим, що для швидкої роботи всі з'єднання необхідно кешувати та підтримувати.

Аналіз продуктивності

Поставимо питання, а чи потрібно взагалі кешувати з'єднання і чи принесе це свої плоди при інтенсивній роботі користувача з COM-з'єднанням. Виконаємо вимірювання часу підключення до конфігурації об'ємом 20 кБайт.

Ми бачимо, що підключення до невеликої бази зайняло 3,5 секунди. При підключенні до більшої бази час збільшиться в кілька разів.

При зберіганні з'єднання, що підтримується, ці дії займуть на кілька порядків менше часу.

Як нам зберегти активне наше COM-з'єднання?

Проблема в тому, що платформа 1С не надає стандартних засобів для поранення COM-з'єднань в ІБ. У довідниках та документах зберігати з'єднання безглуздо, оскільки воно часто може змінюватися. Найбільш перспективним варіантом виглядає зберігання з'єднання параметрі сеансу. Але й тут все не так гладко. Адже для зберігання COM-з'єднання немає жодного відповідного типу даних.

Дані міркування призводять до того, що зберігання можливе лише на клієнті в будь-якій змінній. Розглянемо варіант для керованої форми. Необхідно ініціалізувати у формі змінну з директивою &Клієнта, куди ми і будемо зберігати значення підключення. Відповідно викликати це підключення можна також на клієнті, оскільки передати COM об'єкт із клієнта на сервер ви зможете. Для звичайних форм немає поділу на сервер та клієнт і цей механізм стає навіть простішим. Перед закриттям використовуваної форми не можна забувати з'єднання, щоб запобігти витоку пам'яті.

Замість виведення

Хоч і ця схема вирішує деякі проблеми продуктивності, проте вона далека від ідеалу. Кожна форма, де потрібно буде підтримувати COM-з'єднання, створюватиме новий сеанс в інформаційній базі приймача, відповідно буде потрібна і більша кількість ліцензій. Також одним із головних мінусів є виключення підтримки з'єднання на сервері

У наступній статті буде розглянуто більш досконалий спосіб, який виключає ці проблеми (підключення через Web сервіси).



Подібні публікації