9

I would like to convert dozens of excel sheets to csv files at once. I have a working .vbs file which makes the conversion, and I would like to execute this .vbs file on the different sheets with the help of a python code. I have the following 2 versions of the python code:

Version 1:

import os
import sys
import subprocess

FolderName=sys.argv[1]
FileList=os.listdir(FolderName)
NewList=[]

for i in FileList:
   NewItem=i.split('.xls')
   NewXls=FolderName+"\\"+NewItem[0]+".xlsx "
   NewCsv=FolderName+"\\"+NewItem[0]+".csv"
   NewCommand="C:\\Users\\user\\XlsToCsv.vbs "+sys.argv[2]+" "+NewXls+NewCsv
   subprocess.call(NewCommand)

Version 2:

import os
import sys
import subprocess

def main(directory,extension,sheet):
 for filename in os.listdir(directory):
    if filename.endswith(extension):
        path = os.path.join(directory, filename)
        base = os.path.join(directory, filename[:len(filename)-len(extension)])
        print base
        new_xls = base + extension
        new_csv = base + '.csv'
        subprocess.call(['C:\\Users\\user\\XlsToCsv.vbs', sheet, new_xls, new_csv])

main(sys.argv[1],sys.argv[2],sys.argv[3])

It does not matter, which I try, I get the same error message:

 Traceback (most recent call last):
   File "C:/Users/user/Desktop/Work/XlsDir.py", line 16, in <module>
     subprocess.call(NewCommand)
   File "C:\Python27\lib\subprocess.py", line 524, in call
     return Popen(*popenargs, **kwargs).wait()
   File "C:\Python27\lib\subprocess.py", line 711, in __init__
     errread, errwrite)
   File "C:\Python27\lib\subprocess.py", line 948, in _execute_child
     startupinfo)
   WindowsError: [Error 193] %1 er ikke et gyldigt Win32-program

The last line of the error message means approximately, that it is not a valid Win32-program.

What I have tried so far:

  • If I run the .vbs file from command prompt with the right arguments (sheet, name of the .xls file and name of the .csv file) then it works fine.
  • If I print the commands that python generates and copy them into command prompt, they work fine.
  • I tried every combinations of '\' and '\' within the different paths, and nothing got any better.
  • I tried to execute the programs with replacing the sys.argv[i] arguments with specific arguments and then execute the .py file from command prompt. I get the same error message.

I hope some of you can help me. Thanks a lot!

Rieux
  • 103
  • 1
  • 1
  • 5
  • :-) I found the solution after two days. :-) I do not delete my question, perhaps others will need it. You have to add "wscript.exe " to the subprocess.call argument... 'NewCommand="wscript.exe C:\\Users\\user\\XlsToCsv.vbs "+sys.argv[2]+" "+NewXls+NewCsv" – Rieux Oct 01 '13 at 10:34
  • Did you try to use different way of running you command like using `os.system`? Additionally you can look there: http://stackoverflow.com/questions/5538671/python-call-to-external-program-results-in-error-193-1-is-not-a-valid-win32-a probably it can help you. – user2725093 Oct 01 '13 at 10:38

2 Answers2

18

To elaborate on Ansgar's remedy:

Starting a .vbs from the command line 'works', because the shell associates the extension .vbs with an application (e.g. cscript/wscript; see ftype, assoc, cscript //E, cescript //S).

subprocess.call() does not open a shell, so either specify the application (c|wscript.exe) or start the shell yourself:

import subprocess

#subprocess.call("notepad") # works

#subprocess.call("dir") # [Error 2] The system cannot find the file specified
                        # no shell, no intrinsics

#subprocess.call("19112944.vbs") # [Error 193] %1 is not a valid Win32 application
                                 # no shell, can't associate .vbs with c|wscript.exe

subprocess.call("cscript 19112944.vbs") # works

subprocess.call("cmd /c 19112944.vbs") # works
                                       # have shell, can associate .vbs with c|wscript.exe
Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96
  • Thanks a lot Ekkehard, this was exactly the answer I wanted to get. – Rieux Oct 01 '13 at 11:24
  • Is there a way of executing a vbs file with arguments created by python outside of a command line interface? – Mitrek Dec 03 '17 at 17:33
  • In theory you can use comtypes (https://pypi.python.org/pypi/comtypes) to .CreateObject() a MSScriptControl (https://msdn.microsoft.com/en-us/library/aa227633(v=vs.60).aspx); .AddCode some VBScript code and .Run it with arguments. In practice it won't work: no download, no support, 32 bit only. – Ekkehard.Horner Dec 04 '17 at 09:49
9

Try running the script with cscript.exe:

subprocess.call(['cscript.exe', 'C:\\Users\\user\\XlsToCsv.vbs', sheet, new_xls, new_csv])
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328