Python COM Interop - фабричный шаблон

1

У меня есть два класса python, оба из которых доступны для сценариев независимо от VBA с использованием механизмов взаимодействия COM. Но я хочу, чтобы кто-то контролировал создание другого, в шаблоне родительского ребенка или в шаблоне Factory.

Я экспериментировал, но не могу работать, я перешел на MCRE ниже. Я новичок в Python. Мне было интересно, возможно ли каким-то образом наследовать mixin, который даст классу необходимые методы взаимодействия COM.

Итак, я создал MCRE, вот код Python, который должен быть запущен хотя бы один из командной строки с правами администратора, чтобы получить регистрацию COM (после этого администратор не требуется).

import win32com.client


class MyParent(object):
    _reg_clsid_ = "{C61A7C6E-B657-4D55-AD36-8850B2E501AC}"
    _reg_progid_ = 'PythonInVBA.MyParent'
    _public_methods_ = ['Greet', 'GetChild']

    def __init__(self):  # Rules of Com say paramerless constructors
        self.child = MyChild()
        self.child.SetName("foo")

    def Greet(self):
        return "Hello world"

    def GetChild(self):
        return self.child


class MyChild(object):
    _reg_clsid_ = "{15DAAEE2-3A37-4DE1-9973-CCD011DF4888}"
    _reg_progid_ = 'PythonInVBA.MyChild'
    _public_methods_ = ['Initialize', 'GetName', 'SetName']

    def __init__(self):  # Rules of Com say paramerless constructors
        pass

    def GetName(self):
        return self.name

    def SetName(self, sName):
        self.name = sName

if __name__ == '__main__':
    print ("Registering COM servers...")
    import win32com.server.register
    win32com.server.register.UseCommandLine(MyParent)
    win32com.server.register.UseCommandLine(MyChild)

И вот код VBA, первые две процедуры Sub Procedures, но третий не удался.

Option Explicit

Sub Test_MyParent_OnItsOwn()
    On Error GoTo ErrHand:

    Dim objMyParent As Object
    Set objMyParent = VBA.CreateObject("PythonInVBA.MyParent")
    Debug.Assert objMyParent.Greet = "Hello world"
    Exit Sub
ErrHand:
    Debug.Print Err.Description
End Sub

Sub Test_MyChild_OnItsOwn()
    On Error GoTo ErrHand:

    Dim objMyChild As Object
    Set objMyChild = VBA.CreateObject("PythonInVBA.MyChild")

    objMyChild.SetName "Kevin"
    Debug.Assert objMyChild.GetName = "Kevin"
    ''' success MyChild is scriptable
    Exit Sub
ErrHand:
    Debug.Print Err.Description
End Sub


Sub Test_MyParent_Returning_MyChild()
    On Error GoTo ErrHand:

    Dim objMyParent As Object
    Set objMyParent = VBA.CreateObject("PythonInVBA.MyParent")

    Dim objMyChild As Object

    '* errors with Unexpected Python Error: TypeError: Objects of type 'MyChild' can not be converted to a COM VARIANT (but obtaining the buffer() of this object could)
    Set objMyChild = objMyParent.GetChild()

    Exit Sub
ErrHand:
    Debug.Print Err.Description
End Sub
  • 0
    после этого админ не требуется - зависит. Изменился ли класс или его участники с момента регистрации? Если порядок членов изменился, их DISPID изменился.
  • 0
    Мэтт (Кружка), ладно, продолжайте и всегда запускайте его под администратором, как я всегда делаю.
Показать ещё 6 комментариев
Теги:
excel-vba
com
com-interop

1 ответ

1
Лучший ответ

Я преобразовал содержимое комментария в ответ.

Это связано с тем, что MyChild не создается как COM-объект в MyParent.
Он будет работать, если вы измените его следующим образом.

оригинал:

    def __init__(self):  # Rules of Com say paramerless constructors
        self.child = MyChild()
        self.child.SetName("foo")

изменение:

    def __init__(self):  # Rules of Com say paramerless constructors
        self.child = win32com.client.Dispatch("PythonInVBA.MyChild")
        self.child.SetName("foo")
  • 0
    Фантастика. Большое спасибо.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню