Доступ к данным 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();