Вызов функций 1С с помощью Com-соединения

1. Fubbar 14.06.23 08:13 Сейчас в теме
Всем привет, пишу программу на яп python, очень нужно вызвать процедуру 1С с помощью com-соединения. Нужно написать что то на подобие вот такого (да, данные строки относятся именно к запросу, взял как пример):

name1 = getattr(v83.ОбновлениеИнформационнойБазыСлужебный,u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
            q = "ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()"
            query = v83.NewObject("Query", q)
            X = name1.Execute().Choose()


Нужно вызвать процедуру, которая экспортная и с внешним соединением. Помогите пожалуйста
По теме из базы знаний
Найденные решения
8. truba 14.06.23 10:00 Сейчас в теме
(5)
win32com.client.Dispatch("V83.COMConnector") --вот это коннектор к базам данных, Ком-объект может подключаться к разным БД, аналогия с подключением к разным SQL серверам через один драйвер.

Поключение = коннектор.Connect(строка подключения) - возвращает нам уже целевой объект работы с конкретной БД, указанной в строке подключения. Этот объект содержит все методы и данные этой БД.

Подлючение.Имя_чего_то_там - здесь то, что идет после точки будет анализироваться каким то менеджером имен глобального контекста - все объекты, доступные в глобальном контексте исполнения в среде 1СПредприятия. Как то - все общие модули, все менеджеры прикладных объектов и т.д. Т.е. у этого менеджера есть таблица соответствий имени и объекта, облсуживающего это имя. Объекты общих модулей доступны непосредственно в глобальном контексте по своему имени, а следовательно через Подключение.ИмяМоегоМодуля

Дальше у объектов общих модулей извне доступны только экспортные методы. Т.е. через Подключение.ИмяМоегоМодуля.ИмяМоегоМетода()

Тут грамматический вопрос - как компилятор Пайтона будет компилировать конструкцию метода написанного в его коде на код, принимаемый для анализа v83? Т.к. в общем случае у объектов 1С могут быть и данные и методы с одним и тем же именем и различаются они по наличию или отсутсвию () в конце.
Т.е. МойОбъект.МоиДанные - это реквизит, а МойОбъект.МоиДанные() - это метод.

давайте рассчитывать что пайтон придерживается таких же грамматических правил, тогда () в конце метода обязательно.
Далее ЗаписатьПодтверждениеЛегальностиПолученияОбновлений() - это процедура - она не возвращает ничего, поэтому вряд ли надо пытаться получить результат этого выполнения, но да, может сгенерировать исключение которое передаст на обработку объекту v83, а вот как уже с этим исключением коннектора будет дальше взаимодействовать пайтон, не знаю.

Если что пишите в личку, разберемся.
44. spacecraft 14.06.23 15:29 Сейчас в теме
(1) знаете, что самое интересное? Принципиально то все работает.
Создал расширение с общим модулем мод1 и там процедуру Мод2(), в которой вызывается:
ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()

В коде python:
import pythoncom
import win32com.client as win32


con_str = f'{place};Usr={Usr}'
pythoncom.CoInitialize()
V83 = win32.Dispatch("V83.COMConnector").Connect(con_str)
V83.мод1.Mod2()
Показать

И все отработало.
Единственное предположение, это длина наименования модуля и/или процедуры. Возможно просто отсекается и из-за этого не находится.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
11. spacecraft 14.06.23 10:38 Сейчас в теме
(1) с кодировкой могут быть проблемы.
Пробуйте так:
#coding=cp1251
...
v83module = getattr(V83, u"ОбновлениеИнформационнойБазыСлужебный")
v83method = getattr(v83module, u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
v83method()
13. Fubbar 14.06.23 10:41 Сейчас в теме
(11)
Строки просто прошли. Я убрал последнюю строку, так как не совсем понял, что в "param" записывать, ну и вроде как эта процедура без дополнительных параметров.
После выполнения в v83method осталось None
14. Fubbar 14.06.23 10:44 Сейчас в теме
(11)
При добавлении последней строчки "v83method()" выдал следующую ошибку "TypeError("'NoneType' object is not callable")"
15. spacecraft 14.06.23 10:46 Сейчас в теме
(14) выведите на print v83. Что там?
16. Fubbar 14.06.23 10:48 Сейчас в теме
(15)
Вывело просто "<COMObject Connect>"
17. spacecraft 14.06.23 11:04 Сейчас в теме
(16) приведите полный текст кода
18. Fubbar 14.06.23 11:05 Сейчас в теме
(17)
Некоторые написанные строки, просто попытки добиться нужного результата
con_str = f'{place};Usr={Usr};Pwd={Pwd};'
    out = {}
    global v83
    v83 = None
    # pythoncom.CoInitialize()
    v83 = win32com.client.Dispatch("V83.COMConnector")
    v83.Connect(con_str)
    try:
        try:
            print(v83.ТекущаяДата)
            v83.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()
            Modul = v83.Метаданные
            Model = Modul.ОбщиеМодули
            name1 = getattr(v83.ОбновлениеИнформационнойБазыСлужебный, u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
            q = "ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()"
            query = v83.NewObject("Query", q)
            X = name1.Execute
        except Exception as e:
            print(e)
            pass
        name = getattr(v83.ОбщегоНазначенияКлиентСервер, u"ИмяCOMСоединителя")
        name1 = getattr(v83.ОбновлениеИнформационнойБазыСлужебный, u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
        # getattr(v83.ОбновлениеИнформационнойБазы, u"ОбщегоНазначенияКлиентСервер.ВыполнитьОбновлениеИнформационнойБазы()")
        # getattr(v83.ОбновлениеИнформационнойБазыСлужебный, u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()")
        v83 = None
    except Exception as e:
        pass
Показать
19. spacecraft 14.06.23 11:11 Сейчас в теме
(18) накидали все что могли?
#coding=cp1251
import pythoncom
import win32com.client
con_str = f'{place};Usr={Usr};Pwd={Pwd};'
pythoncom.CoInitialize()
V83 = win32com.client.Dispatch("V83.COMConnector").Connect(con_str)
v83module = getattr(V83, u"ОбновлениеИнформационнойБазыСлужебный")
v83method = getattr(v83module, u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
v83method()
Показать
20. Fubbar 14.06.23 11:13 Сейчас в теме
(19)
pythoncom.CoInitialize()
V83 = win32com.client.Dispatch("V83.COMConnector").Connect(con_str)
v83module = getattr(V83, u"ОбновлениеИнформационнойБазыСлужебный")
v83method = getattr(v83module, u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
v83method()


К сожалению, данный код также выдал ошибку "TypeError("'NoneType' object is not callable")". Ошибка происходит на строке "v83method()"
21. spacecraft 14.06.23 11:18 Сейчас в теме
(20) попробуйте удалить префикс u.
v83module = getattr(V83, "ОбновлениеИнформационнойБазыСлужебный")
v83method = getattr(v83module, "ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
22. Fubbar 14.06.23 11:19 Сейчас в теме
(21)
Та же самая ошибка "TypeError("'NoneType' object is not callable")". Ничего нового, к сожалению
23. spacecraft 14.06.23 11:20 Сейчас в теме
(22) указание кодировки присутствует в самом верху кода?
#coding=cp1251
24. Fubbar 14.06.23 11:22 Сейчас в теме
(23)
В самом верху кода используются такие кодировки:
# -*- coding: cp1251 -*-
# -*- coding: utf8 -*-
25. spacecraft 14.06.23 11:23 Сейчас в теме
(24) издеваетесь?
Я привел полный код. Вот зачем что-то добавлять?
27. Fubbar 14.06.23 11:24 Сейчас в теме
(25)
Я прошу прощения!
Добавил Ваш код, ошибка та же, ничего не меняется. Разница моего и Вашего кода только в кодировке и всё.
30. truba 14.06.23 11:27 Сейчас в теме
(25) Вопрос не в кодировке, если сделаете запрос к атрибуту - все проходит. крашится на запросе к методу ком-объекта. Ощущение что у ком-объекта не существует методов, доступных конструкцией .ИмяМетода(аргументы). Ощущение, что их надо доставать другой грамматической конструкцией Ну, такая гипотеза.
А реквизиты достаются через Ком.МойРеквизит нормально
31. Fubbar 14.06.23 11:28 Сейчас в теме
(30)
Вот например подсчёт активных пользователей в системе и оно корректно работает.
con_str = f'{place};Usr={Usr};Pwd={Pwd};'
    out = {}
    global v83
    v83 = None
    pythoncom.CoInitialize()
    try:
        v83 = win32com.client.Dispatch("V83.COMConnector").Connect(con_str)
        Users = v83.GetInfoBaseConnections()
        CountUsr = Users.Count()
        countses = 0
        logs.Text("Информация об активных пользователях:" + "\n")
        for i in range(CountUsr):
            SesNum = getattr(Users[i], "SessionNumber").__int__()
            if SesNum > 0:
                countses += 1
            PCUs = getattr(Users[i], "User")
            logs.Text("Имя пользователя: " + getattr(PCUs, "Name"))
            logs.Text("Номер соединения: " + SesNum.__str__())
            logs.Text("Приложение: " + getattr(Users[i], "ApplicationName").__str__())
Показать
26. truba 14.06.23 11:24 Сейчас в теме
(15) Пока все атрибуты проходят удачно, а все методы not callable. Ощущение что вызов методов сом-объекта в питоне как то по другому происходит
28. spacecraft 14.06.23 11:25 Сейчас в теме
(26) проблема в том, что не находит по имени общий модуль.
29. Fubbar 14.06.23 11:26 Сейчас в теме
(28)
Кодировку исправил и работаю с той кодировкой, которую указали Вы, ошибки не поменялись. Как будто, можно предположить, что проблема не в кодировке
32. truba 14.06.23 11:29 Сейчас в теме
(28) У меня ощущение что на объект модуля выходит без проблем, а на вызове метода крэш.
Пример

Ком.Метаданные.Имя - норм
Ком.Метаданные.ЕстьИзмененияРасширениямиКонфигурации() - крэш. noncallable.

Хотя казалось бы.
33. Fubbar 14.06.23 11:32 Сейчас в теме
(32)
Да, но без скобочек
Ком.Метаданные.ЕстьИзмененияРасширениямиКонфигурации - отрабатывает, правда возвращает None, но сам факт

Достаточно странная ситуация 😅
34. truba 14.06.23 11:36 Сейчас в теме
ничего в питоне нет какого v83.Execute("Метаданные.ЕстьИзмененияРасширениямиКонфигурации",Парам) ?
35. Fubbar 14.06.23 11:39 Сейчас в теме
(34)
На конструкцию Execute выходит вот такая ошибка "AttributeError('Connect.Execute')"
36. truba 14.06.23 11:41 Сейчас в теме
(35)да я просто преположил, что вызов модулей происходит по другому, каким то методом Ком-объекта самого питона.
Т.е. допустим ком-объект в питоне это объект прежде всего в питоне и он возможно наследует методы объектов родителей питона и там что топодобное есть....
.Execute() это была импровизация)
37. Fubbar 14.06.23 11:43 Сейчас в теме
(36)
ну, да, я понимаю, но, я уже всё пытаюсь. Однако, Execute ведь используют в питоне для запросов и он там корректно отрабатывает, попытка б была неплохой)
38. truba 14.06.23 11:50 Сейчас в теме
(37)зафиксируем. Методы самого v83.AnyMethod() - доступны такой конструкцией
Атрибуты v83.AnyAttribute.AnyAttribute - тоже
методы v83.AnyAttribute.Method() - этой грамматической конструкцией вызывают ошибку, но не вызывают если v83.AnyAttribute.Method - но и не возвращают ничего.
39. Fubbar 14.06.23 11:51 Сейчас в теме
(38)
Получается так, да. Всё верно
40. truba 14.06.23 11:58 Сейчас в теме
(39)да вот нифига не так. т.к. v83.ТекущаяДата() - а этот метод v83
если попробовать v83.CurrentDate() ?
41. Fubbar 14.06.23 12:00 Сейчас в теме
(40)
CurrentDate()


Ошибка "AttributeError('Connect.CurrentDate')" и со скобочками и без
Строка: print(v83.CurrentDate())
42. truba 14.06.23 12:06 Сейчас в теме
(41) а если к тяжелой артиллерии: v83.ЗавершитьРаботуСистемы() v83.Exit() ?
43. Fubbar 14.06.23 13:04 Сейчас в теме
(42)
Соответствующие ошибки:
AttributeError('Connect.ЗавершитьРаботуСистемы')
AttributeError('Connect.Exit')
44. spacecraft 14.06.23 15:29 Сейчас в теме
(1) знаете, что самое интересное? Принципиально то все работает.
Создал расширение с общим модулем мод1 и там процедуру Мод2(), в которой вызывается:
ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()

В коде python:
import pythoncom
import win32com.client as win32


con_str = f'{place};Usr={Usr}'
pythoncom.CoInitialize()
V83 = win32.Dispatch("V83.COMConnector").Connect(con_str)
V83.мод1.Mod2()
Показать

И все отработало.
Единственное предположение, это длина наименования модуля и/или процедуры. Возможно просто отсекается и из-за этого не находится.
45. Fubbar 14.06.23 15:34 Сейчас в теме
(44)
Мы тоже пришли к некоторым выводам. По итогу создал пустую базу и там создал модуль и в нём процедуру. Результат таков, из питона кириллицей модуль вызывается, а вот метод уже нет. Метод вызывается только латиницей, а там символов уж точно не так много))))

Дак, а процедура у Вас Мод2 или Mod2. В коде латиница вы написали кириллицу.
46. spacecraft 14.06.23 15:41 Сейчас в теме
(45) да, возможно из-за этого.
Как выход, это создать расширение.
47. Fubbar 14.06.23 15:57 Сейчас в теме
(46)
Проблема в том, что данный скрипт должен работать автоматически с большим количеством баз и для каждой делать расширение, оно того не стоит. Я уже думал про внешнюю обработку, но там тоже не всё так просто, так как при открытие внешней обработки вылезает предупреждение безопасности, которое может отключить только пользователь, но никак не скрипт. Так что увы, внешняя обработка точно не подойдёт, да и расширение скорее всего также
48. RustamZz 14.06.23 16:09 Сейчас в теме
(47)
Так что увы, внешняя обработка точно не подойдёт
Прикрепленные файлы:
49. Fubbar 14.06.23 16:14 Сейчас в теме
(48)
Это вопрос к уровню доступа пользователей. А скрипт будет заходить под разными пользователями в разных ИБ. Данные настройка пользователей жёстко регламентированы и просто так разрешить выключить эту галочку для внешней обработки вряд ли кто-то позволит, увы. Остаётся довольствоваться тем, что есть, увы)
50. RustamZz 14.06.23 16:21 Сейчас в теме
(49) Тогда стоит поискать замену для вашего серпентария
51. Fubbar 14.06.23 16:22 Сейчас в теме
(50)
Хахах, пожалуй, в чём то Вы может быть правы
52. spacecraft 14.06.23 17:09 Сейчас в теме
(47) заменить python на что-то другое не вариант?
К примеру, на OneScript.
Там все должно отрабатывать правильно.
И код простой:
Соединитель = Новый COMОбъект("V83.COMConnector");
Соединение = Соединитель.connect(con_str);
Соединение.ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений();
53. Fubbar 15.06.23 07:54 Сейчас в теме
(52)
Заменить не получится, так как на python написана добрая часть остального скрипта.
2. truba 14.06.23 08:35 Сейчас в теме
За вызов функций общих модулей уж точно не объект "Query" отвечает, у него в конструктор поступает текст своего языка запросов 1С.
Не знаю что у вас за объект v83, но допустим это подключение и тогда ваш код будет примерно таким:
v83.ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений();
3. Fubbar 14.06.23 08:56 Сейчас в теме
(2)
v83.ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений();

