Имя: Пароль:
1C
1С v8
1с83 запрос через com соединение
0 buketovav
 
21.11.19
08:24
Добрый день, Дорогие Форумчане!
Столкнулся с задачей: необходимо установить подключение к базе через com соединение и создать новый документ - с этим проблем нет.
Есть проблема с заполнением двух реквизитов этого документа, для того, чтобы их заполнить необходимо выполнить запрос к подключаемой базе, чтобы выбрать там сотрудника по реквизиту справочника "физическое лицо", ниже привожу код.
Скажите, что делаю не так и как правильно выполнить такой запрос и его обработать?

    ЗапросВ = КомСоединение.NewObject("Запрос");
    ЗапросВ .Текст = "ВЫБРАТЬ
    |Сотрудники.Представление КАК Сотрудник,
    |Сотрудники.ФизическоеЛицо.Наименование КАК ФизическоеЛицо,
    |Сотрудники.СтруктураКомпании.Представление КАК СтруктураКомпании
    |ИЗ
    |Справочник.Сотрудники КАК Сотрудники
    |ГДЕ
    |НЕ Сотрудники.СтруктураКомпании = ЗНАЧЕНИЕ(Справочник.СтруктураКомпании.ПустаяСсылка)
    |И Сотрудники.ФизическоеЛицо = &ФизическоеЛицо";
    
    ФизЛицо = КомСоединение.Справочники.ФизическиеЛица.НайтиПоНаименованию(СтруктураДанных.Сотрудник);
    ЗапросВ.УстановитьПараметр("ФизическоеЛицо", ФизЛицо);
    
    com_Результат     = ЗапросВ.Выполнить(); // COM объект    
    com_ТЗ_Сотрудники = ЗапросВ.Выгрузить(); // COM объект
    
    // Получаем таблицу значений из COM-объекта
    // COMОбъект в -> строку
    // Запишем COMОбъект в строку на стороне базы-источника
    стр_ТЗ_Сотрудники = КомСоединение.ЗначениеВСтрокуВнутр(com_ТЗ_Сотрудники);

    // получим таблицу значений из строки
    ТЗ_Сотрудники = ЗначениеИзСтрокиВнутр(стр_ТЗ_Сотрудники);

    МенеджерДокумента = КомСоединение.Документы.ЗаписьВРНФактическиеОтпуска;
    КомСоединение.УстановитьБезопасныйРежим(Ложь);
    КомСоединение.УстановитьПривилегированныйРежим(Истина);

    НовДок      = МенеджерДокумента.СоздатьДокумент();
    НовДок.Дата = СтруктураДанных.Период;
    НовДок.Сотрудник...
1 GROOVY
 
21.11.19
08:25
В то время как советские корабли бороздят всякие ws, rest, oData, и прочие http, мы продолжаем юзать COM.
2 buketovav
 
21.11.19
08:28
(1) ws, rest, oData, и прочие http - что из этого оптимальнее и правильнее
3 Галахад
 
гуру
21.11.19
08:35
(0) В чем проблема-то? Код вроде рабочий.
4 Darych
 
21.11.19
08:35
ессно правильнее, но Паша решил пойти по моему пути == пернуть в сторону нормального пути. И он таки прав!).. Комом сейчас узкие задачи решаются )).. и очень узкие)
5 buketovav
 
21.11.19
08:38
(3) как обработать в данном случае результат запроса. стандартными методами не удается, ошибки валятся
6 buketovav
 
21.11.19
08:39
(4) подскажите, где взять материалы по этому правильному и нормальному пути? что-то гугл мне не помог (
7 Darych
 
21.11.19
08:40
(5) обрабатывай там где делаешь
8 Галахад
 
гуру
21.11.19
08:42
(5) Еще раз, в (0) код вроде без ошибок. Если косяки где-то в другом месте, неверное это и нужно выложить?
9 buketovav
 
21.11.19
08:43
(8) {ОбщийМодуль.ДобавленныйОбщийМодульComСоединение.Модуль(79)}: Метод объекта не обнаружен (Выгрузить)
    com_ТЗ_Сотрудники = ЗапросВ.Выгрузить(); // COM объект
10 Галахад
 
гуру
21.11.19
08:45
com_Результат     = ЗапросВ.Выполнить(); // COM объект    
//com_ТЗ_Сотрудники = ЗапросВ.Выгрузить(); // COM объект
com_ТЗ_Сотрудники = com_Результат.Выгрузить(); // COM объект
11 Darych
 
21.11.19
08:51
(10) не взлетит)
12 buketovav
 
21.11.19
08:51
(10) в итоге ТЗ_Сотрудники пустая, хотя в базе, к которой подключаюсь и выполняю в ней запрос, отрабатывает все правильно и выводит нужный результат
13 buketovav
 
21.11.19
08:52
то есть запрос правильный
14 Darych
 
