libreoffice basic宏

文章详细介绍了LibreOffice中宏的概念,包括宏的组织结构、使用的编程语言(如Basic)、编写宏的步骤以及宏的存储位置。提到了两种编写宏的方法,一种是使用dispatcher,另一种是直接使用UNO服务,并提供了相应的代码示例。此外,还阐述了如何运行和调试宏。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(一)宏是什么

宏就是函数。

宏可以按库容器、库、模块、宏四级组织
库容器就是一个文件夹。里面有多个库。
库也是文件夹。里面有多个模块。
模块是单个文件。里面有多个宏。
宏是模块中的单个函数。

(二)用什么语言写宏

LibreOffice API支持Basic、Java、C/C++、Javascript、Python语言。
我选择用basic语言写宏。
LibreOffice Basic语言是专门为LibreOffice开发的,并集成到Office软件包中。顾名思义,LibreOffice Basic是Basic系列的一种编程语言。使用过其他Basic语言的人 - 特别是Microsoft的Visual Basic或Visual Basic for Applications(VBA) - 都会很快习惯LibreOffice Basic。LibreOffice Basic的大部分基本结构都与Visual Basic兼容。

(三)在哪写宏

宏的位置有三个,这三个位置就是三个库容器:
1.我的宏
用户目录下
~/.config/libreoffice/4/user/basic
2.应用程序的宏
系统目录下
/usr/lib64/libreoffice/share/basic
3.文档中的宏
保存在文档中。文档实际上是个压缩包,可以用unzip解压。

菜单栏点击“工具-宏-编辑宏”,进入编辑器
点击编辑器工具栏的“模块”,进入管理器
在管理器里,就可以在上述三个位置新建文件。

新建的文件名后缀是.xba

(四)怎么写宏

参考教程
https://wiki.openoffice.org/wiki/ZH/Documentation/BASIC_Guide
https://wiki.documentfoundation.org/Documentation/BASIC_Guide
https://help.libreoffice.org/latest/zh-CN/text/sbasic/shared/main0601.html?DbPAR=BASIC

分四步:
1.了解libreoffice basic语言。参考之前的文章:libreoffice basic语言
2.了解标准库。就是不直接引用LibreOffice api的标准函数,例如处理数字、字符串、日期值的函数。参考之前的文章:libreoffice basic库函数
3.了解LibreOffice API。允许访问LibreOffice文档,并允许创建、保存、修改和打印这些文档。参考之前的文章:libreoffice api
4.对话框编辑器:创建个人对话框窗口,并提供添加控件元素和事件处理程序的范围。

(五)写宏步骤:

有两种写宏的方法:

1.一种是使用dispatcher

这种方法通常先做宏录制。宏录制就是记录用户的一系列操作。LibreOffice使用LibreOffice Basic语言保存录制的宏。之后再在此基础上编辑宏。
确保启用宏录制,方法是转到工具>选项>LibreOffice >高级,选择“可选功能”下的“启用宏录制”选项。默认情况下,此功能在LibreOffice中处于关闭状态。
1)转到 工具 >宏 > 录制宏 开始录制宏。将显示一个带有“停止录制”按钮的小对话框,指示LibreOffice正在录制宏。
2) 键入运行此宏时要输入的所需文本。例如,键入您的姓名。
3)点击 停止录制 在小对话框中。这将导致“宏”对话框打开。
4) 打开我的宏。
5) 在“我的宏”中找到名为“标准”的库。
6) 选择“标准”库,然后选择一个模块。或者,您可以单击“新建模块”创建一个新模块
7) 在对话框中左上角的宏名称文本框中,键入名称EnterMyName
8) 单击“保存”以保存宏并关闭“宏”对话框。
如果执行了上述所有步骤,则会在所选模块中创建一个名为 EnterMyName 的宏。

使用dispatcher,不需要了解不同服务和接口。dispatcher使用诸如“uno:Undo”的命令处理文档。为简单起见,请将调度视为点击菜单中的动作。

组件(文档)的功能分为模型、控制器和框架。
框架
它包含一个模型的控制器,并知道所有关于窗口的信息。框架没有任何窗口的功能,框架只知道窗口存在。就相当于文档与窗口的中介。
向框架发送调度,因为它控制事物并知道如何路由调度。
模型
由文档数据和更改数据的方法组成。
您可以使用模型直接更新数据。
控制器
了解当前视图和数据;它接收输入然后操作文档。
控制器知道选择了什么,并且能够选择什么。

组件几乎总是指打开的文档,但其他窗口也是组件。例如,IDE和帮助窗口。

DispatchHelper是负责调度命令的服务。
oDispHelper = createUnoService(“com.sun.star.frame.DispatchHelper”)
它的executeDispatch函数负责调度命令,executeDispatch方法的参数如下
XDispatchProvider 执行调度的调度提供程序。
URL String 要调度的命令,以字符串形式。
target Frame String 接收调度的框架。使用空字符串或“_self”指定 当前框架(任何其他值无效)。
long 指示如何查找目标框架的可选搜索标志。使用零或空白
PropertyValue() 可选参数。

示例

oProvider = ThisComponent.CurrentController.Frame
oDispHelper = createUnoService("com.sun.star.frame.DispatchHelper") 
oDispHelper.executeDispatch(oProvider,".uno:Undo", "", , Array()) 

Dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "ToPoint"
args2(0).Value = "$B$3" ' position to B3
oProvider = ThisComponent.CurrentController.Frame
oDispHelper = createUnoService("com.sun.star.frame.DispatchHelper") 
oDispHelper.executeDispatch(oProvider, ".uno:GoToCell", "", 0, args2())

查找调度命令
http://wiki.services.openoffice.org/wiki/Framework/Article/OpenOffice.org_3.x_Commands 包含一个命令列表。

