Форум на Kuban.ru (http://forums.kuban.ru/)
-   Территория 1С (http://forums.kuban.ru/f1040/)
-   -   V8-V7 по COM (http://forums.kuban.ru/f1040/v8-v7_po_com-8917911.html)

USSR 07.07.2019 09:36

V8-V7 по COM
 
Доброго дня, коллеги! При работе с 7.7 из БП 3.0 по COM возникла засада, которую не знаю как решить. В 7.7 ищется Объект типа "Справочник", назовем его Объект77.
А затем мне надо спозиционироваться на него объектом определенного типа, вот так например:
Контр77 = БазаOLE.CreateObject("Справочник.Контрагенты");
Контр77.НайтиЭлемент(Элемент77);

Так вот, поиск в упор не работает. Пару лет назад не стал разбираться, а заменил поиск НайтиЭлемент на поиск по коду:
Контр77.НайтиПоКоду(Элемент77.Код);
Это все отлично работает, хотя я очень не люблю поиск по коду. Но вот возникло продолжение, появились нужда в справочниках, которые не имеют ни кода, ни наименования, например Единицы. И как же их искать? Можно конечно приделать к справочнику код, но как-то не хотелось бы.
Стал разбираться почему не ищет и обнаружил, что БазаOLE.ЗначениеВСтрокуВнутр возвращает строку с неизвестным видом справочника, то есть "172" (Контрагенты) напрочь пропадает. Та же проблема и при использовании класса MetaDataWork из 1С++. Метод ValueToLongDBString теряет вид объекта. Пробовал сам конструировать правильное внутреннее представление и подсовывать его в БазаOLE.ЗначениеИзСтрокиВнутр, но безуспешно, выдается ошибка
Кто сталкивался, как обойти эту проблему ?

Viking 07.07.2019 15:00

по ком работают только примитивные типы..
NULL, Неопределено, Число, Строка, Дата, Булево и массивы.
Данные типа "Объект" нормально работают если только они созданы через COM, т.е. в вашем случае "Элемент77" должен быть создан в базе, присоединенной через COM, а не в базе инициализирующей COM соединение.
[url]https://its.1c.ru/db/metod8dev#content:2262:hdoc@59413ad2[/url]
[url]https://its.1c.ru/db/metod8dev#content:2263:hdoc[/url]

USSR 07.07.2019 15:39

Я знаю про примитивные типы, но объект и найден в базе 77, и на него я хочу спозиционироваться

USSR 07.07.2019 15:45

Надо видимо в 77 завести глобальную переменную и ей присваивать найденный объект и потом уже найти элемент, где аргумент эта глобальная переменная

Фрезер 07.07.2019 21:31

[quote=USSR;46924015] ...но объект и найден в базе 77, и на него я хочу спозиционироваться... [/quote]
А база77 тоже так считает? Например
Сообщить(Элемент77.Код+" "+Элемент77.Наименование)
что-то ведь должно выдать.
Или что возвращает
Контр77.НайтиЭлемент(Элемент77)
0 / -1 / 1
(вечно путаю, а код не под рукой. Но что-то ведь должен вернуть "НайтиЭлемент")

USSR 07.07.2019 22:37

Я осознал свою детскую ошибку, тему можно закрывать)
(4) на это я и попался, что Элемент77 все нормально возвращает, и код, и наименование, но существует он не в базе 77, а а контексте обработки 8.3. Найтиэлемент возвращает 0. Но искать элемент77 и на него позиционироваться надо не в 8.3, а в базе 77. Но вот получится ли Так сделать большой вопрос. Проще наверное будет из 77 цепляться к 83, а не наоборот. Все будет искаться и писать можно в транзакции.

US1C 07.07.2019 22:40

(0) Собственно ты ответил на свой вопрос. Элемент77 не является элементом справочника "Контрагенты". Соответственно НайтиЭлемент(Элемент77) для Объекта=Справочник.Контрагенты вернет пустое значение.
Посмотри через ЗначениеВСтроку(Элемент77) что возвращается. И уже дальше копай, почему вместо ожидаемого элемента справочника Контрагенты получил элемент другого справочника (а может и не справочника).

Фрезер 07.07.2019 22:54

[quote=USSR;46924772] ...Проще наверное будет из 77 цепляться к 83, а не наоборот... [/quote]
Потому как явно путаница произошла в разбивке процедур
#Наклиенте
#Сервере
После выполнения
Контр77 = БазаOLE.CreateObject("Справочник.Контрагенты");
Сам "Контр77" меняет в отладчике значение с Пусто на OLE ?

USSR 08.07.2019 01:29

Что-то мое просветление закончилось и опять окутало сомнение. Давайте внесем ясность на простых модельных примерах
Пример1
Контр1 = База77.CreateObject("Справочник.Контрагенты");
Контр2 = База77.CreateObject("Справочник.Контрагенты");
Контр1.НайтиПоКоду(1);
Элемент77 = Контр1.ТекущийЭлемент();
Рез = Контр.НайтиЭлемент(Элемент77);
Сообщить(Рез);

Пример2
Рег = База77.CreateObject("Справочник.Регистратор");
Контр = База77.CreateObject("Справочник.Контрагенты");
Рез = Рег.НайтиПоКоду(1);
Сообщить(Рез);
Элемент77 = Рег.Элемент;
Рез = Контр.НайтиЭлемент(Элемент77);
Сообщить(Рез);

Так вот. В примере1 элемент77 благополучно ищется, в вот в примере 2 его поиск возвращает 0. База77.ЗначениеВСтрокуВнутр не распознает вид справочника. Возвращается, например, вот такое значение:
"B","0","0","0","0","0"," 0 5650 "
При этом Элемент77.Вид() возвращает "Контрагенты", более того, все реквизиты верны, например Элемент77.ЮрФизЛицо.ИНН ))

