Робота з 1C Підприємство з Visual C + +, Різне, Програмування, статті

В даній статті показано, як можна працювати з 1С Підприємством з С + + за допомогою OLE DB. Так само вона буде цікава тим, хто не користується C + +, але хоче дізнатися подробиці “а як воно влаштовано всередині 1С”. У даній статті мова піде про 1С Підприємстві версії 7.7. Вважаю, що у версії 8 мало що змінилося. Передбачається, що читач хоча б трохи знайомий з 1С Підприємством. Так же передбачається, що ви вивчали офіційне керівництво 1С з питань OLE DB (частина друга опису мови), але решта незадоволений – тому що исходники там наведені для Visual Basic, А вам ну дуже потрібний саме C + + (до речі – не обов’язково Visual – Головне що б у вашому компіляторі була можливість працювати з OLE). 1С Підприємство надаємо користувачам механізм OLE DB. Якщо Вам раптом захотілося використовувати будь-які дані з 1С Підприємства у вашій програмі – ви можете скористатися цим механізмом. Зовсім просто це робиться в таких мовах, як Visual Basic або Delphi. У них вся робота з OLE-інтерфейсами замаскована від програміста наскільки можливо. Це, з одного боку, дуже зручно, але з іншого боку – у нас завжди є можливість підвищити продуктивність шляхом використання С + +. Він від своїх адептів нічого не маскує, це дозволяє яке де заощадити зайвий байт або мілісекунду, але перетворює роботу з OLE DB в пекло. Справа в тому, що 1С не надає для своїх користувачів бібліотеки імпорту (*. tlb), тому єдиний спосіб роботи (якщо не використовувати будь-які обгортки) – це пізнє скріплення. У Мережі повно інформації, як працювати з 1С Підприємством з Delphi або Visual Basic, Але практично зовсім немає прикладів з Visual C++.
Ця стаття покликана заповнити цю прогалину. Тут Ви знайдете шматочки робочого коду, який Ви можете дописувати і модифікувати на свій розсуд. По собі знаю, що іноді досить підглянути одним вічком, що б стало ясно, що до чого. Крім того, я розповім про деякі “тонкі” моменти роботи з 1С, які м’яко обійдені в офіційних виданнях, які мають гарний червоно-жовтий колір.
Найбільш розумним і зручним буде наступне рішення: ми організуємо всю необхідну роботу з 1С у вигляді окремої експортованої функції глобального модуля (я сподіваюся, Ви вже навчилися відкривати в 1С Глобальний модуль і додавати в нього експортовані функції). Ми будемо викликати потрібну функцію глобального модуля, яка буде повертати потрібне значення. Для багатьох практичних додатків цього цілком достатньо.

