2016-12-15 3 views
2

J'essaye de passer la variable Nothing dans VBA en utilisant le win32com de Python. J'ai essayé d'utiliser None mais il a renvoyé 'Type dismatch'.Passez la variable `Nothing` en utilisant` win32com` de Python

Pourriez-vous nous aider s'il vous plaît?

Merci!

Un exemple:

' Book1.xlsm!Module1 
Function test(arg As Object) As String 
    If arg Is Nothing Then 
     test = "Success" 
     Exit Function 
    Else 
     test = "Failure" 
     Exit Function 
    End If 

End Function 

Et en Python:

import win32com.client 
import os 
import pythoncom 


xl = win32com.client.Dispatch('Excel.Application') 
xl.Visible = True 
xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm')) 
test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty) 

Le REPL dit:

runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads') 
Traceback (most recent call last): 

    File "<ipython-input-22-301693920f2c>", line 1, in <module> 
    runfile('C:/Users/shwang/Downloads/untitled0.py', wdir='C:/Users/shwang/Downloads') 

    File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 866, in runfile 
    execfile(filename, namespace) 

    File "C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py", line 102, in execfile 
    exec(compile(f.read(), filename, 'exec'), namespace) 

    File "C:/Users/shwang/Downloads/untitled0.py", line 16, in <module> 
    test_str = xl.Application.Run('Book1.xlsm!Module1.test', pythoncom.Empty) 

    File "<COMObject <unknown>>", line 14, in Run 

    File "C:\Anaconda3\lib\site-packages\win32com\client\dynamic.py", line 287, in _ApplyTypes_ 
    result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args) 

com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147352561), None) 
+0

Avez-vous réussi 'None' ou' 'None''? –

+0

Vous pourriez utiliser 'pythoncom.Empty'. Voir [ce message] (https://mail.python.org/pipermail/python-win32/2009-February/008826.html) –

+0

Aussi http://www.programcreek.com/python/example/36145/pythoncom. Missing –

Répondre

1

Dans VBA, Nothing est utilisé comme valeur par défaut uninitialized pour seulement deux types: Object ou Variant qui fait généralement référence COM objets (c'est-à-dire, bibliothèque d'objets Excel ou bibliothèque d'objets de l'application externe). La valeur Nothing ne peut pas être affectée à l'entier primitif, à la longueur et aux types de chaîne de VBA. Et habituellement les programmeurs l'utilisent à la fin du bloc de code pour libérer des objets de la mémoire.

Par conséquent, il n'y a pas de traduction stricte entre Nothing de VBA (une valeur spéciale pour les types COM) et les types de valeurs de Python, y compris None ce qui signifie crûment valeur vide ou non pour tout type. Cela dit, votre code ne sera pas errer si vous passez un objet COM que vous avez déjà initialisé avec xl. Ci-dessous les sorties FAILURE. Si d'une façon ou d'une autre vous pouvez déclarer un objet COM non initialisé qui portera ensuite Nothing alors vous pouvez passer cela dans votre fonction. Mais appeler Dispatch nécessite un objet nommé. Catch-22!

import win32com.client 
import os 

try: 
    xl = win32com.client.Dispatch('Excel.Application') 
    xl.Visible = True 

    wb = xl.Workbooks.Open(Filename=os.path.abspath('Book1.xlsm')) 
    test_str = xl.Application.Run('test', xl) 
    print(test_str) 
    # FAILURE 

    wb.Close(False) 
    xl.Quit 

except Exception as e: 
    print(e) 

finally: 
    wb = None 
    xl = None 
+0

Merci Parfait! Je vois la logique là-bas. Dommage que j'utilise l'API SolidWorks (un logiciel de CAO 3D) qui nécessite 'Nothing' comme argument d'entrée à certaines fins. Je suppose que je peux l'envelopper avec le code VBA et appeler l'emballage à la place quand 'Nothing 'est nécessaire - pas joli mais faisable. Merci encore! –