USSR 08.07.2019 01:41

В примере 2, Рег.Элемент - справочник неопределенного вида. Так вот оказывается, что если Рег.Элемент - справочник определенного вида, то все начинает работать как часики. Значит все дело не в контекстах объектов, а в косячности V77.Application. Путается он со справочником неопределенного вида.

USSR 08.07.2019 05:46

Отрекаюсь от (5) и все-таки полагаю, что в 8.3 мне по COM должны быть доступны все методы встроенного языка 7.7, ведь оперирую объектами, созданными в 8.3. Но вот со справочником неопределенного вида такая засада. А если не получается в 8.3 спозиционироваться на требуемый элемент справочника, то придется это делать в базе 7.7, вызывая нужные процедуры из 8.3 через EvalExpr, но тогда придется перетаскивать в 7.7 и всю запись справочников и документов. Тогда нет смысла в связке 8.3-7.7, проще юзать 7.7 -> 8.3. Наверное клиентом всегда должна быть база в которой пишешь, а сервером в которой читаешь

Фрезер 08.07.2019 07:28

А может к Реквизиту "Элемент" при Создании Элемента Спр.Регистратор не применяется НазначитьВид(<?>,); ?

Фрезер 08.07.2019 07:44

Или может так? (почти, не пользовался этим)
===
Рег = База77.CreateObject("Справочник.Регистратор");
Контр = База77.CreateObject("Справочник.Контрагенты");
Рез = Рег.НайтиПоКоду(1);
Сообщить(Рез);
База77.НазначитьВид(Рег.Элемент, "Контрагенты");
Элемент77 = Рег.Элемент;
Рез = Контр.НайтиЭлемент(Элемент77);
Сообщить(Рез);

USSR 08.07.2019 08:19

(11)Не назначал, но по моему это и не нужно. Это применяется вроде как для реквизитов формы. В базе у реквизита правильное значение и правильное внутреннее представление (для справочника неопределенного вида). Не знаю, может ты и прав, что если назначить вид, то внутреннее представление тоже станет как для определенного вида. Надо проверить

USSR 08.07.2019 09:11

(13)Это не прокатит, Рег.Элемент определен в контексте 8.3

US1C 08.07.2019 10:05

(8) Ну правильно. У тебя Рез - найденный по коду элемент справочника "Регистратор", а пытаешься получить значение реквизита "Элемент" у объявленной переменной объекта "Справочник.Регистратор".

USSR 08.07.2019 10:15

Не поверите, заработало:
Рез = Контр.НайтиЭлемент(Элемент77.ТекущийЭлемент());

Сам бы никогда не догадался. Бесподобный smaharbA:
Стр=ОлеИсточник.ЗначениеВСтрокуВнутр(СпрОЛЕ.ТекущийЭлемент())//ТекущийЭлемент() обязательно, даже если СпрОЛЕ уже элемент


Текущее время: 10:01. Часовой пояс GMT +3.