#include <objbase.h>
#include <comdef.h>
/ / Для початку инициализируем COM
HRESULT hr = CoInitialize(NULL);
if(FAILED(hr))
{
AfxMessageBox (“Неможливо ініціалізувати COM!”);
  return FALSE;
}
/*
Перш за все, нам необхідно отримати
ID сервера OLE Automation 1С Підприємства.
*/
CLSID   cls77;
/*
Використовуємо універсальний ключ 1С Підприємства
Детальніше див КЖК – якщо у Вас встановлена ​​єдина
версія 1С – то цього достатньо, якщо кілька різних,
то потрібно завантажити потрібний. Ось короткий список можливих значень:
V1CEnterprise.Application – версія незалежний ключ;
V77.Application – версія залежний ключ;
V77S.Application – версія залежний ключ, SQL-версія;
V77L.Application – версія залежний ключ, локальна-версія;
V77M.Application – версія залежний ключ, мережева-версія.
*/
hr = CLSIDFromProgID(L”V77.Application”, &cls77);
if(FAILED(hr))
{
AfxMessageBox (“Перевстановіть 1С Підприємство!”);
  CoUninitialize();
  return FALSE;
}
/ / Основний інтерфейс, за який ми будемо “смикати”
IDispatch *pv77;
/*
Створюємо інстанцію 1С Підприємства.
CLSCTX_LOCAL_SERVER – це означає, що 1С Підприємство
буде запущено у вигляді окремого процесу – за іншим воно не вміє.
*/
hr = CoCreateInstance(cls77, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pv77);
if(FAILED(hr)  //  !pv77)
{
AfxMessageBox (“Неможливо ініціалізувати інтерфейс 1С Підприємства”);
  CoUninitialize();
  return FALSE;
}
/*
поки все було зрозуміло і очевидно, далі починаються складності …
1С надає для запуску програми функцію Initialize.
Виклик цієї функції виглядає в VB елементарно
V7.Initialize (V7.RMTrade, “D: 1CТіпаБаза / N” + Користувач, “NO_SPLASH_SHOW”);
– Ми практично забуваємо, що ж відбувається всередині.
Але займаються С + + люди холоднокровні, труднощів не бояться.
По-перше: ми повинні пам’ятати, що аргументи необхідно заштовхувати задом наперед …
По-друге: ми повинні пам’ятати, що RMTrade – це доже IDispatch інтерфейс .. і його спершу потрібно
отримати.
*/
VARIANT       vRet;
DISPID dispIDRmTrade, dispIDInitialize;
DISPPARAMS args = {0, 0, 0, 0};
VARIANT vars [3]; / / Параметри для виклику Initialize
/ / Ми отримаємо IDispatch інтерфейс від RMTrade відразу в vars [2]
BSTR rmTrade = L”RMTrade”;
hr = pv77->GetIDsOfNames(IID_NULL, &rmTrade, 1, 0, &dispIDRmTrade);
if (FAILED(hr))
{
AfxMessageBox (“Неможливо отримати ID від RMTrade”);
  if (pv77)
    pv77->Release();
  CoUninitialize();
  return FALSE;
}
hr = pv77->Invoke(dispIDRmTrade, IID_NULL, 0, DISPATCH_PROPERTYGET, &args,
      &vars[2], NULL, NULL);
if (FAILED(hr))
{
AfxMessageBox (“Неможливо отримати інтерфейс від RMTrade”);
  if (pv77)
    pv77->Release();
  CoUninitialize();
  return FALSE;
}
/ / Потрібно отримати ID для Initialize (..);
BSTR init = L”Initialize”;
hr = pv77->GetIDsOfNames(IID_NULL, &init, 1, 0, &dispIDInitialize);
if (FAILED(hr))
{
AfxMessageBox (“Не вдалося отримати ID від Initialize”)
  if (pv77)
    pv77->Release();
  CoUninitialize();
  return FALSE;
}
/*
а тепер – викликати цей самий Initialize (..),
але спершу необхідно заповнити масив аргументів функції
*/
args.cArgs = 3;
args.rgvarg = vars;
vars[0] = _variant_t(“NO_SPLASH_SHOW”);
vars[1] = _variant_t(“/D D:1S /N Denis /P Denis “);
/*
vars [2] – у нас вже є, ми його отримали при запиті
інтерфейсу RMTrade в момент попереднього Invoke
*/
hr = pv77->Invoke(dispIDInitialize, IID_NULL, 0, DISPATCH_PROPERTYGET, &args,
   &vRet, NULL, NULL);
if(FAILED(hr) //  (vRet.vt ==  VT_BOOL && vRet.bstrVal == 0x00))
{
AfxMessageBox (“Неможливо запустити 1С Підприємство”);
}

Треба зауважити, що з цим останнім Invoke потрібно бути взагалі обережніше. У мене було таке, що навіть при правильній командному рядку виклик не вдавався. При цьому повинно з’явитися вікно, що пропонує поставити ім’я бази, ім’я користувача і т.п., можливо, це така особливість дизайну 1С. Зрештою довелося видалити старого користувача, і створити нового. Обережніше при розробці сервісів! Це вікно буде появляеться на віртуальному десктопі, і Ви просто нічого не побачите (якщо звичайно, не поставите галочку “взаємодіяти з робочим столом”).

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*