0

I have a python module 'Cal.py' as below :

def Plus(a, b):
    a1 = int(a)
    b1 = int(b)
    result = a1 + b1
    return result

def Minus(a, b):
    a1 = int(a)
    b1 = int(b)
    result = a1 - b1
    return result

In Windows 10, I can call the functions with the arguments interactively from 'cmd.exe' :

D:\vb_python_SO>python
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import Cal
>>> Cal.Plus(2,3)
5
>>> Cal.Minus(5,3)
2
>>>

I would like to do exactly the same thing from Visual Basic 6. That is, function calling text from VB6 needs to be written after '>>>' and 'Return' key should be followed. But I could not find any nice solution yet.

I have tried the followings :

  • VB6 'Shell ("cmd /k python.exe")' can do the upper part but cannot proceed after '>>>'.
  • Writing a *.bat (or *.py) which also includes python function calling scripts. Executing it by Shell command can go further but functions cannot be called interactively, in which the arguments cannot be updated one after another from VB6 textbox.

Additional information)

My goal is to make a VB6 GUI program for calling Python functions. I need to control an instrument which measures certain characteristics of a sensor.

More specifically,

MyTester.py

def Init(_sensor_name='')
   #Sensor Initialization Process

def GetExposure()   
   #Read Present Exposure Time from Sensor Register

def SetExposure(Exposure_Time)
   #Write Exposure Time to Sensor Register

def FindExposure(...)

def MoveAbsolute(Rotation_Degee_A)
   #Rotate Table to Absolute Angle
 
def MoveRelative(Rotation_Degee_R)
   #Rotate Table by Relative Angle

def Roundtrip(...)

...

For now, function calls are performed at Python Shell interactively. It will become easier if I make a VB6 GUI program. Note that Init() function should be called at first and the other function calls follow.

KEH
  • 11
  • 2
  • Why do you need a program to put input into the interactive shell? I think you need to show what you are actually trying to accomplish. Doing it this way seems like an [XY Problem](https://xyproblem.info/). – C.Nivs Feb 19 '21 at 05:06
  • Thanks for your comment. I have made edits in my post to avoid the 'XY Problem'. See the 'Additional Information)' section to catch what exactly I would like to achieve. – KEH Feb 19 '21 at 07:41
  • You might want to have a look at the [SendKeys](https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/sendkeys-statement) method for sending keystrokes to the active window. That said, I do think this is quite awkward and maybe [creating a DLL](https://stackoverflow.com/questions/10859369/how-to-compile-a-python-package-to-a-dll) from your Python module and calling that from VB is a better way. Disclaimer: I don't know Python, so I can't tell how hard that is. – Hel O'Ween Feb 19 '21 at 13:48
  • I think maybe you want VB6 to call `python somescript.py `. That way you can get the dynamics you're looking for without having to inject into the shell. Your params might be something like `operation_type [args]` – C.Nivs Feb 19 '21 at 14:23
  • My appreciation goes to all the above comments. I think the "Sendkeys" method is the most proper solution to my case. To make a DLL is an elegant and grammatically correct way but it is quite complicated to implement. – KEH Feb 21 '21 at 05:50
  • As for calling a Python Script, it is doable as well. One problem in my appliciation is that Init() should be preceded before each function call, which causes a little inefficiency. Calling Python Script starts a new process so that Init() is lost in the beginning. – KEH Feb 21 '21 at 06:17

1 Answers1

1

I have tried "Sendkeys" method and find it works nicely for my purpose. A few tricks are added to get the integrity. Here are my codes :

''''''''''''''''
'Form1.frm     '
''''''''''''''''

Private Declare Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long)
'Declare for using sleep function'

Dim RetVal As Integer

Private Sub Command3_Click()
'Prepare to call the functions in python module'

    RetVal = Shell("cmd", vbNormalFocus)    'Call DOS Cmd window'
    Sleep (1000)                            'Allow time for Shell Execution'
    Sendkeys ("d:")
    Sendkeys ("{ENTER}")
    Sendkeys ("python")                     'Call Python Shell'
    Sendkeys ("{ENTER}")
    Sleep (1000)                            'Allow time for Python Execution'
    Sendkeys ("import Cal")                 'Import the Python Module'
    Sendkeys ("{ENTER}")
    
End Sub

Private Sub Command4_Click()
'Execute to call each function in python module'

    AppActivate (RetVal)                    
    'Re-Obtain the App Focus. RetVal is the ProcessID of the running DOS Cmd Window.'

    Sendkeys ("Cal.Plus" + "+9" + Text1.text + "," + Text2.text + "+0")
    ' Arguments come from Text1.txt and Text2.txt'
    ' "(" --> "+9" and ")" --> "=0" according the Sendkeys convention.'
    Sendkeys ("{ENTER}")
    
End Sub

''''''''''''''''''
' Module1.bas    '
''''''''''''''''''

Public Sub Sendkeys(text As Variant, Optional wait As Boolean = False)
'Replacing Sendkeys Sub to keep from the Error "Permission Denied".'
'This code overrides the existing Sendkeys.'

   Dim WshShell As Object
   Set WshShell = CreateObject("wscript.shell")
   WshShell.Sendkeys CStr(text), wait
   Set WshShell = Nothing


The above is just an example of simple algebra (Cal.py) but I believe the method will work for my real application.

KEH
  • 11
  • 2