Спасибо большое за помощь!
Да, V83 это коннектор. При выполнении вашего кода ошибка "TypeError("'NoneType' object is not callable")"
Ну и как я писал выше, предоставленный код в вопросе это просто пример)
4. truba 14.06.23 09:20 Сейчас в теме
(3)прошу прощения, нужен не коннектор, а подключение. Подключение получается через v83.Connect(строкаПодключения) емнип. а дальше уже с подключением к БД работаете с данными БД.
5. Fubbar 14.06.23 09:28 Сейчас в теме
(4)
е по

Ого, в таком случае, это многое меняет.
con_str = f'{place};Usr={Usr};Pwd={Pwd};'
    out = {}
    global v83
    v83 = None
    # pythoncom.CoInitialize()
    v83 = win32com.client.Dispatch("V83.COMConnector").Connect(con_str)
    try:
        try:
            n = v83.ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений
            Modul = v83.Метаданные
            Model = Modul.ОбщиеМодули
            name1 = getattr(v83.ОбновлениеИнформационнойБазыСлужебный,u"ЗаписатьПодтверждениеЛегальностиПолученияОбновлений")
            q = "ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()"
            query = v83(Model, q)
            X = n.Execute()
        except Exception as e:
Показать


Не могли бы помочь, что именно исправить и как, что бы оно работало, получается, просто убрать Connect(con_str)?
6. truba 14.06.23 09:44 Сейчас в теме
(5)Сам я так то штукатур и пайтон первый раз вижу, но в общем давай попробуем:

