# dotNet.ReoGrid 扩展库 - 范围（Range）

在 ReoGrid 中，范围由起始位置和结束位置定义，最小的范围至少包含一个单元格。需要注意的是，范围本身并不是合并单元格，但它可以被合并成一个单元格。此外，两个范围之间可能存在交叉，如下图所示：

![范围示意图](../images/3.png)

ReoGrid 中通过两种主要对象表示范围：

* **范围位置（Range Position）**：由 `ReoGrid.RangePosition` 结构体表示。
* **范围实例（Range Instance）**：由 `ReoGrid.ReferenceRange` 类表示，提供工作表中更详细且可操作的范围表示。

这些对象便于管理和操作单元格范围，支持电子表格中的复杂操作和交互。

## 范围位置（Range Position）

`ReoGrid.RangePosition` 结构体封装了标识工作表中特定范围所需的数值信息。需要注意的是：
- `ReoGrid.RangePosition` 不与任何特定工作表绑定
- 不存储任何数据或样式信息

可以通过以下方式创建 `ReoGrid.RangePosition`：
1. 从地址字符串创建
2. 指定起始位置和范围大小（包括以下参数）：
   - 起始位置的行索引（从0开始）
   - 起始位置的列索引（从0开始）
   - 范围包含的总行数
   - 范围包含的总列数

🅰 示例：

```aardio
// 从地址字符串创建范围位置
var rangeFromString = ReoGrid.RangePosition("C5:H14");

// 通过指定起始位置、行数和列数创建范围位置
var rangeFromIndices = ReoGrid.RangePosition(4, 2, 9, 5);
```

![范围示意图](../images/8.png)

### RangePosition 索引

可以将 ReoGrid.RangePosition 对象作为工作表对象（ Worksheet ）的索引读写指定范围的数据。

🅰 示例：

```aardio
import win.ui;
/*DSG{{*/
var winform = win.form(text="RangePosition 索引")
/*}}*/

import dotNet.ReoGrid;
var grid = ReoGrid.ReoGridControl(winform);
var sheet1 = grid.CurrentWorksheet;

// 定义范围
var range = ReoGrid.RangePosition("C5:F5"); 

//写入数据
sheet1[range] = ["产品", "单价", "数量", "总价" ];

//读取数据
var data = sheet1[range].Value; 

winform.show();
win.loopMessage();
```

用 `sheet1[rangePos]` 读取值时返回的是 System.Object 数组，这个类型的数组 aardio 默认会封包为 dotNet.object 对象，但可以通过 Value 属性[解包为纯 aardio 数组](../../../../std/dotNet/type-conversion.html#object)。


### RangePosition 属性和方法

`ReoGrid.RangePosition` 的以下属性可用于获取范围位置信息：

| 属性 | 描述 |
| --- | --- |
| Row | 起始位置的行号 |
| Col | 起始位置的列号 |
| Rows | 范围包含的行数 |
| Cols | 范围包含的列数 |
| EndRow | 结束位置的行号 |
| EndCol | 结束位置的列号 |
| IsEmpty | 检查范围是否为空 |

`ReoGrid.RangePosition` 包含以下方法：

```aardio
range.Contains(ReoGrid.CellPosition)  // 检查范围是否包含指定的单元格位置
range.Equals(RangePosition)   // 与另一个范围比较
range.Offset(rows, cols)     // 按指定行数和列数移动范围
```

### 获取安全范围位置

当范围可能超出电子表格有效区域时，使用 `FixRange` 方法获取安全范围：

```aardio
var fixedRange = sheet1.FixRange(range);  // 获取修正后的范围
```

## 范围实例（Range Instance）

范围实例表示工作表中的范围，始终保持对工作表的引用。当关联的工作表被销毁时，属于该工作表的所有范围实例将失效并应被销毁。

### 获取范围实例

通过工作表的 `Ranges` 属性获取范围实例：

```aardio
var range = sheet1.Ranges["B2:D3"];
```

### 访问范围数据

通过 `Data` 属性设置范围数据：

```aardio
range.Data = { "产品", "单价", "数量", "总价" };
```

![设置范围数据](../images/891.png)

### 访问范围样式

通过 `Style` 属性获取或设置范围样式：

```aardio
// 设置背景色为浅蓝色
range.Style.BackColor = ReoGrid.Graphics.SolidColor.LightBlue;
```

### 访问范围边框

通过 `Border` 属性获取或设置范围边框：

```aardio
// 设置外边框为黑色实线
range.Border.Outside = ReoGrid.RangeBorderStyle.BlackSolid;
```

### 命名范围

命名范围是从普通范围实例继承的特殊范围实例，详见[命名范围](../worksheet/named-range.html)。

### 范围位置与范围实例的转换

将范围位置转换为范围实例：

```aardio
var rangeInstance = sheet1.Ranges[rangePosition];
```

将范围实例转换为范围位置：

```aardio
var rangePos = rangeInstance.Position;
```

范围实例可以隐式转换为范围位置：

```aardio
var rangePos = rangeInstance;  // 自动转换
```

例如，以下写法都是有效的：

```aardio
sheet1.SelectionRange = rangePosition;
sheet1.SelectionRange = rangeInstance;
```

![选择范围](../images/90.png)

## 已使用范围（Used Range）

仅获取工作表中有数据的单元格范围（包含已使用的单元格）：

```aardio
var range = sheet1.UsedRange;
```

## 合并范围

关于合并范围的操作，请参考[合并与取消合并](../worksheet/merge-and-unmerge.html)。