Top > OOobbs3 > 73

** [[OOobbs3/73]] [#t16ad984]
-''サマリ'': OLEObjectのファイルからの挿入方法
-''環境'': Calc
-''状態'': 解決
-''投稿者'': [[Bebup]]
-''投稿日'': 2011-10-26 (水) 09:43:52
*** 質問 [#p3768853]
 OpenOffice.org3.2.1で開発を行っております。
 OLE Objectの挿入を OOoBasic/Calc/OLEObj を参考にして
 下記の様に作成しましたが、下記の oEmbDoc を 外部.odsファイルより
 loadする事はできますでしょうか。尚、LinkURL は試しましたが、
 この方法はその名の通り、外部リンクとなってしまいます。下記のごとく
 埋め込み型でリンクしたいと思っております。.odsファイルをloadして
 全てのSheetをコピーする方法しか無いのでしょうか。  

 Sub Main
 Dim oDoc As Object
 Dim oDrawPage As Object
 Dim oEmbCalc As Object
 Dim oEmbDoc As Object
 Dim aPosition As New com.sun.star.awt.Point
 Dim aSize As New com.sun.star.awt.Size
  oDoc = ThisComponent
  oDrawPage = oDoc.getDrawPages().getByIndex(0)
  oEmbCalc = oDoc.createInstance("com.sun.star.drawing.OLE2Shape")
  oDrawPage.add(oEmbCalc)
  aPosition.X = 100
  aPosition.Y = 100
  aSize.Width = 10000
  aSize.Height = 4000
  oEmbCalc.setPosition(aPosition)
  oEmbCalc.setSize(aSize)
  oEmbCalc.CLSID = "47bbb4cb-ce4c-4e80-a591-42d9ae74950f"
  oEmbDoc = oEmbCalc.Model
  'SpreadSheet内容設定
 End Sub
*** 回答 [#zcd8a200]
- アクセシビリティ API を使ったり、こっそり埋め込んだり・・・。

アクセシビリティ API では以下のような感じで行います。
#code(basic){{
Dim oListener As Variant
Dim oContWin As Variant
Dim sURL As String

Sub Main
  sURL = "file:///home/user/Desktop/data.ods"
  
  oDoc = ThisComponent
  oFrame = oDoc.getCurrentController().getFrame()
  oContWin = oFrame.getContainerWindow()
  
  oListener = CreateUnoListener(_
      "TopWindow_", "com.sun.star.awt.XTopWindowListener")
  oContWin.getToolkit().addTopWindowListener(oListener)
  
  dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
  dispatcher.executeDispatch(oFrame, ".uno:InsertObject", "", 0, Array())
End Sub


Sub Gonyagonya(oWin)
  Roles = com.sun.star.accessibility.AccessibleRole
  oAcc = oWin.getAccessibleContext()
  oAccRadio = FindAccChild(oAcc, Roles.RADIO_BUTTON, "Create from file")
  oAccRadio.setCurrentValue(1)
  oAccEdit = FindAccChild(oAcc, Roles.TEXT, "")
  oAccEdit.setText(sURL)
  oAccButton = FindAccChild(oAcc, Roles.PUSH_BUTTON, "OK")
  oAccButton.doAccessibleAction(0)
End Sub


Function TopWindow_disposing(ev)
End Function
Function TopWindow_windowOpened(ev)
  oContWin.getToolkit().removeTopWindowListener(oListener)
  Gonyagonya(ev.Source)
End Function
Function TopWindow_windowClosing(ev)
End Function
Function TopWindow_windowClosed(ev)
End Function
Function TopWindow_windowMinimized(ev)
End Function
Function TopWindow_windowNormalized(ev)
End Function
Function TopWindow_windowActivated(ev)
End Function
Function TopWindow_windowDeactivated(ev)
End Function


Function FindAccChild(oParent, nRole, sName)
  Dim oFound
  For i=0 to oParent.getAccessibleChildCount() -1 step 1
    oChild = oParent.getAccessibleChild(i)
    If HasUnoInterfaces(oChild, "com.sun.star.accessibility.XAccessible") Then
      oAcc = oChild.getAccessibleContext()
      If HasUnoInterfaces(oAcc, "com.sun.star.accessibility.XAccessibleComponent") Then
        If oAcc.getAccessibleRole() = nRole AND oAcc.getAccessibleName() = sName Then
          oFound = oAcc
          Exit For
        End If
      End If
    End If
  Next
  FindAccChild = oFound
End Function
}}

-- はにゃ? &new{2011-10-26 (水) 12:33:46};
- Calc のドキュメントを Calc 以外のドキュメントに挿入するのであれば、次のような方法もあります。Python で書いてありますが・・・。

#code(python){{
import unohelper
import uno
from com.sun.star.datatransfer import XTransferable, DataFlavor
class Trans(unohelper.Base, XTransferable):
	def __init__(self, ctx, url):
		self.ctx = ctx
		self.url = url
	
	def getTransferData(self, flavor):
		print("getdata")
		#print(flavor)
		if flavor.MimeType.startswith("application/x-openoffice-embed-source-xml"):
			try:
				sfa = self.ctx.getServiceManager().createInstanceWithContext(
					"com.sun.star.ucb.SimpleFileAccess", self.ctx)
				io = sfa.openFileRead(self.url)
				d, bytes = io.readBytes(None, 32000)
				return bytes
			except Exception as e:
				print(e)
		return ""
	
	def getTransferDataFlavors(self):
		print("get")
		mime = "application/x-openoffice-objectdescriptor-xml;" + \
			"windows_formatname=\"Star Object Descriptor (XML)\";" + \
			"classname=\"47BBB4CB-CE4C-4E80-a591-42d9ae74950f\";" + \
			"typename=\"calc8\";" + \
			"displayname=\"" + self.url + "\";" + \
			"viewaspect=\"1\";width=\"18066\";height=\"6379\";posx=\"0\";posy=\"0\""
		mime2 = "application/x-openoffice-embed-source-xml;" + \
				"windows_formatname=\"Star Embed Source (XML)\""
		f1 = DataFlavor(mime, "", uno.getTypeByName("[]byte"))
		f2 = DataFlavor(mime2, "", uno.getTypeByName("string"))
		return (f1, f2)
	
	def isDataFlavorSupported(self, flavor):
		return True

def try_to_paste(*args):
	url = "file:///home/asuka/Desktop/data.ods"
	ctx = XSCRIPTCONTEXT.getComponentContext()
	doc = XSCRIPTCONTEXT.getDocument()
	controller = doc.getCurrentController()#.getFrame()
	controller.insertTransferable(Trans(ctx, url))
}}
どちらかというと裏技なので詳しく説明しません。ヒントは [[OOoBasic/Generic/XTransferable]]。

