Top > OOobbs2 > 79
** [[OOobbs2/79]] [#u4255223]
-''サマリ'': Py-UNO で Calc アドイン関数
-''環境'': Calc
-''状態'': 投稿
-''投稿者'': [[はにゃ?]]
-''投稿日'': 2007-10-17 (水) 14:31:59

*** 質問 [#bf1a5c2a]
Py-UNO では UNO コンポーネントを作成できるのでアドイン関数が作成できます (OOo Basic でも作成できますが)。


*** 回答 [#idd8c1bd]

必要なものは
-IDL ファイル
-Python-UNO コンポーネントファイル
-META-INF/manifest.xml

まず、関数の仕様を決めます (以下の使用はかなり適当なものです)。

-POWEROFNUMBER(number; value) 値の累乗を返します
-POWEROFTWO(Value) 2 の累乗を返します

引数および返り値は long 型にして整数のみとします。

次に、サービス名とインターフェース名を決めます。関数はインターフェースのメソッドとして実装し、そのインターフェースを備えたサービスを作成します。

-サービス名: mytools.sheet.addin.MyAddInFn
-インターフェース名: mytools.sheet.addin.XMyAddInFn

インターフェース名が決まれば、IDL ファイルを書きます。

-XMyAddInFn.idl
 #ifndef _MYTOOLS_SHEET_ADDIN_XMYADDINFN_IDL_
 #define _MYTOOLS_SHEET_ADDIN_XMYADDINFN_IDL_
 
 #include <com/sun/star/uno/XInterface.idl>
 
 module mytools {
 	module sheet {
 		module addin {
 			interface XMyAddInFn : com::sun::star::uno::XInterface
 			{
 				long powerOfTwo( [in] long nValue );
 				
 				long powerOfNumber( [in] long nValue, [in] long nNumber )
 			};
 		};
 	};
 };
 #endif

idlc と regmerge を使って rdb (uno typelibrary)ファイルを作成しておきます。

つぎに、Py-UNO コンポーネントを書きます。

アドイン関数のサービスは DevGuide によると以下のインターフェースが必要です。(XLocalizable は書かれていないが、無いと Calc がクラッシュします)
-実装するアドイン関数のインターフェース
-XAddIn
-XServiceName
-XServiceInfo
-XTypeProvider
-XLocalizable

XTypeProvider は unohelper.Base を継承してやれば実装してもらえます。

-MyAddInFn.py
 import uno
 import unohelper
 
 from mytools.sheet.addin import XMyAddInFn
 from com.sun.star.sheet import XAddIn
 from com.sun.star.lang import XLocalizable, XServiceName, XServiceInfo
 
 class MyAddInFn(unohelper.Base,XMyAddInFn,XAddIn,XLocalizable,XServiceName,XServiceInfo):
 	def __init__(self,ctx):
 		self.ctx = ctx
 		self.aAddInFnService = "mytools.sheet.addin.MyAddInFn"
 		self.aAddInService = "com.sun.star.sheet.AddIn"
 		self.aImplName = "MyAddInFn"
 		
 		self.aFunctionNames = ("powerOfTwo","powerOfNumber")
 		
 		self.aDisplayFunctionNames = {
 			self.aFunctionNames[0]: "PowerOfTwo", 
 			self.aFunctionNames[1]: "PowerOfNumber"}
 		
 		self.aArguments = {
 			self.aFunctionNames[0]: ("Value",),
 			self.aFunctionNames[1]: ("Number","Value")}
 		
 		self.FunctionDescriptions = {
 			self.aFunctionNames[0]: "The value power of two.", 
 			self.aFunctionNames[1]: "The value power of the number."}
 		
 		self.aArgumentsDescriptions = {
 			self.aFunctionNames[0]: ("The value power of two.",),
 			self.aFunctionNames[1]: ("The number is powered by the value.",
 				"The value power of the Number.")}
 		
 	
 	# XMyAddInFn
 	
 	def powerOfTwo(self,nValue):
 		return pow(2,nValue)
 	
 	# XMyAddInFn
 	
 	def powerOfNumber(self,nNumber,nValue):
 		return pow(nNumber,nValue)
 	
 	
 	# XAddIn
 	
 	def getProgrammaticFuntionName(self,aDisplayName):
 		for (aKey,aName) in self.aDisplayFunctionNames.iteritems():
 			if aName == aDisplayName:
 				return aKey
 		return ""
 	
 	def getDisplayFunctionName(self,aProgrammaticName):
 		if self.aDisplayFunctionNames.has_key(aProgrammaticName):
 			return self.aDisplayFunctionNames[aProgrammaticName]
 		return ""
 	
 	def getFunctionDescription(self,aProgrammaticName):
 		if self.FunctionDescriptions.has_key(aProgrammaticName):
 			return self.FunctionDescriptions[aProgrammaticName]
 		return ""
 	
 	def getDisplayArgumentName(self,aProgrammaticFunctionName,nArgument):
 		if self.aArguments.has_key(aProgrammaticFunctionName):
 			return self.aArguments[aProgrammaticFunctionName][nArgument]
 		return ""
 	
 	def getArgumentDescription(self,aProgrammaticFunctionName,nArgument):
 		if self.aArgumentsDescriptions.has_key(aProgrammaticFunctionName):
 			return self.aArgumentsDescriptions[aProgrammaticFunctionName][nArgument]
 		return ""
 	
 	def getProgrammaticCategoryName(self,aProgrammaticFunctionName):
 		return ("Add-In")
 	
 	def getDisplayCategoryName(self,aProgrammaticFunctionName):
 		return ("Add-In")
 	
 	
 	# XLocalizable
 	
 	def setLocale(self,eLocale):
 		pass
 	
 	def getLocale(self):
 		return uno.createUnoStruct("com.sun.star.lang.Locale")
 	
 	
 	# XServiceName
 	
 	def getServiceName(self):
 		return self.aAddInFnService
 	
 	
 	# XServiceInfo
 	
 	def getImplementationName(self):
 		return self.aImplName
 	
 	def supportsService(self,ServiceName):
 		return (ServiceName in (self.aAddInService,self.aAddInFnService))
 	
 	def getSupportedServiceNames(self):
 		return (self.aAddInFnService,self.aAddInService)
 
 
 
 g_ImplementationHelper = unohelper.ImplementationHelper()
 g_ImplementationHelper.addImplementation(
 	MyAddInFn,"mytools.sheet.addin.MyAddInFn",
 	("com.sun.star.sheet.AddIn",),)

META-INF/manifest.xml ファイルを作成します。
-META-INF/manifest.xml
 <?xml version="1.0" encoding="UTF-8"?>
 <manifest:manifest>
  <manifest:file-entry manifest:full-path="MyAddInFn.py" 
  manifest:media-type="application/vnd.sun.star.uno-component;type=Python"/>
  <manifest:file-entry manifest:full-path="MyAddInFn.rdb" 
  manifest:media-type="application/vnd.sun.star.uno-typelibrary;type=RDB"/>
 </manifest:manifest>

次のファイルから拡張機能パッケージを作成します。
 MyAddInFn.py
 MyAddInFn.rdb
 META-INF/manifest.xml
 (description.xml オプション)

パッケージを拡張機能マネージャからインストールした後、OOo を再起動します。

Add-In カテゴリに関数が追加されています。

&ref(PyFn.png,nolink);

パッケージ&ref(MyAddInFn.oxt); 入れる必要の無い idl ファイルも入っています。

#comment
*** 感想,コメント,メモ [#b0069e34]

#comment

Reload   New Lower page making Edit Freeze Diff Upload Copy Rename   Front page List of pages Search Recent changes Backup   Help   RSS of recent changes