从网上下载了一些关于OOs宏编程的电子书,先从Learn OpenOffice.org Spreadsheet Macro Programming(PACKT 出版,作者为Dr. Mark Alexander Bain)开始学习。
这里所有的内容都是基于Windows XP下的OpenOffice3.1版。没有安装中文版,所以菜单和对话框与中文版有些区别。
使用OOs Basic IDE
开始学习编写宏之前必需学会IDE的使用方法。这里的Basic是表示使用OOs Basic语言来编程。
和MS Excel一样,点击菜单“Tools”->“Macro”->“Organize Macros”->“OpenOffice.org Basic”可以打开IDE窗口,如下图。
在上图中我们还可以看到另外三个选项:
- Python
- BeanShell
- JavaScript
也就意味着除了Basic语言外,我们还可以选择另外三种语言来对OOs编程。
点击“OpenOffice.org Basic…”后,显示“OpenOffice.org Basic Macros”对话框,如下图。
在这里我们可以选择创建宏的位置,提供了三个选择:
- My Macros:如果我们希望所有的工作表都可以使用这个宏,可以保存在这个地方。这个宏对仅对当前用户有效,宏文件保存在Documents and Settings\current username\Application Data\OpenOffice.org\3\User\Basic下面。
- OpenOffice.org:如果你希望所有的用户都可以使用这个宏,可以保存在这个地方。但是当点击这个选项时,我们可以看到“New”按钮是灰色的,表示不能直接在这里创建宏。后面再介绍怎样将自定义的宏放入到这个目录供所有的用户使用。
- 当前工作表:将宏嵌入到工作表中的好处是你可以将文件连同宏一起复制或发送给其他人使用。
选择当前工作表Untitled 1,然后单击“New”按钮,将显示“New Module”对话框,如下图:
输入模块名称例如“ModNew”,然后单击“OK”按钮,就打开IDE窗口,如下图。在代码窗口中,OOs已经自动创建了一个Main过程,我们也可以将它删除,它的主要作用是展示一个简单的代码结构给我们。
IDE的工具
现在简单的介绍一下工具栏上的各个图标,图标标识如下图:
图标 1:运行(Run)按钮,点击这个按钮将运行模块中的第一个过程,而不是像MS Excel一样运行光标所在的过程。如果需要运行指定的过程,需要点击“Select Macro”按钮来选择需要运行的过程。
图标 2:停止(Stop)按钮,运行过程中点击这个按钮将停止代码运行而进入到编辑状态。
图标 3:逐过程(Step Over)按钮,逐句运行代码,当运行到调用的过程或函数时,将该过程和函数作为单个语句运行,然后直接运行后一个语句。
图标 4:逐语句(Step Into)按钮,逐句运行代码,当运行到调用的过程或函数时,代码将逐句运行过程或函数的每一个语句。
图标 5;跳出(Step Out)按钮,在调用的过程或函数中,如果不希望逐句运行每一个语句,点击此按钮可以完成该过程或函数而直接跳到该过程或函数的后一个语句。
图标 6:设置或取消断点,点击此按钮,将设置光标所在的行设置断点或取消断点。也可以双击指定行代码区左边的区域设置该行为断点,再次双击断点标记则取消断点。
图标 7:管理断点的对话框。点击此按钮,将显示如下图的对话框,在该对话框中可以添加或取消断点。在Breakpoints下的文本框中输入“#”并紧接着行号,如#12,然后单击“New”按钮,再点击“OK”按钮关闭对话框,则可在指定行添加断点。
图标 8:设置监视。在代码中选择指定变量,单击此按钮,则可以在监视窗口中添加对该变量的运行中的监视。或者在监视窗口中的文本框中输入变量,然后按Enter键也可添加监视变量。
图标 A:Object Catalog(对象目录),点击此按钮将显示Objects对话框,可以选择指定的过程双击即可打开该过程的代码窗口。
图标 B:Select Macro(选择宏),点击此按钮将显示OpenOffice.org Basic Macros对话框,可以运行、编辑或删除指定的宏。
图标 C: Select Module(选择模块),点击此按钮将显示OpenOffice.org Basic Macro Organizer对话框,你可以发现这个对话框中有三个标签页,Modules(模块)、Dialogs(对话框)、Libraries(库)。以后再 介绍Modules和Libraries。
在IDE中设计Dialogs
在宏中可以使用对话框提供一个用户界面,这里简单地介绍一下怎样在IDE中设计Dialogs。
首先打开OpenOffice.org Basic Macro Organizer对话框,然后选择Dialogs标签页。然后选择你需要保存这个对话框的库。如下图:
例如选择文档Untitiled 1的Standard库,单击New按钮,将弹出New Dialog对话框要求输入名称,在输入一个有意义的名称后点击”Edit“按钮即可进入对话框的设计窗口。
OOs提供了丰富的工具箱以供创建各种控件。点击其中一个控件,例如Textbox,在Dialog上拖动鼠标则可创建文本框。
选择文本框,单击右键弹出菜单“Properties”打开属性窗口,其中General标签页设置文本框的外观和内容,Events则可设置文本的事件过程。对话框的详细以后再介绍。
总的来说,相对MS Excel的IDE来说,OOS的IDE有些简单,尤其是调试。OOs仅提供了一个监视(Watch)窗口和过程堆栈(Call)窗口,而下面这些功能是OOs所缺少的:
- 立即窗口
- 本地窗口
- 对象浏览器
- 智能语法提示
- 监视窗口的表达式监视
另外对于宏和代码窗口的操作也不太方便。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
前面介绍了OpenOffice.org的IDE环境,接着介绍怎样使用模块(Module)和库(Library)。
使用库(Library)
我们知道宏被保存在模块中,而模块本身被保存在库中。库可以在以下三个位置:
- My Macros:仅你个人可以访问宏
- OpenOffice.org Macros:所有用户都可以访问宏
- 嵌入到电子表格中:通过这个电子表格访问宏
当我们创建模块时,OOs已经帮我们创建了一个叫做Standard的库,我们不能删除它或将它改名。一般来说,我们可以使用OOo的标准库来满足我们大部分的要求。但是如果我们需要更有效地管理我们的模块或者需要一个多用户的环境,那么创建自己的库是必要的。
我们可以使用OOo Basic Organizer来创建自己的库,单击Tools -> Macros -> Organize Dialogs打开OOo Basic Macro Organizer对话框,然后选择Libraries标签页。选择库保存的位置,我们可以看到库列表中只有Standard库,如图:
单击“New…”按钮,弹出“New Library”对话框,输入库的名称,如图:
然后单击“OK”按钮即可在库列表中添加自定义的库。如图:
选择“Modules”标签页,我们就可以在自定义库中创建模块了,如图:
我们还可以拖动模块在库之间移动,如图。不过好像不能将相同名称的模块移动到另外一个库中。
在多用户环境中使用库
前面我们在My Macros位置创建了myLib库,这个库可以在下面这个路径找到:
C:\Documents and Settings\username\Application Data\OpenOffice.org\3\user\basic\myLib
这个目录一般包括下面这几个文件,另外还包括以我们自己创建的模块为名称的xba文件,如图:
这些文件其实都是一些XML格式的文件。
- dialog.xlb 包含对话框的索引
- script.xlb 包含模块的索引
- Module1.xba 模块定义文件,包含宏代码
导入别人的库很简单,打开OOs Basic Macro Organizer对话框,选择“Libraries”标签页和并选择导入的位置例如当前文档,然后单击“Import”按钮,将显示“Import Libraries”文件浏览窗口,然后选择需要导入的库的位置,例如如图的MyLib库。
选择需要导入的xlb文件,点击“OK”按钮,然后弹出“Import Libraries”对话框提供一些导入的选项。
- Insert As Reference (read-only):如果选择此项,只是创建一个对于该库只读的链接,我们可以运行宏但不能修改。如果我们想做自己的修改,则不能选择此项。
- Replace existing libraries:是否覆盖以存在项。注意使用此项以免覆盖自己的宏。
单击“OK”按钮,则可以将该库以及该库下所有的模块导入指定的位置,如图:
以Insert As Reference导入的库显示如图:
如果这个库是以单个电子表格发布,可以同样在“Import Libraries”文件浏览窗口中选择电子表格文件,如图:
在接着显示的“Import Libraries”对话框中选择需要导入的库,如图:
如果该位置已经存在相同名称的库而对话框中没有选择覆盖选项,则会弹出如下图的提示框。
如果新建文档中没有Standard库,则可以导入Standard库。但是如果已经存在Standard库,并且在“Import Libraries”对话框中选择覆盖选项,仍然不能导入别人命名为Standard的库,将显示如下提示框。
如果我们需要分发自己的库,可以使用“Export”功能,在Organizer对话框的“Libraries”标签页中,选择需要导出的库,单击“Export”按钮,显示“Export Basic Library”对话框,提供两个导出方式,如图:
一个是以Basic Library库方式,点击“OK”按钮后,弹出“Export as BASIC library”文件夹浏览窗口以选择导出的位置。
另外一个是以Extension方式,点击“OK”按钮后,弹出“Export library as extension”文件浏览窗口以保存extersion文件。
在OpenOffice.org Macros位置添加库
在My Macros位置保存库,只能供当前用户使用,如果其它人使用的话,则需要提供复制文件,这样不利于控制文件版本,如果以链接形式导入库,又不能控制文件被有意的修改或删除。
前面说过OpenOffice.org Macros位置保存库可以给所有的用户使用,但是在Organizer对话框中,我们发现Import按钮是不可用的。
前面说过,一个库保存在一个文件夹下,而这个文件夹包含两个xlb文件分别为模块和对话框的索引,另外这个文件夹中包含一个或多个xba文件,这些是模块定义文件,包含宏或对话框的代码。
因此我们可以将自定义库的文件夹直接复制到OpenOffice.org Macros位置下:
C:\Program Files\OpenOffice.org 3\Basis\share\basic
这个时候在Organizer对话框中仍然不能显示自定义的库。我们还需要修改上面这个目录下的xlc文件,在这个目录下有两个xlc文件,这两个文件都是xml格式,包含库和对话框列表。
script.xlc
dialog.xlc
用文本编辑器打开,然后再最后一行之前也就是</library:libraries>之前添加下面的内容。
<library:library library:name=”myLib” xlink:href=”$(INST)/share/basic/myLib/script.xlb/” xlink:type=”simple” library:link=”true” library:readonly=”false”/>
如图:
保存文件,然后重新打开OpenOffice.org Calc,就可以在Organizer对话框中看到自定义的库。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++注意:我根据上面的操作修改script.xlc文件后,仍然在Organizer对话框中不能显示自定义的库,很奇怪,不知是否还有其它的地方需要设置。
另外,书上说在Organizer对话框的Module标签页中可以通过单击(可能需要多次)指定模块来修改模块名称,但实际上也是不能实现。
前面介绍了OpenOffice.org的IDE环境、模块(Module)和库(Library)。现在开始看一个OpenOffice宏的示例。
Sub Main
Dim fname as String
Dim sname as String
Dim username as String
fname = "Fred"
sname = "Smith"
ppi_add_user_sub(fname, sname)
username = ppi_add_user_func(fname, sname)
msgbox "User Name for " & fname & " " & sname _
& " is " & username, 0 ,"User Name"
End Sub
Sub ppi_add_user_sub (fname as String, sname as String)
Dim username as String
username =lcase(sname+mid(fname,1,1))
msgbox "User Name for " + fname + " " + sname _
+ " is " + username, 0 ,"User Name"
End Sub
Function ppi_add_user_func (fname as String, sname as String) as String
ppi_add_user_func = lcase(sname+mid(fname,1,1))
End Function
从上面这个代码可以看到,OpenOffice的宏和MS Excel的VBA代码十分相似。同样使用Dim语句声明变量,同样适用Sub和Function分别表示过程和函数。甚至部分函数或语句都是一样的,例如lcase和msgbox。
同样,在Basic编辑器中选择需要查询的函数或语句,按F1可以获取该函数或语句的帮助。
在MS Excel VBA中,我们主要是针对Excel对象模型编程来控制Excel。在OOs中,我们则是访问OOs的Universal Network Objects,一般叫做UNOs。UNOs是跨平台和跨语言的对象,我们可以利用它来控制OOo环境的每个方面。
OOo对象模型
我们从下往上来了解UNOs。
先把我们的宏理解为客户端(Client),和UNOs的接口(Interface)打交道。
接口(Interface)
每个接口由一系列的方法组成,我们可以使用这些方法来:
- 获取或设置参数
- 控制接口定义的任何功能性的操作
每个接口包含在一个服务(Service)中。
服务(Service)
一个服务是一个UNO部件—OOo Calc的一个组成部分。每个服务由一个或多个服务组成,它还包含一系列的属性。
我们可以发现服务有四个类型的属性:
- 常数(Constants)
- 枚举(Enums)
- 例外(Exceptions)
- 结构(Structs)
模块
UNO服务按层级结构在模块中分组。我们现在已经从UNO的最底级来到了最高级。很多模块嵌套在另外一个模块中。而所有的模块嵌套在一个最高级的模块—com.sun.star。这个模块就像Excel中的Application对象。
开始使用UNOs
到了这里我们基本上对OpenOffice.org对象模型有了一个基本的了解。我们可以先使用一个简单的例子(打开和关闭一个电子表格)来了解怎样使用UNOs。
我们先需要了解:
- 每个服务保存在一个模块中。
- 所有的模块保存在一个中央模块中—com.sun.star。
- 一个服务由函数createUnoService创建。
- 我们将使用frame模块中的Desktop服务。
Sub OpenAndClose
Dim oDesk as Object
Dim oDoc as Object
Dim oUrl as String
oDesk = createUnoService ("com.sun.star.frame.Desktop")
oUrl = "private:factory/scalc"
oDoc = oDesk.loadComponentFromURL (oUrl, "_blank", 0, Array() )
oDoc.close(true)
End Sub
这个代码打开一个空白电子表格然后关闭它,没什么用处,但是告诉我们怎样操作电子表格。
那么怎样打开现有文件呢?需要修改”private:factory/scalc”为需要打开的文件名称。我们看到了上面使用了loadComponentFromURL方法,这个方法接受下面这样的输入:
* file:///home/bluek/ppi_current.dos (Linux环境)
* file:///c:/ppi_current.ods (Windows环境)
我们可以使用convertToUrl函数来转换。
Sub exampleConversion
Dim f1 as String
Dim f2 as String
f1 = "/home/bluek/ppi_current.ods"
f2 = "C:\ppi_docs\ppi_current.ods"
msgBox _
f1 & " converts to " & convertToUrl (f1) & chr (10) & _
f2 & " converts to " & convertToUrl (f2)
End Sub
下面是修改后的代码。判断是否文件存在,如果不存在则打开新的空白表格,然后保存文件并关闭。
Sub OpenAndClose
Dim oDesk as Object
Dim oDoc as Object
Dim oFile as String
Dim oUrl as String
Dim oUrlTemp as String
oDesk = createUnoService ("com.sun.star.frame.Desktop")
' 改变文件名以便于写入
oFile = "c:\home\bluek\ppi_current.ods"
oUrl = convertToUrl (oFile)
' 检查文件是否存在,如果不存在则使用空白电子表格
If fileExists (oFile) Then
oUrlTemp = oUrl
Else
oUrlTemp = "private:factory/scalc"
End If
oDoc = oDesk.loadComponentFromURL (oUrlTemp, "_blank", 0, Array() )
oDoc.storeAsUrl (oUrl, Array()) ' 保存文件
oDoc.close(true)
End Sub
另外我们还可以简化一些。上面的代码中我们创建了Desktop服务,但是实际上在Calc打开的时候已经自动创建了一个叫做StartDesktop的对象。
这样我们可以将:
oDesk = createUnoService ("com.sun.star.frame.Desktop")
oDoc = oDesk.loadComponentFromURL(oUrlTemp, "_blank", 0, Array())
改成
oDoc = starDeskTop.loadComponentFromURL(oUrlTemp, _
"_blank", 0, Array())
在线UNO资料
Calc自带的帮助文件没有提供详细的UNO参考。我们需要查找OpenOffice.org的在线资料来学习UNO。这个网页包括了com.sun.star下所有模块的内容,以层级结构组织。
点击任何一个嵌套的模块,我们可以看到这个对象模型包含的所有元素:
- Services
- Interfaces
- Constants
- Enums
- Exceptions
- Structs
另外我们还可以发现有些模块还包含:
- 嵌套的模块
- 这个模块中服务使用的接口列表
接着可以点击这些链接获得更详细的信息。
一个真实的例子:使用Table UNO访问单元格
Table就像MS Excel中的Worksheet。
我们可以访问OpenOffice.org网站的table模块网页。
先只关注服务。有很多table相关的服务,我们先找CellRange服务和它的XCellRange接口。
从接口页面我们可以看到有三个方法访问单元格,getCellByPosition、getCellRangeByPosition和getCellRangeByName。
服务中的服务
我们经常发现一个服务还包含另一个服务。CellRange服务是com.sun.star.table模块中的一个服务,它还可以在另外一个服务speadsheet中使用。
发现包含的服务
如果我们想知道是否一个服务是否是一个包含的服务,有两个方法:
- 在整个文档中搜寻要使用的服务,看是否包含另外的服务(我们需要访问的服务)
- 找到我们想要包含的服务的文档,看是否有一个”Use”链接可用。
以CellRange服务为例,我们将会发现“Link”链接可用,单击链接,我们可以发现这个服务包含在:
- com.sun.star.sheet.SheetCellCursor
- com.sun.star.sheet.SheetCellRange
- com.sun.star.sheet.Spreadsheet
怎样查找方法在那些服务中可用
打开OOo全局索引网页,这里有所有模块、服务、方法、常数、枚举、例外和结构的A-Z完整列表,假如我们查找“Print”,将会发现三个引用:
- PRINT: 常数组com.sun.star.awt.KeyFunction下的常数
- Print: com.sun.star.text.BaseFrameProperties服务下的属性
- print(): com.sun.star.view.XPrintable接口下的函数
这样我们知道接口com.sun.star.view.XPrintable下的print函数,那么这个接口在哪些服务中使用?在XPrintable接口文档页面,单击“Use”链接,我们可以得到支持这个接口的所有服务列表。
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
前面介绍了OpenOffice.Org SpreadSheet宏的IDE和UNO,现在可以开始编写代码了。这里主要介绍怎样使用宏操作工作表,我们将学会怎样:
- 打开和关闭文件
- 使用多个工作表
- 在工作表中操作数据
- 使用OOo的内置函数
- 使用单元格和区域
打开和关闭电子表格
在前面我们已经知道了怎样打开和关闭电子表格
- 使用starDeskTop对象访问电子表格
- 使用loadComponentFromURL函数载入电子表格
- 使用close方法关闭电子表格
- 使用fileExists函数判断文件是否存在
- 使用storeAsUrl方法保存电子表格。
接着我们开始操作电子表格的内容。
操作电子表格单元格
我们知道:
- 每个电子表格包括一个或多个工作表(一般默认是3个,最多可以到256个)
- 每个工作表由8192000个单元格组成(256列乘以32000行)— OpenOffice.org Calc 3.0已经增加到67108864个单元格(1024乘以65536行)
- 每个工作表可以通过一个序号(0到255)来指认
- 每个单元格可以通过getCellByPosition方法使用一个格子坐标来指认它的位置
下面这个代码在一个工作表的单元格中填充内容:
Sub singleFile
Dim oDoc as Object
Dim oSheet as Object
Dim oCell as Object
oDoc = starDeskTop.loadComponentFromUrl _
("private:factory/scalc", "_blank",0,Array ())
oSheet = oDoc.sheets (0)
oCell = oSheet.getCellByPosition (0,0)
oCell.String = now 'This function returns the current date and time
End Sub
这个宏打开一个空白电子表格,获得第一个工作表,然后获得最左上角的单元格,写入当前时间到该单元格。
内容可以以三种方式写入到单元格—公式、字符串、数值。这个很重要,参考下面的代码:
oCell = oSheet.getCellByPosition (0,1)
oCell.Value = 20
oCell = oSheet.getCellByPosition (0,2)
oCell.Value = 30
oCell = oSheet.getCellByPosition (1,1)
oCell.String = "=A2+A3"
oCell = oSheet.getCellByPosition (2,1)
oCell.Formula = "=A2+A3"
oCell = oSheet.getCellByPosition (3,1)
oCell.Value = "=A2+A3"
尽管我们输入的信息差不多,但是结果却完全不同。
如果简单一些的话,上面的代码也可以写成:
oSheet.getCellByPosition (0,1).Value = 20
oSheet.getCellByPosition (0,2).Value = 30
oSheet.getCellByPosition (1,1).String = "=A2+A3"
oSheet.getCellByPosition (2,1).Formula = "=A2+A3"
oSheet.getCellByPosition (3,1).Value = "=A2+A3"
使用OOo内置函数
我们会经常在Calc中使用OOo的内置数学函数。在宏中我们也可以使用它们。例如,我们可以:
oCell1 = oSheet.getCellRangeByName ("A1")
oCell2 = oSheet.getCellRangeByName ("B1")
oCell1.value = 23.1
oCell2.value = SIN(oCell1.value)
也可以这样:
oCell2.formula = "=SIN(A1)"
有什么区别呢?前面的代码将值-0.9放入B1单元格,而后面的代码则在B1单元格中放入一个公式。
然而,只有一部分函数可以这样使用。例如,下面的代码可以运行:
For r = 0 to 9
i = r + 1
oCell1 = oSheet.getCellByPosition (0,r)
oCell1.Value = i
oCell2 = oSheet.getCellByPosition (1,r)
oCell2.Formula = "=ROMAN(A" + i + ")"
Next r
oLetters = Array("I","V","X","L","C","D","M")
For r = 0 to ubound(oLetters)
i = r + 1
oCell1 = oSheet.getCellByPosition (2,r)
oCell1.String = oLetters(r)
oCell2 = oSheet.getCellByPosition (3,r)
oCell2.Formula = "=ARABIC(C" + i + ")"
Next r
运行上面的代码,将在工作表中显示下面有趣的结果。
但是如果我们试下面的代码:
oCell2.value =ARABIC(oCell1.String)
将会得到下面的错误提示:
但这并不表示我们不能使用内置函数,只是需要使用另外一种方法(有些类似于Excel VBA中的Application.WorksheetFunction)。
oFunction = createUnoService("com.sun.star.sheet.FunctionAccess")
oCell4.value = oFunction.callFunction("ARABIC", _
Array(oCell3.String))
注意传递给函数CallFunction的第二个参数是一个数组。
命名工作表和单元格
我们可以使用序号通过Sheets集合来访问工作表,但是在删除或添加工作表或者工作表的顺序改变后,使用现有的序号访问工作表时可能会发生错误。因此最好使用工作表名称来访问它们。
访问现有命名的工作表和单元格
使用序号访问:
oSheet = oDoc.sheets(0)
使用名称访问:
oSheet = oDoc.Sheets.getByName("PPI Accounts")
访问到工作表后,也可以使用名称访问单元格。
使用位置访问:
oCell = oSheet.getCellByPosition(0,1)
使用名称访问:
oCell = oSheet.getCellRangeByName("Daily Total")
创建新的命名工作表和单元格
命名一个已存在的单元格很简单:
oSheet.name = "PPI Client Details"
创建一个新的单元格也差不多简单:
oSheet = oDoc.createInstance ( "com.sun.star.sheet.Spreadsheet" )
oDoc.Sheets.insertByName ( "PPI Daily Tasks", oSheet )
给一个单元格命名则稍微麻烦点:
Dim oCellAddress As new com.sun.star.table.CellAddress
Dim oNamedRanges
oNamedRanges = oDoc.NamedRanges
oNamedRanges.addNewByName("Total", "$Sheet1.$A$8", oCellAddress, 0)
删除工作表
oDoc.Sheets.removeByName("Sheet3")
使用多个工作表
使用多个工作表和一个工作表的复杂程度是差不多的。
Sub sequencialFiles
Dim oDoc as Object
Dim oDesk as Object
Dim oSheet as Object
Dim oCell as Object
oDoc = starDeskTop.loadComponentFromUrl _
("private:factory/scalc", "_blank",0,Array())
oSheet = thisComponent.sheets (0)
oCell = oSheet.getCellByPosition (0,0)
oCell.String = now
oDoc = starDeskTop.loadComponentFromUrl _
("private:factory/scalc", "_blank",0,Array())
oSheet = thisComponent.sheets (0)
oCell = oSheet.getCellByPosition (0,0)
oCell.String = now + 1
End Sub
运行结果如图:
上面的代码使用一个对象变量来表示不同的对象,这样需要再转换到另外一个对象之前保证完成自己的操作。我们会发现如果对每个电子表格使用不同的对象会更有效一些,这样我们可以控制所有的操作。
Sub multiSheets
Dim oURL1 as String
Dim oURL2 as String
Dim oDoc1 as Object
Dim oDoc2 as Object
Dim oCell1 as Object
Dim OCell2 as Object
oURL1 = "private:factory/scalc"
oURL2 = "private:factory/scalc"
oDoc1 = starDeskTop.loadComponentFromURL (oURL1, "_blank", 0, _
Array() )
oDoc2 = starDeskTop.loadComponentFromURL (oURL2, "_blank", 0, _
Array() )
oCell1 = oDoc1.Sheets (0).getCellByPosition (0,0)
oCell1.String = now
oCell1 = oDoc1.Sheets (0).getCellByPosition (0,1)
oCell1.Value = 37.5
oCell2 = oDoc2.Sheets (0).getCellByPosition (0,0)
oCell2.String = now
oCell2 = oDoc2.Sheets (0).getCellByPosition (0,1)
oCell2.String = "Amount"
oCell2 = oDoc2.Sheets (0).getCellByPosition (1,1)
oCell2.String = "VAT"
oCell2 = oDoc2.Sheets (0).getCellByPosition (2,1)
oCell2.String = "Total"
oCell2 = oDoc2.Sheets (0).getCellByPosition (0,2)
oCell2.Value = oCell1.Value
oCell2 = oDoc2.Sheets (0).getCellByPosition (1,2)
oCell2.Value = oCell1.Value * 0.175
oCell2 = oDoc2.Sheets (0).getCellByPosition (2,2)
oCell2.Value = oCell1.Value * 1.175
End Sub
使用区域
除了使用单元格之外,我们还需要使用区域。下面的代码将第2个工作表中区域A1:A100的内容负责到第一个工作表相同的区域中。
oRange1 = oDoc1.Sheets (1).getCellRangeByName ("A1:A100")
oRange2 = oDoc2.Sheets (0).getCellRangeByName ("A1:A100")
oRange2.setDataArray (oRange1.getDataArray ())
也可以使用单元格位置来表示区域。
oRange1 = oDoc1.Sheets (0).getCellRangeByPosition (0,0,0,100)
oRange2 = oDoc2.Sheets (0).getCellRangeByPosition (0,0,0,100)
区域在使用某些函数时特别有用。
oCell1 = oSheet.getCellRangeByName ("A1")
oCell2 = oSheet.getCellRangeByName ("A2")
oCell3 = oSheet.getCellRangeByName ("A3")
oCell4 = oSheet.getCellRangeByName ("B3")
oCell1.Value = 36
oCell2.Value = 57
oCell3.Value = 42
oRange1 = oSheet.getCellRangeByName ("A1:A3")
'Remember to use callFunction
oCell4.Value = _
oFunction.callFunction("STDEV", Array(oRange1.getDataArray ()))