Office文档模型深入---Excel文档模型与开发实战(3)
Range是最常见的对象,他可以代表Excel文档中的一个单元格,一行(列)单元格,若干行(列)单元格,几个不相邻的单元格,甚至他还可以代表不同工作表中的单元格。Range同时也给我们提供了非常便利的操作,如自动填充,查找,排序等。本篇的内容可以分为两部分:获取Range选区,对Range选区的操作。
一.获取Range选区
下面是我们本次实例需要操作的Excel文档:
在Excel中,可以用"$A$1"来表示一个单元格,其中$表示绝对地址,A1即代表第一行第一列。同样的,我们可以用"$A$1:%E%7"来表示实例中的数据区域,即为A1到E7区域。在API中,我们同样可以通过如下方式获取Range区域。
3 Console.WriteLine(Range1.Address.ToString());
另外,在上面例子中我们省略掉了$(去掉$之后表示相对地址,不过在本处仍表示这个区域),而在通过Address属性获取到的地址属性里返回的仍是"$A$1:$C$5",也就是Address返回的始终是绝对地址。因此在判断用户选区时,地址字符串要注意加个绝对地址符号。
通过上面的代码我们可以简单的获取一个连续的区域,我们还可以通过Application类的ActiveCell属性来获取用户在当前Excel中的选中区域
除此之外,还存在有另一种获取特定选区的方法,第一步是直接通过WorkSheet的Cells属性获取目标选区的起点位置(需要注意的是在如下的调用方法中,第一个参数代表列,第二个代表行),不太符合习惯。
在获取起点位置之后,可以通过该起点位置的Rows,Columns属性来获取更大的选区。
上面介绍的都是连续选区的获取,针对不连续的选区就要使用Range的合并,
3 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
4 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
5 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
6 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
7 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
8 Type.Missing, Type.Missing, Type.Missing, Type.Missing,
9 Type.Missing, Type.Missing, Type.Missing, Type.Missing);
这样可以获取一个不连续的选区,那么这个选区的Address属性会返回什么呢?
在获取Range对象时,还有个非常强大的工具Offset属性,Offset属性可以帮助我们获取相对地址,这样使选区的获得更加灵活,Range同样是一个参数化的属性,我们只能通过get_Offset()属性来获取Offset对象,下面的代码展示了Offset应用的灵活
3 for (int i = 1; i <= 5; i++)
4 {
5 Range5.get_Offset(i, 0).Value2 = i.ToString();
6 }
通过上面的实例,会在以A1开始的一列中分别填入数字(此处的索引方式是 从0开始,第一个参数表示行,第二个参数表示列,与Excel中其他地方不同)。
Range还有一些其他的属性可以协助我们获取选区。如下代码所示:其中Get_End用于获取选区中的选区,Excel.XlDirection枚举用来表示区域方位。
3 rng = (Excel.Range)xapp.Selection;
4 rngRight = rng.get_End(Excel.XlDirection.xlToRight); //获取选区右侧的一个单元格
5 rngLeft = rng.get_End(Excel.XlDirection.xlToLeft); //获取选区左侧的一个单元格
6 rngUp = rng.get_End(Excel.XlDirection.xlUp); //获取选区上方的一个单元格
7 rngDown = rng.get_End(Excel.XlDirection.xlDown); //获取选区下方的一个单元格
二.对Range选区的操作
上一部分我们了解到了获取Range选区的几种方法,接下来我们看一下针对Range选区类的一些基础操作:
1.格式化选区
通过API可以轻易地更改选区内的文字属性,如加粗等,下面的例子是MSDN中实现excel里 给选中的选区加粗,取消选择后恢复的代码:
2 private int LastBoldedRow = 0;
3 private void BoldCurrentRow(Excel.Worksheet ws)
4 {
5 // Keep track of the previously bolded row.
6
7 // Work with the current active cell.
8 Excel.Range rngCell = ThisApplication.ActiveCell;
9
10 // Bold the current row.
11 rngCell.EntireRow.Font.Bold = true;
12
13 // Make sure intRow isn't 0 (meaning that
14 // this is your first pass through here).
15 if (LastBoldedRow != 0)
16 {
17 // If you're on a different
18 // row than the last time through here,
19 // make the old row not bold.
20 if (rngCell.Row != LastBoldedRow)
21 {
22 Excel.Range rng =
23 (Excel.Range)ws.Rows[LastBoldedRow, Type.Missing];
24 rng.Font.Bold = false;
25 }
26 }
27 // Store away the new row number
28 // for next time.
29 LastBoldedRow = rngCell.Row;
30 }
其中通过以下几步来实现
ThisApplication.ActiveCell 以获取当前选中的单元格,
rngCell.EntireRow.Font.Bold = true;以实现对粗体的控制,
rngCell.Row != LastBoldedRow 判定是否已经离开选区
2.自动填充
Range类允许通过AutoFill方法来实现自动填充功能,使用此功能可以讲一组递增或递减的量填入某个选区,填充的方式会作为一个参数被传入,这个参数是一个XLAutoFillType枚举:
枚举名 | 描述 |
---|---|
xlFillCopy | 复制值和格式到新单元 |
xlFillDays | 拓展复制星期的值和格式到目标单元 |
xlFillDefault | Excel默认复制方式 |
xlFillFormats | 复制格式到目标单元 |
xlFillMonths | 拓展复制月份的值和格式到目标但愿 |
xlFillSeries | 拓展复制系列值 (e.g., '1, 2' 被拓展为 '3, 4, 5')和格式到目标但愿 |
xlFillValues | 复制值到目标但愿 |
xlFillWeekdays | 拓展工作周的日期名的值和格式到目标单元 |
xlFillYears | 拓展年份的值和格式到目标单元 |
xlGrowthTrend | 增长拓展数据和格式到目标单元(如1 2 拓展 4 8 16) |
xlLinearTrend | 线性拓展数据和格式到目标单元(如1 2 拓展 3 4 5) |
3 Range3.AutoFill(Range1,Excel.XlAutoFillType.XlFillCopy);
上述代码实现了以Range3为基础在Range1中的拓展,拓展方式为复制。参数中的填充的起点和目标范围是必须提供的,填充方式留空的话会默认xlFillCopy
3.查找
查找方法默认是和查找对话框对应的
Range.Find()需要的参数比较多,可以实现搜索界面中所需的绝大多数功能。
参数 | 类型 | 说明 |
---|---|---|
What(必需) | 对象 | 要查找的数据;可以是一个字符串或者任何 Excel 数据类型。 |
After | 范围 | 您想从这个范围的后面开始搜索(在搜索中,不包括这个单元格);如果不指定单元格,则从范围的左上角开始搜索。 |
LookIn | XlFindLookin(xlValue、xlComments、xlFormulas) | 要搜索的信息类型;不能用 Or 运算符组合查询。 |
LookAt | XlLookAt(xlWhole、xlPart) | 确定搜索匹配所有单元格,还是部分单元格。 |
SearchOrder | XlSearchOrder(xlByRows、xlByColumns) | 决定搜索顺序;xlByRows(默认值)将横向搜索,然后纵向搜索;xlByColumns 将纵向搜索,然后横向搜索。 |
SearchDirection | XlSearchDirection(xlNext、xlPrevious) | 确定搜索的方向;默认值是 xlNext。 |
MatchCase | 布尔值 | 确定搜索是否区分大小写。 |
MatchByte | 布尔值 | 确定是否双字节字符只和双字节匹配 (True) 或者也可以和单字节字符匹配 (False);只有当您安装了对双字节支持时才适用。 |
与Find()类似的,Range提供有FindNext(),FindPrevious()以实现 查找下一个 和查找上一个,这个方法会调用上一次的Find(),不过在使用的时候需要注意,这两个方法在查找到了页首(页尾)的时候会自动重头来过,如果不想死循环的话就得在代码中控制了。还有一种比较原始的方法可以实现查找--对Range中的Cell进行遍历,有需要的话这也是个好方法,接下来附一段查找的代码:
3 {
4 Excel.Range rng = xapp.
5 get_Range("Fruits", Type.Missing);
6 Excel.Range rngFound;
7
8 // Keep track of the first range you find.
9 Excel.Range rngFoundFirst = null;
10
11 // You should specify all these parameters
12 // every time you call this method, since they
13 // can be overriden in the user interface.
14 rngFound = rng.Find("apples", Type.Missing,
15 Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
16 Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext,
17 false, Type.Missing, Type.Missing);
18 while (rngFound != null)
19 {
20 if (rngFoundFirst == null)
21 {
22 rngFoundFirst = rngFound;
23 }
24 else if (GetAddress(rngFound) == GetAddress(rngFoundFirst))
25 {
26 break;
27 }
28 rngFound.Font.Color = ColorTranslator.ToOle(Color.Red);
29 rngFound.Font.Bold = true;
30 rngFound = rng.FindNext(rngFound);
31 }
32 }
4.替换
替换为Replace()方法,这个方法和Find()类似,只是多了一个替换内容的参数,其他都可参照Find()
5.排序
就像Excel应用程序中一样,我们编程实现对Excel中数据的排序,指出来要排序的范围和方式,剩下的Sort()会帮我们搞定
参数 | 类型 | 说明 |
---|---|---|
Key1 | Object(String 或 Range) | 首要排序字段,可以是一个范围名称 (String),或是一个 Range 对象,确定了要排序的值。 |
Order1 | XlSortOrder(xlAscending、xlDescending) | 为 Key1 中指定的值决定排序顺序。 |
Key2 | Object(String 或 Range) | 第二个排序字段,排序透视表时无法使用。 |
Type | Object | 当对透视表进行排序时,指定对哪些元素排序;对一个普通范围则没有影响。 |
Order2 | XlSortOrder | 为在 Key2 中指定的值决定排序顺序。 |
Key3 | Object(String 或 Range) | 第三个排序字段,不能使用于透视表。 |
Order3 | XlSortOrder | 为在 Key3 中指定的值决定排序顺序。 |
Header | XlYesNoGuess(xlGuess、xlNo、xlYes) | 指定第一行是否包含头信息,默认值为 xlNo;如果想让 Excel 自己去推测,就指定为 xlGuess。 |
OrderCustom | Integer | 为自定义排序顺序列表指定一个基于 1 的索引;如果不指定这个参数,则使用默认排序顺序。图 28 显示了一种创建自定义排序顺序的技术。对于这个例子,将这个参数指定为 6 将基于“fruits”自定义顺序进行排序。 |
MatchCase | Boolean | 设置成 True 就会进行区分大小写的排序,设置成 False 则进行不区分大小写的排序;不能用于透视表。 |
Orientation | XlSortOrientation (xlSortRows, xlSortColumns) | 排序方向。 |
SortMethod | XlSortMethod(xlStroke、xlPinYin) | 指定排序方法;不能适用于所有语言(当前值只适用于对汉字进行排序,而不适用于对其他语言排序)。 |
DataOption1 | XlSortDataOption (xlSortTextAsNumbers, xlSortNormal) | 指定如何对 Key1 中指定的范围进行文本排序;不能用于透视表排序。 |
DataOption2 | XlSortDataOption | 指定如何对 Key2 中指定的范围进行文本排序;不能用于透视表排序。 |
DataOption3 | XlSortDataOption | 指定如何对 Key3 中指定的范围进行文本排序;不能用于透视表排序。 |
如上述表格所示,现在能提供的排序条件只有三组,暂不能实现无限条件。排序顺序可以通过XlSortOrder枚举实现升序降序,是否包含列头等属性,是否忽略大小等也可以由参数来控制,除排序条件外可以实现对话框中的所有选项。
本篇实例:
/Files/shenyubao/ExcelDemo-3.rar
以上列举了Range中一些常见的方法,还有些方法因为不太常用不再一一介绍,MSDN中可以查到完整列表:http://msdn.microsoft.com/zh-cn/library/microsoft.office.interop.excel.range_members.aspx
由于考试原因,最近更新较慢。Excel的基础类型告一段落,下阶段会开始Excel的一些专题,如图表等,OutLook系列的也会近期发出来,希望大家能够喜欢。