在MS访问中,使用DDE从Python到VBA的响应

发布于 2025-01-26 17:09:52 字数 3349 浏览 5 评论 0原文

我需要将字符串从Python脚本传递到MS Access中运行的VBA应用程序。

从VBA到Python的沟通效果很好!

从Python到VBA的通信 - 不太好...

代码没有错误运行,但我只获得了响应的第一个字符。

例如:Python返回“ Joy” VBA只能获得“ J”,

请记住什么是如此令人沮丧的是,我可以将字符串从VBA发送到Python脚本是没问题的。

Python DDE服务器:

import win32ui
from pywin.mfc import object
import dde


class MySystemTopic(object.Object):
    def __init__(self):
        object.Object.__init__(self, dde.CreateServerSystemTopic())

    def Exec(self, cmd):
        print("System Topic asked to exec", cmd)


class recv_from_VBA_topic(object.Object):
    def __init__(self, topicName):
        object.Object.__init__(self, dde.CreateTopic(topicName))

    def Exec(self, cmd):
        print("recv_VBA_CMD asked to exec", cmd)
        # print('sending back responce: ' + 'Dave is really great!!!!')


class send_to_VBA_topic(object.Object):
    def __init__(self, topicName):
        topic = dde.CreateTopic(topicName)
        topic.AddItem(dde.CreateStringItem(""))
        object.Object.__init__(self, topic)

    def Request(self, aString):
        daLen = str(len(aString))
        print("send_to_VBA_topic Request Topic asked to compute length of:", aString, daLen)
        return(daLen + ' : ' + aString)


def main():
    server = dde.CreateServer()
    server.AddTopic(MySystemTopic())
    server.AddTopic(recv_from_VBA_topic("recv_VBA_CMD"))
    server.AddTopic(send_to_VBA_topic("send_to_VBA_topic"))
    server.Create('SDER_DDE')
    print('server: SDER_DDE\n Topic: recv_VBA_CMD\n Topic: send_to_VBA_topic\n')

    while 1:
        win32ui.PumpWaitingMessages(0, -1)


if __name__ == "__main__":
    main()

VBA代码:

Option Compare Database
Option Explicit

Public Function dde_send(Optional strIn As String) As String
Dim sRet As String
Dim Blp As Long
'Blp = DDEInitiate("RunAny", "RunAnyCommand")
Blp = DDEInitiate("SDER_DDE", "recv_VBA_CMD")

If Not IsNull(strIn) Then
    Call DDEExecute(Blp, strIn)
Else
    Call DDEExecute(Blp, "Greetings from VBA!")
End If

Call DDETerminate(Blp)
dde_send = sRet
End Function

Public Function dde_recv(Optional strIn As String) As String
Dim sRet As String
Dim Blp As Long

Dim vDDE As Variant, sDDE As String
Blp = DDEInitiate("SDER_DDE", "send_to_VBA_topic")
If Not IsNull(strIn) Then
'    vDDE = DDERequest(Blp, strIn)
    sDDE = DDERequest(Blp, strIn)
    Debug.Print sDDE
Else
    vDDE = DDERequest(Blp, "dde_recv test")
End If

DDETerminate (Blp)
dde_recv = sDDE
End Function

DDE_SEND工作 DDE_RECV仅获取第一个字符

注意:我使用此代码测试了Python服务器,并且可以从服务器接收正确的字符串。

import win32ui
import dde

#apparently "servers" talk to "servers"
server = dde.CreateServer()
#servers get names but I'm not sure what use this name
#has if you're acting like a client
server.Create("TestClient")
#use our server to start a conversation
conversation = dde.CreateConversation(server)

# RunAny is the server name, and RunAnyCommand is the topic
conversation.ConnectTo("SDER_DDE", "send_to_VBA_topic")
# DoSomething is the command to execute
# conversation.Exec("Dave is Great!")

# For my case I also needed the request function
# request somedata and save the response in requested_data.
try:
    requested_data = conversation.Request("somedata")
    print(requested_data)
