1

特定の問題で立ち往生しています。私は、VBA API を使用して MS Access データベース (.mdb) からデータを読み取り、tkintertable モジュールを使用して GUI テーブルに表示する Python スクリプトに取り組んでいます。

問題は、スクリプトが終了した後、MSACCESS.exe プロセスがプロセス リストに残っていることです。

ルート ウィンドウの mainloop() メソッドにコメントすると、問題はなくなります。

access.quit() を明示的に呼び出しても問題は解決しません。さらに悪いことに、スクリプトは終了しますが、MS Access プロセスが表示されます。ウィンドウが表示されますが、ウィンドウがどんどん表示されるため、閉じることができません。

問題を特定するために、コードから不要な行をすべて削除しました。

#!C:\Python343\python
from comtypes.client import CreateObject
from tkinter import *

access = CreateObject('Access.Application')

root = Tk()
root.mainloop() # if I comment this line, everything works
# access.quit() - does not help: MS Access window gets visible and immortal
#

なぜこれが起こるのか、何か手がかりを与えることができますか? アドバイスをよろしくお願いします。

Python バージョン: 3.4.3。MS オフィス: 2013.

4

1 に答える 1

0

残念ながら、pypyodbc や他のパッケージに切り替えることはできません。スクリプトが大きく、再設計するのが不便だからです。現在、VBA API (OpenRecordSet、MoveFirst、MoveLast メソッドなど) を使用していますが、pypyodbc はこの API AFAIK をミラーリングしていません。

ここで、回避策 (MSACCESS.EXE アプリケーションの強制終了) を使用します。ここに投稿します。おそらく、同じ問題で立ち往生している人に役立つでしょう:

def close_by_force(app): # Took this function from https://stackoverflow.com/
    # questions/10221150/cant-close-excel-completely-using-win32com-on-python,  
    # but had to redesign it to be usable to work with COM objects

import win32process
import win32gui
import win32api
import win32con

# Get the window's process id's
hwnd = app.hWndAccessApp()
t, p = win32process.GetWindowThreadProcessId(hwnd)
# Ask window nicely to close
win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
# Allow some time for app to close
time.sleep(10) # not really necessary
# If the application didn't close, force close
try:
    #print('pid='+str(p))
    handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, p)
    if handle:
        win32api.TerminateProcess(handle, 0)
        win32api.CloseHandle(handle)
except:
    pass

...
access = CreateObject('Access.Application')
DBEngine = access.DBEngine
db = DBEngine.OpenDatabase("C:\<my_db_path>")
.... some code (working with the database) ...
close_by_force(access.Application) # this is the crucial line

Web で見つけたように、この問題は古い問題であり、さまざまなトピックで議論されていましたが、正確な解決策はどこにもありません。たとえば、次のようになります。

http://www.xtremebbtalk.com/showthread.php?t=298607

C# では、実行中のスレッド ( Access DB ) を閉じるにはどうすればよいですか?

http://python-list.python.narkive.com/gCMlrB8M/using-excel-with-python

System.Runtime.InteropServices.Marshal.ReleaseComObject(access) のようなものを使用できることもわかりましたが、これらのクラスを使用するための関連する Python パッケージを入手できるリンクが見つかりません。

--

敬具、

アレクサンダー。

于 2015-04-23T00:04:49.807 に答える