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')