except:
    print('conversation.Request: exception error')

I have a need to pass strings back forth from a python script to a VBA application running in MS Access.

Communication from VBA to Python works great!

Communication from Python to VBA - not so great great...

The code runs without error, but I only get the 1st character of the response.

EX: Python returns "Joy" VBA only gets "J"

Keep in mind what is so frustrating is I can send strings from VBA to the Python script is no problem.

The Python DDE server:

import win32ui
from pywin.mfc import object
import dde


class MySystemTopic(object.Object):
    def __init__(self):
        object.Object.__init__(self, dde.CreateServerSystemTopic())

    def Exec(self, cmd):
        print("System Topic asked to exec", cmd)


class recv_from_VBA_topic(object.Object):
    def __init__(self, topicName):
        object.Object.__init__(self, dde.CreateTopic(topicName))

    def Exec(self, cmd):
        print("recv_VBA_CMD asked to exec", cmd)
        # print('sending back responce: ' + 'Dave is really great!!!!')


class send_to_VBA_topic(object.Object):
    def __init__(self, topicName):
        topic = dde.CreateTopic(topicName)
        topic.AddItem(dde.CreateStringItem(""))
        object.Object.__init__(self, topic)

    def Request(self, aString):
        daLen = str(len(aString))
        print("send_to_VBA_topic Request Topic asked to compute length of:", aString, daLen)
        return(daLen + ' : ' + aString)


def main():
    server = dde.CreateServer()
    server.AddTopic(MySystemTopic())
    server.AddTopic(recv_from_VBA_topic("recv_VBA_CMD"))
    server.AddTopic(send_to_VBA_topic("send_to_VBA_topic"))
    server.Create('SDER_DDE')
    print('server: SDER_DDE\n Topic: recv_VBA_CMD\n Topic: send_to_VBA_topic\n')

    while 1:
        win32ui.PumpWaitingMessages(0, -1)


if __name__ == "__main__":
    main()

The VBA code:

Option Compare Database
Option Explicit

Public Function dde_send(Optional strIn As String) As String
Dim sRet As String
Dim Blp As Long
'Blp = DDEInitiate("RunAny", "RunAnyCommand")
Blp = DDEInitiate("SDER_DDE", "recv_VBA_CMD")

If Not IsNull(strIn) Then
    Call DDEExecute(Blp, strIn)
Else
    Call DDEExecute(Blp, "Greetings from VBA!")
End If

Call DDETerminate(Blp)
dde_send = sRet
End Function

Public Function dde_recv(Optional strIn As String) As String
Dim sRet As String
Dim Blp As Long

Dim vDDE As Variant, sDDE As String
Blp = DDEInitiate("SDER_DDE", "send_to_VBA_topic")
If Not IsNull(strIn) Then
'    vDDE = DDERequest(Blp, strIn)
    sDDE = DDERequest(Blp, strIn)
    Debug.Print sDDE
Else
    vDDE = DDERequest(Blp, "dde_recv test")
End If

DDETerminate (Blp)
dde_recv = sDDE
End Function

dde_send works
dde_recv only gets the 1st character

NOTE: I tested the Python server with this code and it works for receiving the correct string back from the server.

import win32ui
import dde

#apparently "servers" talk to "servers"
server = dde.CreateServer()
#servers get names but I'm not sure what use this name
#has if you're acting like a client
server.Create("TestClient")
#use our server to start a conversation
conversation = dde.CreateConversation(server)

# RunAny is the server name, and RunAnyCommand is the topic
conversation.ConnectTo("SDER_DDE", "send_to_VBA_topic")
# DoSomething is the command to execute
# conversation.Exec("Dave is Great!")

# For my case I also needed the request function
# request somedata and save the response in requested_data.
try:
    requested_data = conversation.Request("somedata")
    print(requested_data)
except:
    print('conversation.Request: exception error')

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文