21.11.19
08:53
(12) из кома читай что те нужно в постобработке запроса
15 buketovav
 
21.11.19
08:54
(14) то есть это как? не совсем понял
16 buketovav
 
21.11.19
08:54
(14) я же комп попытался выгрузить в ТЗ, но она пустая получилась
17 Darych
 
21.11.19
08:57
(15) 1. Прочти про ком и данные, которые передаются. Ты не сможешь тз передать через ком -> думай, все просто))
18 ЗлаяЗая
 
21.11.19
08:58
com_ТЗ_Сотрудники =com_Результатпрос.Выполнить().Выбрать();
правильно?
19 buketovav
 
21.11.19
09:06
(18) здесь получите - Метод объекта не обнаружен (Выполнить)
20 Darych
 
21.11.19
09:09
(19) полный код от начала запроса до ошибки
21 Галахад
 
гуру
21.11.19
09:11
(17) Строкой можно.
22 buketovav
 
21.11.19
09:14
МенеджерДокумента = КомСоединение.Документы.ЗаписьВРНФактическиеОтпуска;
    КомСоединение.УстановитьБезопасныйРежим(Ложь);
    КомСоединение.УстановитьПривилегированныйРежим(Истина);
    
    //Попытка
    
    НовДок      = МенеджерДокумента.СоздатьДокумент();
    НовДок.Дата = СтруктураДанных.Период;
        
    ЗапросВ = КомСоединение.NewObject("Запрос");
    ЗапросВ.Текст = "ВЫБРАТЬ
    |Сотрудники.Представление КАК Сотрудник,
    |Сотрудники.ФизическоеЛицо.Наименование КАК ФизическоеЛицо,
    |Сотрудники.СтруктураКомпании.Представление КАК СтруктураКомпании
    |ИЗ
    |Справочник.Сотрудники КАК Сотрудники
    |ГДЕ
    |НЕ Сотрудники.СтруктураКомпании = ЗНАЧЕНИЕ(Справочник.СтруктураКомпании.ПустаяСсылка)
    |И Сотрудники.ФизическоеЛицо = &ФизическоеЛицо";
    
    ФизЛицо = КомСоединение.Справочники.ФизическиеЛица.НайтиПоНаименованию(СтруктураДанных.Сотрудник);
    ЗапросВK.УстановитьПараметр("ФизическоеЛицо", ФизЛицо);
    
    com_Результат     = ЗапросВ.Выполнить(); // COM объект    
    com_ТЗ_Сотрудники = com_Результат.Выгрузить(); // COM объект
    
    // Получаем таблицу значений из COM-объекта
    // COMОбъект в -> строку
    // Запишем COMОбъект в строку на стороне базы-источника
    стр_ТЗ_Сотрудники = КомСоединение.ЗначениеВСтрокуВнутр(com_ТЗ_Сотрудники);

    // получим таблицу значений из строки
    ТЗ_Сотрудники = ЗначениеИзСтрокиВнутр(стр_ТЗ_Сотрудники);

получаем пустую ТЗ
23 Индиго
 
21.11.19
09:22
(22)Нормально можно передавать ТЗ через COM, только если в ней все ссылки будут ComObject
Если ТЗ пустая, значит результат запроса пустой.Смотри правильность заполнения параметров запроса, может у тебя ссылки не нашло или еще чего
24 buketovav
 
21.11.19
09:23
так формируется структцра данных:

СтруктураДанных = Новый Структура;
    Для каждого Стр Из Источник.ЭтотОбъект Цикл
        СтруктураДанных.Вставить("Период",           Стр.Период);
        СтруктураДанных.Вставить("Регистратор",      Строка(Стр.Регистратор));
        СтруктураДанных.Вставить("Активность",       Стр.Активность);
        СтруктураДанных.Вставить("ВидДвижения",      "");
        СтруктураДанных.Вставить("Сотрудник",        Стр.Сотрудник);
        СтруктураДанных.Вставить("ВидЕжегодногоОтпуска", Стр.ВидЕжегодногоОтпуска);
        СтруктураДанных.Вставить("Количество",       Стр.Количество);
        СтруктураДанных.Вставить("ДатаНачала",       Стр.ДатаНачала);
        СтруктураДанных.Вставить("ДатаОкончания",    Стр.ДатаОкончания);
        СтруктураДанных.Вставить("Компенсация",      Стр.Компенсация);
        СтруктураДанных.Вставить("ДатаРегистрации",  Стр.ДатаРегистрации);
        СтруктураДанных.Вставить("РабочийПериодС",   Стр.РабочийПериодС);
        СтруктураДанных.Вставить("РабочийПериодПо",  Стр.РабочийПериодПо);
        СтруктураДанных.Вставить("Основание",        Стр.Основание);
        СтруктураДанных.Вставить("ПериодНачисления", Стр.ПериодНачисления);
        СтруктураДанных.Вставить("Сторно",           Стр.Сторно);
    КонецЦикла;
