Ошибка метода OCCatalogRef.getObject()

classic Classic list List threaded Threaded
15 messages Options
man2000 man2000
Reply | Threaded
Open this post in threaded view
|

Ошибка метода OCCatalogRef.getObject()

Использую по-прежнему OCtitbit 0.5.3(r.1.8.4) на платформе Win Vista 64 bit
Раньше обращался к 1С только в режиме чтения - всё работало, теперь попробовал чего-нибудь изменить в БД и получаю ошибку.
Пытаюсь получить объект справочника "КалендарныеПланы", чтобы внести в него изменения.
Вот такая последовательность вызовов:

...
OCCatalogRef VariantCP = app.getCatalogManager("ВариантыКалендарныхПланов").findByCode("4");
System.out.println("ВариантКП = "+VariantCP.getDescription());
OCCatalogObject VCPobj = VariantCP.getObject();
System.out.println("КоличествоРабот = "+VCPobj.getAttributeValue("КоличествоРабот"));
OCCatalogRef RABref = app.getCatalogManager("КалендарныеПланы").findByCode("001", Boolean.FALSE, null, VariantCP);
System.out.println("Работа = "+RABref.getDescription());
OCCatalogObject RABobj = RABref.getObject();

...

Последняя строка NNN вызывает ошибку:
org.jinterop.dcom.impls.automation.JIAutomationException: Exception occurred.  [0x80020009]
        at org.jinterop.dcom.impls.automation.JIDispatchImpl.invoke(JIDispatchImpl.java:333)
        at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA(JIDispatchImpl.java:459)
        at org.jinterop.dcom.impls.automation.JIDispatchImpl.callMethodA(JIDispatchImpl.java:453)
        at com.ipc.msa.ComObject.callMethodA(ComObject.java:94)
        at com.ipc.oce.OCObject.callMethodA(OCObject.java:147)
        at com.ipc.oce.objects._OCCommonRef.getObject(_OCCommonRef.java:52)
        at com.ipc.oce.objects.OCCatalogRef.getObject(OCCatalogRef.java:131)
        at cit.usp.server.GreetingServiceImpl.ReExport2USP(GreetingServiceImpl.java:NNN)

...

В интерактивном режиме 1С под тем же пользователем этот объект изменить можно.

Куда копать ?
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

Возможный вариант, что ссылка RABref пустая - попробуйте ее на isEmpty. При этом:
1) RABref.getDescription() не вызывает ошибки, т.к. у пустой ссылки имеется пустое описание.
2) А вот объекта getObject уже нет и 1С кидает ошибку.

Возможная причина:
1) не тот owner. Т.е. у "КалендарныеПланы.001" owner не "ВариантыКалендарныхПланов.4". Попробуйте найти этот объект без указания owner-а, затем взять у найденного объекта getOwner и сравнить с КалендарныеПланы.001.
2) Справочник имеет иерархию и надо указывать или fullCode или parentRef
OCTitbit developer.
man2000 man2000
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

This post was updated on .
В том-то и дело, что RABref НЕ ПУСТАЯ, потому что

System.out.println("Работа = "+RABref.getDescription()); 

выдаёт ПРАВИЛЬНОЕ наименование ...

Поиск без owner'а выдаст не ту запись, которую нужно, так как с кодом 001 есть несколько записей у различных владельцев (впрочем, даже найденная простым методом findByCode("001") RABref при getObject() вызывает ту же ошибку).
А вот parentRef и fullCode заранее определить у искомой записи практически невозможно.

