На главную

Доступ к данным 1С из C++.


Достаточно экзотическая задача: получение данных посредством OLE автоматизации из 1С в среде Visual C++. Информации по этому вопросу весьма мало, поэтому пришлось скрести по сусекам... Попытка вытащить остатки по 51 счёту и по кассе из бухгалтерской базы. Где то приблизительно так:

Переменные

HRESULT hr;
CComBSTR name;
BYTE *parms;
BYTE *parmsDate;
BYTE *parmsPer;
BYTE *parmsIt;

Создаем OLE объект

CoInitialize(NULL); 
COleDispatchDriver drvApp;
BOOL ret=drvApp.CreateDispatch("V77.Application"); 
if(!ret) { TRACE("ОБЪЕКТ НЕ НАЙДЕН\n"); return 0; } ;

Находим ID объекта "RMTrade",создаем

DISPID id_rmtrade=0;
name=_T("RMTrade"); 
hr=drvApp.m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&id_rmtrade);
if(hr!=S_OK || id_rmtrade==0 || id_rmtrade==-1) { TRACE("ОБЪЕКТ НЕ НАЙДЕН\n"); return 0; } 

Получаем его значение

long RMTrade=0;
drvApp.GetProperty(id_rmtrade,VT_I4,&RMTrade);

Дальше надо проинициализировать 1С. Находим ID метода Initialize

BOOL init;
name=_T("Initialize");
DISPID id_init=0; 
hr=drvApp.m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&id_init); 

Путь к базе данных 1С, имя, пароль

CString strCommand="/DC:\\All\\БлаБлаБла\\ /M /NWhu /P123" ; 

Необязательный параметр, значение NO_SPLASH_SHOW - не показывать заставку при загрузке 1С

CString strEmpty="NO_SPLASH_SHOW"; 

Параметры и вызов метода Initialize

parms=(BYTE*)(VTS_I4 VTS_BSTR VTS_BSTR);
drvApp.InvokeHelper(id_init,DISPATCH_METHOD,VT_BOOL,&init,parms,
					RMTrade,
					(void*)(LPCTSTR)strCommand,
					(void*)(LPCTSTR)strEmpty);
if(init==FALSE) { TRACE("Initialize failed!\n"); return 0; }

Находим ID метода CreateObject

name=_T("CreateObject"); 
DISPID id_create=0; 
hr=drvApp.m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&id_create);

Указатель на объект, который надо получить

IDispatch *pBI=NULL; 

Параметры вызова метода CreateObject и имя объекта

parms=(BYTE*)(VTS_BSTR);
CString strBI="БухгалтерскиеИтоги";
drvApp.InvokeHelper(id_create,DISPATCH_METHOD,VT_DISPATCH,&pBI,parms,(void*)(LPCTSTR)strBI);
if(pBI==NULL) { TRACE("ОБЪЕКТ НЕ НАЙДЕН\n"); return 0; };

Иеперь найдём текущую дату, находим ID метода EvalExpr

name=_T("EvalExpr"); 
DISPID id_eval=0; 
hr=drvApp.m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&id_eval);

Параметры вызова метода EvalExpr, имя объекта

parmsDate=(BYTE*)(VTS_BSTR);
CString pData;
CString strDate="ТекущаяДата()";
drvApp.InvokeHelper(id_eval,DISPATCH_METHOD,VT_BSTR,&pData,parmsDate,(void*)(LPCTSTR)strDate);

Работаем с бухгалтерскими итогами

COleDispatchDriver drvBI;
drvBI.AttachDispatch(pBI);

drvBI - и есть наши бухгалтерские итоги

DISPID id_pereschet=0;
name=_T("Рассчитать");
hr=drvBI.m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&id_pereschet);

рассчитаем бух итоги

BOOL Rasch = 0;
parmsPer=(BYTE*)(VTS_BSTR);
if(id_pereschet) drvBI.InvokeHelper(id_pereschet,DISPATCH_METHOD,VT_BOOL,&Rasch,parmsPer,(void*)(LPCTSTR)pData);

хотим смотреть сальдо по дебету на начало периода

DISPID id_itogi=0;
name=_T("СНД");
hr=drvBI.m_lpDispatch->GetIDsOfNames(IID_NULL,&name,1,LOCALE_SYSTEM_DEFAULT,&id_itogi);

Неужели добрались таки? Наконец то можем запросить остатки по 51 счёту, опять этот дурацкий тип данных VARIANT...

double Itogi51=0 ;
parmsIt=(BYTE*)(VTS_BSTR);
CString strIt="51";
if(pBI!=NULL) drvBI.InvokeHelper(id_itogi,DISPATCH_METHOD,VT_R8,&Itogi51,parmsIt,(void*)(LPCTSTR)strIt);

Аналогично остатки по 50

double Itogi50=0 ;
parmsIt=(BYTE*)(VTS_BSTR);
strIt="50";
if(pBI!=NULL) drvBI.InvokeHelper(id_itogi,DISPATCH_METHOD,VT_R8,&Itogi50,parmsIt,(void*)(LPCTSTR)strIt);

Всё работает! как ни странно...

drvApp.ReleaseDispatch();
Eladres (8K)

Используются технологии uCoz