25 Индиго
 
21.11.19
09:24
* Если - лишнее:-). просто они там будут
26 Индиго
 
21.11.19
09:25
(24) Если СтруктураДанных.Сотрудник - это сотрудник в текущей базе, то ты оптимист - искать ссылку этой базы в подключенной напрямую
27 Индиго
 
21.11.19
09:26
Если там ссылка конечно а не наименование
28 SSSSS_AAAAA
 
21.11.19
09:27
(22) "    ФизЛицо = КомСоединение.Справочники.ФизическиеЛица.НайтиПоНаименованию(СтруктураДанных.Сотрудник);
    ЗапросВK.УстановитьПараметр("ФизическоеЛицо", ФизЛицо);
"
И с чего решили что ссылка на элемент справочника в удаленной базе придет в "рабочем" виде, без преобразования в строку?
29 buketovav
 
21.11.19
09:31
(28) да я вообще ни чего не решил, я же не докладываю, а спрашиваю. как сделать правильно, прошу подсказки
30 Darych
 
21.11.19
09:35
ФизЛицо = (?,НЕ ПустаяСсылка() = КомСоединение.Справочники.ФизическиеЛица.НайтиПоНаименованию(СтруктураДанных.Сотрудник), Ужене помнюкакпустуюссылку));
31 buketovav
 
21.11.19
09:36
(28) подскажите как это сделать правильно
32 SSSSS_AAAAA
 
21.11.19
09:49
(31) Объединить процитированные строки убрав из них локальную переменную.
33 SSSSS_AAAAA
 
21.11.19
09:51
(32) А еще лучше весь этот код работы с запросом поместить куда-то в удаленную базу и просто вызывать его через СОМ.
34 buketovav
 
21.11.19
09:52
(32)ЗапросВ.УстановитьПараметр("ФизическоеЛицо",КомСоединение.Справочники.ФизическиеЛица.НайтиПоНаименованию(СтруктураДанных.Сотрудник));

Так?
35 Darych
 
21.11.19
09:54
(34) не получится - скайп live:horsescoat
сам таким давно был, не стесняйся
36 SSSSS_AAAAA
 
21.11.19
09:56
(34) Примерно.
37 SSSSS_AAAAA
 
21.11.19
09:59
(34) Но дальше все равно передача результата из удаленной базы в локальный контекст:
"   com_Результат     = ЗапросВ.Выполнить();// COM объект     "
Потому и говорю, что надо все это оформить куском кода в той самой удаленной базе.
38 buketovav
 
21.11.19
09:59
чем дальше, тем страшнее - теперь получаю такую ошибку

{ОбщийМодуль.ДобавленныйОбщийМодульComСоединение.Модуль(90)}: Поле объекта не обнаружено (ЗаписьВРНФактическиеОтпуска)
    МенеджерДокумента = КомСоединение.Документы.ЗаписьВРНФактическиеОтпуска;
39 buketovav
 
21.11.19
10:01
(35) не находит ((( мой скайп buketov.av
40 SSSSS_AAAAA
 
21.11.19
10:05
(38) "МенеджерДокумента = КомСоединение.Документы.ЗаписьВРНФактическиеОтпуска;"
Ну так опять попытка ссылку на что-то внутри удаленной базы передать в локальный контекст... А передаваться так могут только строки и числа.
41 hhhh
 
21.11.19
10:24
(40) всё это нормально. Чего вы мутите?
42 buketovav
 
21.11.19
11:10
Заработало так:
Огромное спасибо за помощь Darych

//выбираем сотрудника
    ЗапросВ = КомСоединение.NewObject("Запрос");
    ЗапросВ.Текст = "
    |ВЫБРАТЬ первые 1
    |Сотрудники.Ссылка КАК Сотрудник
    |ИЗ
    |Справочник.Сотрудники КАК Сотрудники
    |ГДЕ
    |НЕ Сотрудники.СтруктураКомпании = ЗНАЧЕНИЕ(Справочник.СтруктураКомпании.ПустаяСсылка)
    |И Сотрудники.ФизическоеЛицо.Наименование = &ФизическоеЛицо
    |И Сотрудники.ПометкаУдаления = ЛОЖЬ
    |";
    
    ЗапросВ.УстановитьПараметр("ФизическоеЛицо", СтруктураДанных.Сотрудник.Наименование);
    
    com_Результат     = ЗапросВ.Выполнить().Выбрать(); // COM объект    
    Если com_Результат.следующий() Тогда
        //нашли сотрудника
        com_ТЗ_Сотрудники = com_Результат.Сотрудник; // COM объект
    Иначе
        //соответственно не нашли
        com_ТЗ_Сотрудники = Неопределено;
    КонецЕсли;
Я не хочу быть самым богатым человеком на кладбище. Засыпать с чувством, что за день я сделал какую-нибудь потрясающую вещь — вот что меня интересует. Стив Джобс