Сейчас занят тем, что сочиняю эквивалентный код на "чистой" j-Interop, но О-О-О-ЧЕНЬ ТЯЖКО %(

В порядке бреда: возможно что получаемый RABref в условиях неоднозначности кода - это массив ссылок, при этом RABref.getDescription() работает правильно, т.к. берёт нулевой элемент массива, а вот getObject() "лезет" не туда ?
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

С fullCode и parentRef это конечно барство.

Странно конечно.. часто работал и с getObject и с записью объектов все было ок. Кстати, еще мы такое наблюдали в системах с битыми ссылками, но тогда бы getDescription тоже ничего не выдал бы (хотя и isEmpty = false), так что это не Ваш случай.
А ошибка постоянно проявляется или от случая к случаю?
На других объектах этих справочников тоже самое?
А какая конфигурация? Я бы у себя может эксперименты провел.
OCTitbit developer.
man2000 man2000
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

Там выше я отредактировал сообщение... Искать объекты справочников пробовал разные - без разницы.

Конфигурация 1С "Управление строительным производством (Подрядчик строительства 3.0)" на платформе 8.1 разработанная в своё время ИВЦ Импульс, а сейчас основательно "допиленная" мною.

В принципе могу для опытов предоставить *.dt ( менее 100 Мб ), но об этом надо договариваться, например по ICQ
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

По поводу массивов ссылок это исключается. У 1С поиск в случае нахождения какой-то неоднозначности выдает первый попавшийся элемент. Это относится только к findXXX. Выборки (а-ля массивы) возвращают методы select.
Конфиг конечно экзотический, но это нормально. Если не получится найти ошибку, тогда чуть позже может придется и конфиг взять. Пока попробую на своих конфигах что-то подобное изобразить.
OCTitbit developer.
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

In reply to this post by man2000
Читал сейчас доку по 1С и не понял одного момента: методы find к менеджера справочников принимают owner-а только как ссылку на справочник. А вот сам owner у CatalogObject.getOwner может быть не только ссылкой на справочник, а еще всяким разным, например ссылкой на план обмена. Реализовать то по доке я реализовал, а вот как так я не понял.

Кстати можно попробовать не findXXX, а select найти этот справочник. Код указать через структуру. Но это временная и вынужденная мера, просто может с ее помощью получится найти ошибку find->ref->obj.

А кроме getDescription этот ref на что-нибудь еще реагирует, уж больно он странный.
OCTitbit developer.
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

This post was updated on .
Погонял у себя на УПП. Связка была такая: ЕдиницыИзмерения имели owner-а Номенклатуры или НоменклатурныеГруппы. Написал вот так:
OCCatalogManager catalogManager = app.getCatalogManager("ЕдиницыИзмерения");
			OCCatalogSelection selection = catalogManager.select();
			String mainCode = null;
			String ownerCode = null; String ownerMetaName = null;
			while(selection.next()) {
				if (selection.isFolder() == false && selection.getRef().getOwner() != null ) {
					OCCatalogObject selObj = selection.getObject();
					mainCode = (String)selObj.getCode();
					System.out.println("Main object code: " + mainCode + " (" + selObj.getMetadata().getName() + ")");
					OCCatalogRef ownerRef = selObj.getOwner();
					ownerCode = ownerRef.getFullCode();
					ownerMetaName = ownerRef.getMetadata().getName();
					System.out.println("Owner object code: " + ownerCode + " (" + ownerMetaName + ")");
					break;
				}
			}
			if (mainCode != null && ownerCode != null) {
				OCCatalogManager itemsManager = app.getCatalogManager(ownerMetaName);
				OCCatalogRef ownerCRef = itemsManager.findByCode(ownerCode, true, null, null);
				if (ownerCRef.isEmpty()) {
					System.out.println("* Owner not found");
				} else {
					System.out.println("* Owner object code: " + ownerCRef.getFullCode());
				}
				OCCatalogRef mainCRef = catalogManager.findByCode(mainCode, false, null, ownerCRef);
				if (mainCRef.isEmpty()) {
					System.out.println("* Main not found");
				} else {
					OCCatalogObject mainCObj = mainCRef.getObject();
					System.out.println("* Main object code: " + mainCObj.getFullCode());
				}
			} else {
				System.out.println("Bad 1C, bad...");
			}

Смысл какой:
В while я беру любой объект, у которого есть owner и запоминаю их коды. Также пришлось запоминать тип справочника owner-а, так как ЕдиницыИзмерения могут содержать в качестве owner справочники Номенклатура или Номенклатурные группы.
В IF я сперва нахожу owner-а. Тут пришлось использовать fullCode, так как этот справочник имеет иерархию (но я думаю это не ключевой момент). Далее, так же как и Вы, я ищу основной объект через find (code, false, null, onwerRef). В самом конце я получаю mainCRef.getObject() и все вроде бы работает.
SystemOut такой:
Main object code: 000027360 (ЕдиницыИзмерения)
Owner object code: 000000081/000000100 (НоменклатурныеГруппы)
* Owner object code: 000000081/000000100
* Main object code: 000027360

И на всякий случай версия платформы "1С:Предприятие 8.2 (8.2.13.205)" и конфиг "Управление производственным предприятием, редакция 1.3 + CRM, редакция 1.3 (1.3.12/1.3.2) (1.3.12.1)"
OCTitbit developer.
man2000 man2000
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

This post was updated on .
In reply to this post by IgorKonovalov
Проверил - RABref нормально реагирует например на вызов методов getOwner() и getParent(), но getObject() - не проходит !!!

Вообще я RABref и из запроса получал тоже:
OCQuery query1C = app.newQuery(
  "ВЫБРАТЬ "
  +"КалендарныеПланы.Ссылка КАК Ref "
  +"ИЗ "
  +"Справочник.КалендарныеПланы КАК КалендарныеПланы "
  +"ГДЕ "
  +"КалендарныеПланы.Владелец.Код = \"4\" "
  +"И КалендарныеПланы.ПометкаУдаления = FALSE"
 );

 - та же фигня.

Может быть дело в том, что у справочника КалендарныеПланы 49(!) реквизитов и 6 табличных частей по 3-5 реквизитов в каждой, т.е. в переполнении при загрузке объекта ?

IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

In reply to this post by man2000
Ммм... интересно. OCCatalogObject на стороне java объект не кэшируемый, т.е. все что он содержит находится на стороне 1С и в памяти самого сервера платформы 1С. По сети гоняются только запросы и примитивные типы данных. А у этого ref-а getFullCode кстати работает? И что все таки возвращает isEmpty?

И точно ли КалендарныеПланы имеет во владельцых ВариантыКалендарныхПланов? Или может есть вероятность другого владельца как это получилось в моем примере?
OCTitbit developer.
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

In reply to this post by man2000
man2000 wrote
Вообще я RABref и из запроса получал - та же фигня.
Если в логике нет каких-то ошибок, то это уже плохо... значит 1С не может по какой-то причине отдать этот объект. А в 1С-овских логах по этому поводу ничего не зафиксировано?
OCTitbit developer.
man2000 man2000
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

In reply to this post by IgorKonovalov
System.out.println("Работа 1С:УСП = "+RABref.getDescription()
+"   isEmpty = "+RABref.isEmpty()
+"   ПолныйКод = "+RABref.getFullCode()
+"   Родитель = "+RABref.getParent().getDescription()
+"   Владелец = "+RABref.getOwner() );


Выдача в консоли:

Работа 1С:УСП = Площадка
isEmpty = false
ПолныйКод = 1ПР/001
Родитель = Подготовительные работы
Владелец = Рабочий график
 (это ВариантКалендарногоПлана)

В журналах 1С ошибок нет.
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

Нда... все признаки вполне здоровой ссылки. Может действительно из-за объема... пока загадка. Сам getObject вполне рабочий, данную схему я прогнал в примере выше. Значит дело в конкретных объектах 1С.
OCTitbit developer.
IgorKonovalov IgorKonovalov
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

Походу не Вы первый. Я не отправляю в гугл, просто сам удивился, что это весьма распространено.
Это гугл:
http://www.google.ru/search?sourceid=chrome&ie=UTF-8&q=1%D0%A1+%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C%D0%9E%D0%B1%D1%8A%D0%B5%D0%BA%D1%82+%D0%BE%D1%88%D0%B8%D0%B1%D0%BA%D0%B0

А эта статья весьма интересна
http://nastroy-ka.ru/faq/8-faq/116--1-.html
Цитата оттуда:
В момент вызова процедуры ПолучитьОбъект() происходит создание объекта, с компиляцией его модуля. При работе пользователя с 1С никакой ошибки не возникает, потому что пользователь работает в "обычном режиме". Ему доступны все интерактивные функции, такие как Сообщить, Предупреждение или работа с диалогами. Т.е. такие функции которые влияют на поведение программы.
При работе с 1С в отличном от обычного, режиме, скажем "Внешнее соединение", как вы в данном примере, интерактивные функции становятся не доступными. 1С в таких режимах загружается не полностью, а только компилятор и исполняемый модуль - без интерфейсной части. Соответственно, при таком режиме работы вызов интерактивной функции, которая не помечена специальными маркерами - инструкциями препроцессору вызывает ошибку компилятора.
OCTitbit developer.
man2000 man2000
Reply | Threaded
Open this post in threaded view
|

Re: Ошибка метода OCCatalogRef.getObject()

Заработало, однако... Век живи - век учись !!! (с)

СПАСИБО !!!
Ну вот не обращал внимания на препроцессорные команды в 1С %(