Имя: Пароль:
1C
1С v8
Как определить имя подключенной базы (ComОбъект)?
0 Mikhail Volkov
 
02.07.14
13:40
Раньше подключался только к одной ИБ: подключился, ComОбъект в глобальной переменной, и по мере необходимости беру из той ИБ данные.
Теперь возникла необходимость цепляться в разным ИБ. Как определить имя текущей подключенной базы? (СтруктураПодключения или СтрокаПодключения сохранять в отдельной гл. переменной нежелательно)
1 DmitrO
 
02.07.14
13:47
Глобальный контекст (Global context)
СтрокаСоединенияИнформационнойБазы (InfoBaseConnectionString)
Синтаксис:

СтрокаСоединенияИнформационнойБазы()
Возвращаемое значение:

Тип: Строка.

Описание:

Возвращает Строка соединения информационной базы, которую, например, можно использовать для запуска 1С:Предприятия средствами встроенного языка в Automation, Менеджер COM-соединений. Пример результата метода: File="C:\1cv8\Base".

Доступность:

Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение.
2 Mikhail Volkov
 
02.07.14
16:46
А типа СтруктураПодключения.ИмяИБНаСервере никак?
Ну, в принципе ComОбъект.СтрокаСоединенияИнформационнойБазы() тоже содержит ИмяИБ
3 Mikhail Volkov
 
04.07.14
16:30
А GUID через Com-соединение получить можно?
Например, подключился, нашел во внешней базе нужный документ. Как получить его GUID?

Функция НайтиПоВходящимНомерДатаДокументПоступлениеТоваровУслугКА(Организация, ВхДокНомер, ВхДокДата)   Экспорт
    
    Запрос = COMОбъект.NewObject("Запрос");
    Запрос.Текст =
    Запрос = ОбъектКА.NewObject("Запрос");
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ПоступлениеТоваровУслуг.Ссылка,
    |    ПоступлениеТоваровУслуг.НомерВходящегоДокумента,
    |    ПоступлениеТоваровУслуг.Организация.Код КАК Код
    |ИЗ
    |    Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
    |ГДЕ
    |    ПоступлениеТоваровУслуг.ДатаВходящегоДокумента = &ВхДокДата
    |    И ПоступлениеТоваровУслуг.Организация.Код = &Организация";
    
    Запрос.УстановитьПараметр("ВхДокДата",     ВхДокДата);
    Запрос.УстановитьПараметр("Организация", Организация.Код);
        
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Если Найти(Выборка.НомерВходящегоДокумента, БезПрефикса(ВхДокНомер)) = 0 Тогда
            Продолжить;
        КонецЕсли;
        Возврат Выборка.Ссылка;
    КонецЦикла;
    Возврат Неопределено;
    
КонецФункции

НайденныйДокумент = НайтиПоВходящимНомерДатаДокументПоступлениеТоваровУслугКА(Документ.Организация, Документ.ВхДокНомер, Документ.ВхДокДата);
Если НайденныйДокумент <> Неопределено Тогда
    Документ.Номер        = НайденныйДокумент.Номер;
    Документ.Дата        = НайденныйДокумент.Дата;
//    Документ.СкладКомпании    = НайденныйДокумент.СкладОрдер;
    Документ.СкладКомпании    = Справочники.СкладыКомпании.НайтиПоКоду(НайденныйДокумент.СкладОрдер.Код);
//    Документ.УстановитьСсылкуНового(НайденныйДокумент.УникальныйИдентификатор());
    Сообщить("Найден с GUID: " + СокрЛП(НайденныйДокумент.УникальныйИдентификатор()) + ", Номер: " + СокрЛП(Документ.Номер) + ", Дата: " + СокрЛП(Документ.Дата) + ", Склад: " + СокрЛП(Документ.СкладКомпании));
КонецЕсли;

Да и не хотелось бы все (Организация, Склад) по кодам искать...!?
4 Mikhail Volkov
 
04.07.14
16:32
Сообщает: Найден с GUID: COMОбъект !?
5 Serginio1
 
04.07.14
16:36
COMОбъект.XMLСтрока(НайденныйДокумент.УникальныйИдентификатор()))
6 Mikhail Volkov
 
04.07.14
16:43
(5) Спс, а в текст запроса как-то GUID можно вставить, ну чтобы не по коду организации отбор делать?
7 hhhh
 
04.07.14
16:56
делаете в организации реквизит строковый Гуид, по нему и делаете отбор.
8 Serginio1
 
04.07.14
17:29
COMОбъект.Документы.ПоступлениеТоваровУслуг.ПолучитьСсылку()

