Основная задача состояла в синхронизации нашего сервиса с 1С(списком контрагентов, номенклатуры и т.д.)
При этом 1С могла быть как на dbf-файлах, так и на MSSQL, поэтому было решено испольнозовать COM для связи сервиса с 1С. Конечно, если бы 1С работала на SQL, гораздо проще было бы общаться с ней с помощью jdbc драйвера, но так как варианты конфигурации могли быть самые разные, использование сom решало все проблемы.
JACOB идеально подошел нашим требованиям. Дальше задача выглядела тривиально: переписать код 1С через com.
Инициализация и авторизация в 1С:
try {
sC = new ActiveXComponent(_1CUtils.V7_APPLICATION);
sControl = (Dispatch)sC.getObject();
} catch (Exception e) {
e.printStackTrace();
throw new _1CException(_1CException._1C_NOT_AVAILABLE) ;
}
int rmTradeId ;
try {
rmTradeId = Dispatch.getIDOfName(sC, _1CUtils.V7_RM_TRADE) ;
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw new _1CException(_1CException.RM_TRADE_NOT_AVAILABLE);
}
Variant rmTradeVar = Dispatch.invoke(sControl, rmTradeId, Dispatch.Get, new Object[]{}, new int[]{rmTradeId}) ;
int id = Dispatch.getIDOfName(sControl, _1CUtils.V7_INITIALIZE) ;
Object[] args = new Object[3] ;
args[0] = rmTradeVar.getInt() ;
args[1] = "/D" + ResourceUtils.getResource("path") + " /N" + ResourceUtils.getResource("user") + " /P" + ResourceUtils.getResource("password") ;
args[2] = new Variant("NO_SPLASH_SHOW").getString() ;
Variant result = Dispatch.invoke(sControl, _1CUtils.V7_INITIALIZE, Dispatch.Get, args, new int[]{id}) ;
if (!result.getBoolean()) {
throw new _1CException(_1CException.NOT_AUTHORISED);
}
В переменных _1CUtils.V7_APPLICATION, _1CUtils.V7_RM_TRADE, _1CUtils.V7_INITIALIZE хранятся соответсвующие значения:
- V77.Application
- RMTrade
- Initialize
Для авторизации используется второй параметр функции Initialize – “/DПуть /NПользователь /PПароль”.
Далее, используя стандартные функции 1С, мы можем получить доступ ко всем данным.
- Для чтения свойства справочника воспользоваться функцией GetAttrib, для записи – SetAttrib.
- Для создания объекта – CreateObject
- Для поиска – FindByCode, FindByDescr
- Для выбора из перечисления функциями – ValueByIdentifier
- Для создания нового объекта – New
- Для получения текщуго значения – CurrentItem, выбора значений -SelecвtItems, выбора текущего значения – GetItem
- Для записи – Write
- и т.д.
Прекрасный справочник по работе с функциями 1С можно скачать здесь
Весь функционал работы с 1С был вынесен на отдельный сервер под Windows)), общение с которым осуществлялось псредством веб-сервисов(использовалась связка tomcat+metro).
Не забудьте положить jacob.dll в classpath(или Windows/system32/)
Отличный материал!
Вот только ссылка на справочник по работе с функциями 1С не работает.
В развитие темы нельзя ли еще привести примеры по чтению/записи данных в 1с 7.7 с помощью Jacob и закрытию объекта после использования.
Материала по данной теме крайне мало, а он крайне нужен.
комментарий от arhosbros — Февраль 28, 2010 @ 4:10 дп
Конечно, можно)
http://webfile.ru/4328437 – вот здесь можно посмотреть пример работы с 1С. В _1CUtils хранятся оболочки для 1С-ных функций.
Для записи объектов используется функция write:
public static Variant write(Dispatch dispatch) {
return invokeFunction(dispatch, “Write”) ;
}
public static Variant invokeFunction(Dispatch dispatch, String functionName) {
return invokeFunction(dispatch, functionName, new Object[]{}) ;
}
В income/IncomeServiceImpl в конце метода create можно посмотреть как она используется:
_1CUtils.write(incomeDispatch) ;
Для чтения и выставления свойств:
public static Variant getProperty(Dispatch dispatch, String propertyName) {
return invokeFunction(dispatch, “GetAttrib”, new Object[]{propertyName}) ;
}
public static Variant setProperty(Dispatch dispatch, String propertyName, String propertyValue) {
return invokeFunction(dispatch, “SetAttrib”, new Object[]{propertyName, propertyValue}) ;
}
public static Variant setProperty(Dispatch dispatch, String propertyName, Dispatch propertyValue) {
return invokeFunction(dispatch, “SetAttrib”, new Object[]{propertyName, propertyValue}) ;
}
public static Variant setProperty(Dispatch dispatch, String propertyName, Double propertyValue) {
return invokeFunction(dispatch, “SetAttrib”, new Object[]{propertyName, propertyValue}) ;
}
Для получения списка объектов:
Dispatch contactDispatch = _1CUtils.createObject(getControl(), ResourceUtils.getResource(“dictionary.kontragent”)).getDispatch() ;
Double selectItemsResult = _1CUtils.selectItems(contactDispatch).getDouble() ;
if (selectItemsResult != 1.0) {
return contacts ;
}
boolean bReturn ;
int i = 0 ;
do {
bReturn = _1CUtils.getItem(contactDispatch).getDouble() != 1.0 ;
if (!bReturn) {
Dispatch currentСontactDispatch = _1CUtils.getCurrentItem(contactDispatch).getDispatch() ;
Еще много проблем вызывали Enum’ы но и для них обертки можете посмотреть в _1CUtils
комментарий от sidslog — Февраль 28, 2010 @ 9:11 дп
Обновил ссылку на справочник по 1с 7.7
комментарий от sidslog — Март 1, 2010 @ 10:41 пп
Большое спасибо!
Буду разбираться.
комментарий от ArhosBros — Март 3, 2010 @ 5:12 дп