-- はにゃ? &new{2011-10-26 (水) 20:58:29};

#comment
*** 感想,コメント,メモ [#tb45917b]
- はにゃさん 早速のご返答有難うございます -- BeBup 2011-10-26 (水) 14:09:35;
- ご教示頂いた方法は Window操作のAutomation方法だと思いますが、
この方法はリスナー、アクセシビリティ等の方法が入り、私にとっては
かなり難解となりますので、前述しました全シートのコピーの方法で
模索したいと思います。ただしこの様な方法も今後研究したいと思います。
今回は、ひとまずこの時点で解決とさせていただきます。
- はにゃさん 再度のご返答有難うございます。 -- BeBup &new{2011-10-29 (土) 22:41:26};
- このサイトの OOoBasic/Calc/Sheet/シートリンク 
よりヒントを得て全シートのコピーの方法で解決しました。
途中、EmbeddedCalcのCurrentControllerの取得で手間取りましたが、
XModel.setCurrentControllerの方法で解決しました。
目標達成と思いきや、今度はOLE2Shapeの外枠線(BorderLine)の
追加方法で悪戦苦闘中です。
また、お世話になるかも知れませんが宜しくお願いします。
 
- OLE 系の図形には外枠は設定できませんよ・・・。無理に枠線を引きたければ、図形描写オブジェクトを下に配置するなどの方法が必要です。 -- はにゃ? &new{2011-10-30 (日) 00:45:18};
- Excelもそのとうりでした。 -- BeBup &new{2011-10-31 (月) 15:51:15};

#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