А вообще лучше пользоваться внешними отчетами.
Премущества отладка в родной среде

v8: 8.2, COM-соединение, C#, dynamic строки
9 Mikhail Volkov
 
05.07.14
08:52
(8) У меня такая конструкция сработала:
Документ.СкладКомпании    = Справочники.СкладыКомпании.ПолучитьСсылку(Новый УникальныйИдентификатор(COMОбъект.XMLСтрока(НайденныйДокумент.СкладОрдер.УникальныйИдентификатор())));
Документ.УстановитьСсылкуНового(Документы.ПоступлениеТоваров.ПолучитьСсылку(Новый УникальныйИдентификатор(COMОбъект.XMLСтрока(НайденныйДокумент.УникальныйИдентификатор()))));
Покороче нельзя?

(7) Как это написать в запросе? Вместо:
    |    И ПоступлениеТоваровУслуг.Организация.Код = &ОрганизацияКод";
10 Mikhail Volkov
 
05.07.14
11:07
Дык, надо подставлять в отбор Организация не текущей базы, а подключенной базы COMОбъект! У меня есть такая функция:
Запрос.УстановитьПараметр("Организация", НайтиЭлементСправочникаCOMОбъект(Организация, "Организации"));
Заработало... Как насчет (9), нельзя как-то покороче?
11 Mikhail Volkov
 