使用UICommandDescription服务来枚举支持的模块。创建一个新的Calc文档并为每个模块创建一个工作表。模块支持的命令放置在工作表上。

Sub Print_All_Commands
	oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_default", 0, Array())
	oSheets = oDoc.getSheets()
	oUICommandDescription = CreateUnoService("com.sun.star.frame.UICommandDescription")
	oModuleIdentifier = CreateUnoService("com.sun.star.frame.ModuleManager")
	aModules = oModuleIdentifier.getElementNames()
	For n = 0 To UBound(aModules)
		oModuleUICommandDescription = oUICommandDescription.getByName(aModules(n))
		aCommands = oModuleUICommandDescription.getElementNames()
		If n <= UBound(oSheets.getElementNames()) Then
			oSheets.getByIndex(n).setName(aModules(n))
		Else
			oSheets.insertNewByName(aModules(n),n)
		End If
		oSheets.getCellByPosition(0, 0, n).getText().setString("Command") 
		oSheets.getCellByPosition(1, 0, n).getText().setString("Label")
		oSheets.getCellByPosition(2, 0, n).getText().setString("Name")
		oSheets.getCellByPosition(3, 0, n).getText().setString("Popup")
		oSheets.getCellByPosition(4, 0, n).getText().setString("Property")
		For i = 0 To UBound(aCommands)
			aCommand = oModuleUICommandDescription.getByName(aCommands(i))
			For k = 0 To UBound(aCommand)
				If aCommand(k).Name = "Label" Then
					sLabel = aCommand(k).Value
				ElseIf aCommand(k).Name = "Name" Then
					sName = aCommand(k).Value
				ElseIf aCommand(k).Name = "Popup" Then
					bPopup = aCommand(k).Value
				ElseIf aCommand(k).Name = "Property" Then
					nProperty = aCommand(k).Value
				End If
			Next
			oSheets.getCellByPosition(0, i+1, n).getText().setString(aCommands(i))
			oSheets.getCellByPosition(1, i+1, n).getText().setString(sLabel)
			oSheets.getCellByPosition(2, i+1, n).getText().setString(sName)
			If bPopup Then
				oSheets.getCellByPosition(3, i+1, n).getText().setString("True")
			Else
				oSheets.getCellByPosition(3, i+1, n).getText().setString("False")
			End If
			oSheets.getCellByPosition(4, i+1, n).getText().setString(CStr(nProperty))
		Next
		oColumns = oSheets.getByIndex(n).getColumns()
		For j = 0 To 4
			oColumns.getByIndex(j).setPropertyValue("OptimalWidth", True)
		Next
	Next
End Sub

XDispatchInformationProvider从当前控制器返回调度命令的列表

Sub printcommands
	oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_default", 0, Array())
	oSheet = oDoc.getSheets().getByIndex(0)
	oSheet.getCellByPosition(0, 0).getText().setString("Group")
	oSheet.getCellByPosition(1, 0).getText().setString("Command")
	oController = ThisComponent.getCurrentController()
	If IsNull(oController) Or NOT HasUnoInterfaces( oController, "com.sun.star.frame.XDispatchInformationProvider") Then
		Exit Sub
	End If
	k=0
	iSupportedCmdGroups = oController.getSupportedCommandGroups()
	For i = 0 To UBound(iSupportedCmdGroups) 
		aDispatchInfo = 	oController.getConfigurableDispatchInformation(iSupportedCmdGroups(i))
		For j = 0 To UBound(aDispatchInfo) 
			aDispatchInformation = aDispatchInfo(j)
			k = k + 1
			oSheet.getCellByPosition(0, k).getText().setString(iSupportedCmdGroups(i)) 			
			oSheet.getCellByPosition(1, k).getText().setString(aDispatchInformation.Command)
		Next
	Next
End Sub

Dispatch命令名称区分大小写。

使用调度程序编写宏
某些组件不支持宏记录器,例如,Draw。
宏记录器有很多局限性,例如,宏记录器通常不会跟踪对话框打开。我是在使用宏记录器创建宏来导入文本时发现这个限制的

Sub CreateOutlineInImpress
	oProvider = ThisComponent.CurrentController.Frame
	oDispHelper = createUnoService("com.sun.star.frame.DispatchHelper") 
	oDispHelper.executeDispatch(oProvider,".uno:SendOutlineToStarImpress","", , Array())
End Sub

将整个Writer文档复制到剪贴板。
宏记录器很快提供了一个解决方案。不幸的是,从添加到文档中的按钮调用宏时失败,但它从IDE和AOO调用时成功。解决方案是在执行之前将焦点设置在文档上

Sub CopyToClipboard_Dispatch
	document = ThisComponent.CurrentController.Frame
	document.ContainerWindow.setFocus
	dispatcher = createUnoService("com.sun.star.frame.DispatchHelper") 
	dispatcher.executeDispatch(document, ".uno:SelectAll", "", 0, Array()) 
	dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
End Sub

如果改成用直接服务,那么如下所示

Sub CopyToClipboard_API
	ThisComponent.CurrentController.Select(ThisComponent.Text)
	o = ThisComponent.CurrentController.getTransferable()
	sClipName = "com.sun.star.datatransfer.clipboard.SystemClipboard"
	oClip = createUnoService(sClipName)
	oContents = oClip.setContents(o, null)
End Sub

调度功能强大,并且不需要太多关于内部工作原理的知识。
但除了只能在调度中使用的功能,如撤销命令,最好是直接使用内部对象。

2.另一种就是直接使用uno服务写宏,这种方法不用dispatcher。

下面是基本步骤:
StarDesktop
样式
文本文档

(六)运行宏

工具 - 宏 - 运行宏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值