con_str = f'{place};Usr={Usr};Pwd={Pwd};'
out = {}
global v83
v83 = None
# pythoncom.CoInitialize()
v83 = win32com.client.Dispatch("V83.COMConnector").Connect(con_str)
try:
    v83.ОбновлениеИнформационнойБазыСлужебный.ЗаписатьПодтверждениеЛегальностиПолученияОбновлений()
     except Exception as e:
Показать
7. Fubbar 14.06.23 09:47 Сейчас в теме
(6)
Вот, если сделать так, как предложили Вы, будет ошибка, которую я описал выше "TypeError("'NoneType' object is not callable")"
Если сделать без скобочек, то оно просто проходит без каких либо изменений в самой базе
8. truba 14.06.23 10:00 Сейчас в теме
(5)
win32com.client.Dispatch("V83.COMConnector") --вот это коннектор к базам данных, Ком-объект может подключаться к разным БД, аналогия с подключением к разным SQL серверам через один драйвер.

Поключение = коннектор.Connect(строка подключения) - возвращает нам уже целевой объект работы с конкретной БД, указанной в строке подключения. Этот объект содержит все методы и данные этой БД.

Подлючение.Имя_чего_то_там - здесь то, что идет после точки будет анализироваться каким то менеджером имен глобального контекста - все объекты, доступные в глобальном контексте исполнения в среде 1СПредприятия. Как то - все общие модули, все менеджеры прикладных объектов и т.д. Т.е. у этого менеджера есть таблица соответствий имени и объекта, облсуживающего это имя. Объекты общих модулей доступны непосредственно в глобальном контексте по своему имени, а следовательно через Подключение.ИмяМоегоМодуля