06.07.14
05:46
Нельзя значит :(
(8) А что там про внешние отчеты? Чувствую, что придется мне скоро всякие сверки с партнером писать...
12 Serginio1
 
07.07.14
14:59
А какие у тебя проблемы с внешними отчетами?
13 Mikhail Volkov
 
08.07.14
09:09
(12) С внешними отчетами? Никаких. А как они связаны с COM-Объектами? С COM-Объектами как-то не приходилось работать, думаю нельзя ли их использовать для обмена баз? Обычно использую УниверсальныйОбменДаннымиXML. И сейчас также планировал поступить: ответный документ партнера создан (обновлен) в нашей базе, далее фоновое задание сделает обмен с базой партнера...
А сейчас думаю, а нельзя ли сразу после создания (обновления) этого документа предать его в базу партнера? Или вообще его не создавать в своей базе, а создавать (обновлять) прямо в базе партнера, подключенной как COM-Объект?
Есть отработанные схемы обмена через COM-Объект, где про них почитать?
14 Mikhail Volkov
 
08.07.14
10:01
+ Создавать, используя механизм заполнения на основании, но не записывать
15 Serginio1
 
08.07.14
11:29
(13) Я тебе ссылочку в 8 давал. Создаешь внешнийотчет из базы по COM. Вызываешь  метод модуля отчета помеченного как экспорт. Премущества это отладка и простота написания, т.к. отчет вызывается на стороне вызываемой базы.
  Если очень хочется онлайн, то проще использовать вэб сервисы, а не ком. Или напрямую писать используя SQL.
16 Mikhail Volkov
 
08.07.14
12:17
(15) По ссылке в (8) ничего не понял...
Он-лайн не желателен - зачем напрягать пользователя.
Когда начинаешь настраивать обмен, 1-м пунктом идет "Есть возможность подключиться к ИБ-приемнику" - это COM? (ни когда не пользовался)
17 Serginio1
 
08.07.14
12:28
(16) А что там непонятно?
v8: 8.2, COM-соединение, C#, dynamic строки

Там все расписано, правда на C#.
Вообще то при онлайне пользователь вообще не напрягается, т.к. обмен происходит после записи документа. То, что ты написал в 13.
18 Mikhail Volkov
 
08.07.14
13:03
(17) Суть? Через COM-соединение в ИБ-приемнике запускается внешняя обработка подобная УниверсальныйОбменДаннымиXML, которая делает внеочередной обмен (не дожидаясь расписания)?
19 Serginio1
 
08.07.14
13:44
(18)  Суть в том, что при загрузке через COM если соединение не кэшируется приходится подымать метаданные и более долгая начальная загрузка. При обмене через Веб сервис или http-сервис. Сервис уже запущен и метаданные загружены. Единственно, что для вэб сервиса нужно пройти установкуПараметровСеанса

v8: Web сервис, момент подключения

http сервисы должны быть еще легче
http://v8.1c.ru/o7/201312http/index.htm
20 Mikhail Volkov
 
08.07.14
14:37
Да, но еще кроме переноса еще возникает вопрос конвертации. Для УниверсальныйОбменДаннымиXML у меня правила обмена написаны.
И все же повторюсь: Когда начинаешь настраивать обмен, 1-м пунктом идет "Есть возможность подключиться к ИБ-приемнику" - это COM?
21 Serginio1
 
08.07.14
14:53
(20) А кто тебе мешает из Вэб сервиса вызвать твою внешнюю обработку?
22 Mikhail Volkov
 
08.07.14
18:03
Ну, не знаю, не пробовал... остановлюсь на файловом обмене (как и планировал). Тем более, сегодня "Есть возможность подключиться к ИБ-приемнику", а завтра - может и не быть...
23 Mikhail Volkov
 
31.07.14
07:01
Понадобилось получать не только ссылки документов из COM присоединенной базы, но и их табличные части:

// Получить табличную часть COMОбъекта
Функция ПолучитьCOMОбъектТЧ(СсылкаCom, ВидДокументаCom)   Экспорт
    
    Запрос = COMОбъект.NewObject("Запрос");
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ДокументТовары.Номенклатура,
    |    ДокументТовары.ХарактеристикаНоменклатуры,
    |    ДокументТовары.ЕдиницаИзмерения,
    |    ДокументТовары.Номенклатура.Артикул КАК Артикул,
    |    ДокументТовары.Коэффициент,
    |    ДокументТовары.Количество,
    |    ДокументТовары.Цена,
    |    ДокументТовары.ПроцентСкидкиНаценки,
    |    ДокументТовары.Сумма,
    |    ДокументТовары.СуммаНДС
    |ИЗ
    |    Документ." + ВидДокументаCom + ".Товары КАК ДокументТовары
    |ГДЕ
    |    ДокументТовары.Ссылка = &Ссылка";
    
    Запрос.УстановитьПараметр("Ссылка", СсылкаCom);
        
    ТЗCom = Запрос.Выполнить().Выгрузить();                // COM-Объект
    Для каждого СтрокаТЗ Из ТЗCom Цикл
        СтрокаТЗ.Номенклатура                = COMОбъект.XMLСтрока(СтрокаТЗ.Номенклатура.Ссылка);
        СтрокаТЗ.ХарактеристикаНоменклатуры = COMОбъект.XMLСтрока(СтрокаТЗ.ХарактеристикаНоменклатуры.Ссылка);
        СтрокаТЗ.ЕдиницаИзмерения            = COMОбъект.XMLСтрока(СтрокаТЗ.ЕдиницаИзмерения.Ссылка);
    КонецЦикла;
    СтрТЗCom = COMОбъект.ЗначениеВСтрокуВнутр(ТЗCom);    // COM-Объект в строку
    Возврат ЗначениеИзСтрокиВнутр(СтрТЗCom);            // ТЗ из строки
    
КонецФункции

ТЧ выгружаю в ТЗ, далее получаю ее посредством COMОбъект.ЗначениеВСтрокуВнутр()/ЗначениеИзСтрокиВнутр(). Для примитивных типов сработало, а для справочников - нет. Ну мне сами справочники не нужны, только их GUID-ы. Вставил цикл их замены на: COMОбъект.XMLСтрока(СтрокаТЗ.ЭлСправочника.Ссылка) - не работает!? И так тоже: COMОбъект.XMLСтрока(СтрокаТЗ.ЭлСправочника.Ссылка.УникальныйИдентификатор())
Что ни так?
24 Mikhail Volkov
 
31.07.14
09:37
+ СсылкаCom - это НайденныйДокумент в (3)
25 Mikhail Volkov
 
31.07.14
12:01
Оказалось тип колонок не тот, новые пришлось добавить:

    ТЗCom.Колонки.Добавить("НоменклатураGUID");
    ТЗCom.Колонки.Добавить("ХарактеристикаНоменклатурыGUID");
    ТЗCom.Колонки.Добавить("ЕдиницаИзмеренияGUID");
    Для каждого СтрокаТЗ Из ТЗCom Цикл
        СтрокаТЗ.НоменклатураGUID                = COMОбъект.XMLСтрока(СтрокаТЗ.Номенклатура.Ссылка);
        СтрокаТЗ.ХарактеристикаНоменклатурыGUID    = COMОбъект.XMLСтрока(СтрокаТЗ.ХарактеристикаНоменклатуры.Ссылка);
        СтрокаТЗ.ЕдиницаИзмеренияGUID            = COMОбъект.XMLСтрока(СтрокаТЗ.ЕдиницаИзмерения.Ссылка);
    КонецЦикла;

Но только коряво все как-то, покрасивши нет решения?
26 Mikhail Volkov
 
15.08.14
10:09
А еще не знаю как грамотно передавать Перечисления в присоединенную базу через COM-соединение. В простейшем случае я делаю так:

ОбъектCom.СтавкаНДС = ?(Ссылка.СтавкаНДС = Справочники.СтавкиНДС.БезНДС, COMОбъект.Перечисления.СтавкиНДС.БезНДС, COMОбъект.Перечисления.СтавкиНДС.НДС18);

Коряво, да? А если что-то посложнее, например, ВидОперации, которые у каждого типа документов свой, и значений несколько?
27 Трик
 
15.08.14
10:28
(26) если имена совпадают есть воможность сконвертировать погугли.
28 Serginio1
 
15.08.14
11:28
29 Torquader
 
15.08.14
13:35
(26) НИкто не мешает создать переменную и один раз в неё установить значение, а потом передавать её.
Если же делается один раз, то как бы не передавалась - скорость работы будет зависеть от других мест.
30 Torquader
 
15.08.14
13:36
+ Имя базы лучше всего по строке подключения определять.
31 Mikhail Volkov
 
15.08.14
14:52
(29) COMОбъект - глобальная переменная, содержит COM-соединение присоединенной базы.
ОбъектCom - объект, создаваемый в Com-базе, которому надо установить реквизит типа ПеречислениеСсылка.
Меня пугает, что приходится писать длинные конструкции... или это нормально, просто непривычно?
(28) Не очень понял, что предлагает автор: все возможные перечисления собрать в некий справочник, а через COM-соединение передавать коды нужных тебе перечислений?
32 Torquader
 
15.08.14
15:09
Просто, с перечислениями есть "засада" - у них нет GUID-а.
Если нам хочется работать с данными одной базы в другой базе или другой программе, то мы легко можем хранить вместо самого объекта строковое представление GUID-а.
То есть, получив какое-то значение из "далёкой" базы, мы сначала проверяем его тип - если он не ComObject, то у нас строка,дата, число или булево - получается значение, которым легко оперировать.
Если мы получаем ComObject, то у всех объектов в базе, кроме перечисления, есть метод УникальныйИдентификатор(), который возвращает GUID (который, правда, всё равно ComObject), но из него легко сделать строку ComBase.String(GuidFromFarBase) и ей уже можно прекрасно оперировать.
С перечислением сложнее, нужно узнать идентификатор перечисления, а потом получить идентификатор значения перечисления (если мы просто приведём к строке, то получим представление) - соответственно, очень много операций - если все значения перечислений где-то есть, то мы просто ищем значение в этом "списке" и получаем его "представление" для нас.

P.S. честно говоря (28) не читал, но другого смысла в использовании справочника всех перечислений не вижу.
33 Mikhail Volkov
 
15.08.14
15:27
(32) В (9) пример, я нашел Документ в COM-базе, и копирую его в свою базу. При этом использую такую длинную конструкцию:
Документ.УстановитьСсылкуНового(Документы.ПоступлениеТоваров.ПолучитьСсылку(Новый УникальныйИдентификатор(COMОбъект.XMLСтрока(НайденныйДокумент.УникальныйИдентификатор()))));

ComBase.String(GuidFromFarBase) - вижу впервые, как это применить для моего примера?
34 Mikhail Volkov
 
15.08.14
15:34
(32) Да, у них нет GUID-а, но есть Имя, а у значения вроде Индекс - их можно передать в COM-базу. Вот только как с их помощью задать нужное Перечисление?
35 Serginio1
 
15.08.14
15:46
(31) http://help1c.com/help/view/7666.html

ну и вычислить.

Но я являюсь сторонником внешних отчетов вызывая метод из них передавая нужные параметры и получая ответ например ввиде тз.
36 Mikhail Volkov
 
15.08.14
15:48
+ Например, для простых справочников: Валюты, КлассификаторЕдиницИзмерения, и т.п. GUID-ы не использую:
ОбъектCom.Валюта = COMОбъект.Справочники[ТипОбъекта].НайтиПоКоду(Ссылка.Код);
(если имена совпадают)
37 Serginio1
 
15.08.14
16:04
А так работает ?
Ставка=COMОбъект.Перечисления.СтавкаНДС["НДС18"];
38 Serginio1
 
15.08.14
16:06
Ну а имя перечисления
ИмяПеречисления = СсылкаНаПеречисление.Метаданные().Имя;
39 Mikhail Volkov
 
15.08.14
16:20
(37) Вроде должно, проверю...
(38) В итоге: СтавкаНДС = COMОбъект.Перечисления[ИмяПеречисления][1]; - если индекс значения НДС18 = 1 (или 0?)?
40 Serginio1
 
15.08.14
16:23
39
Нет можешь
СтавкаНДС =COMОбъект.Перечисления.СтавкаНДС[XmlСтрока(Ссылка.СтавкаНДС )];
41 Mikhail Volkov
 
15.08.14
16:53
(40) Скорее, так: СтавкаНДС = COMОбъект.Перечисления[ИмяПеречисления]; или так СтавкаНДС = COMОбъект.Перечисления[1]; - пробовать буду... вообще-то в Альфа-Авто Ставки НДС - справочник, но ИмяПеречисления или его Индекс в типовой УПП/КА мне будет известен заранее.
Спс за ссылку (35) - что-то начал понимать...
42 Defender aka LINN
 
15.08.14
16:57
Что мешает КД использовать?
43 Mikhail Volkov
 
15.08.14
17:13
(42) Первоначально так и задумывалось: в нашей базе создали реализацию "близкому" партнеру (в одной сетке). По нему автоматом формируется ответный документ поступления. Номер по COM-соединению беру из базы партнера. Чтобы его не заняли, надо его застолбить там - создаю там пустой документ, его номер и GUID присваиваю ответному документу в своей базе. После этого посылаю сигнал фоновому заданию, чтобы сделал внеочередной обмен (желательно только этим документом)...
Как-то сложно все это, вот пробую сразу заполнить ответный документ через COM-соединение.
44 Mikhail Volkov
 
15.08.14
17:15
+ Может есть более простые решения этой задачи?
45 Defender aka LINN
 
15.08.14
19:36
(43) Ты же в курсе, что обработок, которые использую правила, больше, чем 1, но меньше, чем 3?
Можно обмен через планы обмена и правила из КД настроить, все тебе будет.
46 Mikhail Volkov
 
15.08.14
20:00
(45) Это все есть, и по ночам выполняется через УниверсальныйОбменДаннымиXML около 2-3 часов. Но обмен с партнером надо сделать быстро (3-5 минут) одним или списком из (до) 5-7 документов.
Как задать этот список для обработки УниверсальныйОбменДаннымиXML я не нашел. :(
47 Torquader
 
15.08.14
23:58
Чего-то мне кажется, что OleБаза.Перечисления[ИмяПеречисления][ЗначениеПеречисления] должно работать.
48 Defender aka LINN
 
16.08.14
10:20
(46) Там какбе отборы есть
49 Mikhail Volkov
 
17.08.14
07:55
(48) Например, срочно понадобилось обменяться цепочкой документов: заказ покупателя, заказ поставщику, реализация, поступление, возврат от покупателя, возврат поставщику... (возможны еще корректировки) - е все по одному документу. Проблематично это отбором делать.
50 ДенисЧ
 
17.08.14
08:08
(49) Если тебе это проблематично, то может, поменяешь профессию?
В дворники не предлагаю, там занято, может, в два раза больше пойдёшь зарабатывать?
51 Serginio1
 
18.08.14
12:48
(46) Я использую обмен через схему загружаемой базы. Это аналог КД ,но так как использыется Схема загружаемой базы то при загрузке используется СериализаторXDTO, а при выгрузке создаются процедуры записи, которые записывают ОбъектXDTO и которые легко можно модифицировать. Скорость обмена очень быстрая.
52 Mikhail Volkov
 
18.08.14
16:07
(51) Схемы аналогичные КД в принципе инертны - в процессе обмена могут изменить документ, если выгружается более одного документа. И чем больше этот список, тем больше вероятность, что выгрузится уже неактуальная версия документа.
По по COM-соединению создание/обновление COM-документа происходит сразу после его записи (в моей схеме).
В общем с заполнением реквизитов шапки и табличной части COM-документа разобрался. Вот только не проводится!? На
ДокументCom.Записать(РежимЗаписиДокумента.Проведение, РежимПроведенияДокумента.Неоперативный); пишет ошибку:
Ошибка при вызове метода контекста (Записать): Произошла исключительная ситуация (1C:Enterprise 8.2.19.90): Несоответствие типов (параметр номер '1')
В процедуре ОбработкаПроведения() COM-базы поставил точки останова - никакой реакции!? Как отлаживать проведение COM-документа?
53 Mikhail Volkov
 
18.08.14
16:10
+ Хотя в самой COM-базе вручную проводится без проблем!?
54 Mikhail Volkov
 
18.08.14
16:26
Разобрался, так надо: ДокументCom.Записать(COMОбъект.РежимЗаписиДокумента.Проведение);
55 Serginio1
 
18.08.14
17:15
(52) Необязательно. Ты можешь используя COM записывать через СериализаторXDTO, а можешь и в оффлайне, а можешь через Вэб сервисы. Непринципиально, но универсально.
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.