リボン バーをエクセルするボタンを作成する pywin パッケージ デモを変更しました。ボタンが押されると、選択されたテキストがコマンドラインで実行され、選択されたテキストが出力に置き換えられます。
clsid とファイル名の組み合わせが異なるプログラムを登録すると問題が発生します。コードの clsid やファイル名を変更できません。このファイルのコピーを作成し、変更して登録すると、実行される COM オブジェクトは、新しく変更されたファイルではなく、元の excelAddin.py になります。COM 登録プロセスのステップが欠落しています。どの行をどこに追加すればよいですか?
from win32com import universal
from win32com.server.exception import COMException
from win32com.client import gencache, DispatchWithEvents
import winerror
import pythoncom
from win32com.client import constants, Dispatch
import sys
import win32traceutil
# Support for COM objects we use.
gencache.EnsureModule('{00020813-0000-0000-C000-000000000046}', 0, 1, 3, bForDemand=True) # Excel 9
gencache.EnsureModule('{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}', 0, 2, 1, bForDemand=True) # Office 9
# The TLB defiining the interfaces we implement
universal.RegisterInterfaces('{AC0714F2-3D04-11D1-AE7D-00A0C90F26F4}', 0, 1, 0, ["_IDTExtensibility2"])
class ButtonEvent:
def OnClick(self, button, cancel):
import win32ui # Possible, but not necessary, to use a Pythonwin GUI
import win32con
import subprocess
app = Dispatch("Word.Application")
cmd = app.Selection
#subprocess.Popen(str(cmd))
cmdP = subprocess.Popen(str(cmd), shell = True, stdout = subprocess.PIPE)
txt = cmdP.stdout.readlines()
output = ''
for line in txt:
output += line
app.Selection.TypeText(output)
#win32ui.MessageBox(txt, "Python Test",win32con.MB_OKCANCEL)
return cancel
class ExcelAddin:
_com_interfaces_ = ['_IDTExtensibility2']
_public_methods_ = []
_reg_clsctx_ = pythoncom.CLSCTX_INPROC_SERVER
#_reg_clsid_ = ""
_reg_clsid_ = "{C5482ECA-F559-45A0-B078-B2036E6F011A}"
#_reg_clsid_ = "{E44EF798-7FDF-4015-AED6-00234CBBBA77}"
#_reg_clsid_ = "{91A89B71-56C0-4a76-BF1F-CF52E3671740}"
_reg_progid_ = 'Juha.test'#"Python.Test.ExcelAddin2"
_reg_policy_spec_ = "win32com.server.policy.EventHandlerPolicy"
def __init__(self):
self.appHostApp = None
def OnConnection(self, application, connectMode, addin, custom):
print "OnConnection", application, connectMode, addin, custom
try:
self.appHostApp = application
cbcMyBar = self.appHostApp.CommandBars.Add(Name="PythonBar",
Position=constants.msoBarTop,
MenuBar=constants.msoBarTypeNormal,
Temporary=True)
btnMyButton = cbcMyBar.Controls.Add(Type=constants.msoControlButton, Parameter="Greetings")
btnMyButton=self.toolbarButton = DispatchWithEvents(btnMyButton, ButtonEvent)
btnMyButton.Style = constants.msoButtonCaption
btnMyButton.BeginGroup = True
btnMyButton.Caption = "&Run..."
btnMyButton.TooltipText = "Runs the selected text in command line"
btnMyButton.Width = "34"
cbcMyBar.Visible = True
except pythoncom.com_error, (hr, msg, exc, arg):
print "The Excel call failed with code %d: %s" % (hr, msg)
if exc is None:
print "There is no extended error information"
else:
wcode, source, text, helpFile, helpId, scode = exc
print "The source of the error is", source
print "The error message is", text
print "More info can be found in %s (id=%d)" % (helpFile, helpId)
def OnDisconnection(self, mode, custom):
print "OnDisconnection"
self.appHostApp.CommandBars("PythonBar").Delete
self.appHostApp=None
def OnAddInsUpdate(self, custom):
print "OnAddInsUpdate", custom
def OnStartupComplete(self, custom):
print "OnStartupComplete", custom
def OnBeginShutdown(self, custom):
print "OnBeginShutdown", custom
def RegisterAddin(klass):
import _winreg
key = _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Word\\Addins")
#key = _winreg.CreateKey(_winreg.HKEY_LOCAL_MACHINE, "Software\\Classes\\CLSID")
subkey = _winreg.CreateKey(key, klass._reg_progid_)
_winreg.SetValueEx(subkey, "CommandLineSafe", 0, _winreg.REG_DWORD, 0)
_winreg.SetValueEx(subkey, "LoadBehavior", 0, _winreg.REG_DWORD, 3)
_winreg.SetValueEx(subkey, "Description", 0, _winreg.REG_SZ, "Runs selection in command line and pastes output")
_winreg.SetValueEx(subkey, "FriendlyName", 0, _winreg.REG_SZ, "cmdlineRunner")
def UnregisterAddin(klass):
import _winreg
try:
_winreg.DeleteKey(_winreg.HKEY_CURRENT_USER, "Software\\Microsoft\\Office\\Word\\Addins\\" + klass._reg_progid_)
except WindowsError:
pass
if __name__ == '__main__':
import win32com.server.register
win32com.server.register.UseCommandLine(ExcelAddin)
if "--unregister" in sys.argv:
UnregisterAddin(ExcelAddin)
else:
RegisterAddin(ExcelAddin)