Дальше у объектов общих модулей извне доступны только экспортные методы. Т.е. через Подключение.ИмяМоегоМодуля.ИмяМоегоМетода()

Тут грамматический вопрос - как компилятор Пайтона будет компилировать конструкцию метода написанного в его коде на код, принимаемый для анализа v83? Т.к. в общем случае у объектов 1С могут быть и данные и методы с одним и тем же именем и различаются они по наличию или отсутсвию () в конце.
Т.е. МойОбъект.МоиДанные - это реквизит, а МойОбъект.МоиДанные() - это метод.

давайте рассчитывать что пайтон придерживается таких же грамматических правил, тогда () в конце метода обязательно.
Далее ЗаписатьПодтверждениеЛегальностиПолученияОбновлений() - это процедура - она не возвращает ничего, поэтому вряд ли надо пытаться получить результат этого выполнения, но да, может сгенерировать исключение которое передаст на обработку объекту v83, а вот как уже с этим исключением коннектора будет дальше взаимодействовать пайтон, не знаю.

Если что пишите в личку, разберемся.
9. Fubbar 14.06.23 10:20 Сейчас в теме
(8)
К большому сожалению, почему то, не могу Вам написать в личный сообщения infostart. Просто нет необходимой кнопки ¯\_(ツ)_/¯
10. truba 14.06.23 10:36 Сейчас в теме
(9) Давайте экспериментировать
Что выдаст такой код:
print(v83.ТекущаяДата())
12. Fubbar 14.06.23 10:38 Сейчас в теме
(10)
Выдал ошибку "AttributeError('Connect.ТекущаяДата')"
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот