同时在 Excel 加载项中处理多个区域

可以同时对多个范围应用作或设置属性,即使这些作不是连续的。 与单独访问每个范围相比,这使得代码更短、更高效。

要点

  • 使用 RangeAreas 在一次调用中读取或设置多个单独范围上的相同内容。
  • 属性为 , null 除非所有成员范围共享相同的值。
  • 在 对象上 RangeAreas 设置一次属性,而不是循环,除非每个范围需要不同的逻辑。
  • 避免使用由多个单个单元格组成的大型 RangeAreas 对象。 首先使用 getSpecialCells 或其他筛选器进行窄化。
  • 请注意整列或整行。 有关更多详细信息,请参阅 读取或写入无限范围

RangeAreas

RangeAreas 对象表示一组可能无法触摸的区域。 它与 Range共享许多成员,但在返回值的方式上存在一些差异。

示例:

  • address 返回所有地址的一个逗号分隔字符串。
  • dataValidation 仅当每个区域具有相同规则时,才返回单个对象,否则返回 null
  • cellCount 是所有区域中的总单元格。
  • calculate 重新计算集中的所有单元格。
  • getEntireColumngetEntireRow 为每个成员返回一个新的 RangeAreas 跨越完整列或行。
  • copyFrom Range接受 或 RangeAreas 作为源。

RangeAreas 还提供了区域成员的完整列表

属性

在编写用于读取任何所列属性的代码之前,请先熟悉读取 RangeAreas 的属性。 返回的内容存在细微差别。

  • address
  • addressLocal
  • cellCount
  • conditionalFormats
  • context
  • dataValidation
  • format
  • isEntireColumn
  • isEntireRow
  • style
  • worksheet

方法

  • calculate()
  • clear()
  • convertDataTypeToText()
  • convertToLinkedDataType()
  • copyFrom()
  • getEntireColumn()
  • getEntireRow()
  • getIntersection()
  • getIntersectionOrNullObject()
  • getOffsetRange()在对象) 上RangeAreas命名 getOffsetRangeAreas (
  • getSpecialCells()
  • getSpecialCellsOrNullObject()
  • getTables()
  • getUsedRange()在对象) 上RangeAreas命名 getUsedRangeAreas (
  • getUsedRangeOrNullObject()在对象) 上RangeAreas命名 getUsedRangeAreasOrNullObject (
  • load()
  • set()
  • setDirty()
  • toJSON()
  • track()
  • untrack()

特定于 RangeArea 的属性和方法

RangeAreas 类型具有一些未包含在 Range 对象中的属性和方法。 以下是其中的一部分。

  • areas:一种 RangeCollection 对象,它包含由 RangeAreas 对象表示的所有区域。 RangeCollection 也是新对象,与其他 Excel 集合对象类似。 它具有 items 属性,它是一组表示区域的 Range 对象。
  • areaCountRangeAreas 中的区域总数。
  • getOffsetRangeAreas:与 Range.getOffsetRange 的作用类似,不同之处在于,前者将返回 RangeAreas 并且包含多个区域,每个区域都是原始 RangeAreas 中的区域的偏移。

创建 RangeAreas

可以通过多种方式创建 RangeAreas 对象。 以下列表包含一些示例。

  • 调用 Worksheet.getRanges() 并向其传递具有以逗号分隔的区域地址的字符串。 如果要包含的任何区域已插入到 NamedItem 中,则可以在字符串中包含名称而不是地址。
  • 调用 Range.getSpecialCells() 并返回具有 RangeAreas 特定类型的单元格的对象,例如包含公式、数据验证或条件格式的单元格。
  • 调用 Workbook.getSelectedRanges()。 此方法将返回 RangeAreas,它表示在当前活动工作表上选择的所有区域。

获得 RangeAreas 对象后,你可以在返回 RangeAreas 的对象上使用该方法创建其他对象,例如 getOffsetRangeAreasgetIntersection

注意

你不能直接将其他区域添加到 RangeAreas 对象。 例如,RangeAreas.areas 中的集合不具有 add 方法。

警告

不要尝试直接添加或删除数组的成员 RangeAreas.areas.items 。 这将导致代码中出现不需要的行为。 例如,可能会将其他 Range 对象推送到数组上,但这样做会导致错误,因为 RangeAreas 属性和方法将表现为如同新项目并不存在一样。 例如,areaCount 属性不包含通过这种方法推送的区域,并且如果 index 大于 areasCount-1,则 RangeAreas.getItemAt(index) 将引发错误。 同样,删除 RangeAreas.areas.items 数组中的 Range 对象(通过获取对它的引用并调用其 Range.delete 方法)也会导致错误:尽管 Range 对象已被删除,但父 RangeAreas 对象的属性和方法将表现为或尝试表现为如同它仍然存在一样。 例如,如果你的代码调用 RangeAreas.calculate,Office 将尝试计算区域,但这会引发错误,因为区域对象并不存在。

在多个区域设置属性

RangeAreas 对象上设置属性会在 RangeAreas.areas 集合中的所有区域上设置相应的属性。

以下是在多个区域上设置属性的示例。 函数将突出显示区域 F3:F5H3:H5

await Excel.run(async (context) => {
    let sheet = context.workbook.worksheets.getActiveWorksheet();
    let rangeAreas = sheet.getRanges("F3:F5, H3:H5");
    rangeAreas.format.fill.color = "pink";

    await context.sync();
});

此示例适用于可以对传递给 getRanges 的区域地址进行硬编码或在运行时轻松进行计算的应用场景。 一些适用的应用场景包括:

  • 代码在已知模板的上下文中运行。
  • 代码在导入数据的上下文中运行,其中数据架构是已知的。

与 合并RangeAreasgetSpecialCells

RangeAreas在应用格式或验证之前,仅筛选到与条件(如公式)匹配的单元格。

await Excel.run(async (context) => {
    const sheet = context.workbook.worksheets.getActiveWorksheet();

    // Two discontiguous vertical bands.
    const targets = sheet.getRanges("A1:A100, C1:C100");

    // Narrow to only the formula cells within those bands.
    const formulaCells = targets.getSpecialCells(Excel.SpecialCellType.formulas);
    formulaCells.format.fill.color = "lightYellow";
    await context.sync();
});

从多个区域获取特殊单元格

RangeAreas 对象上的 getSpecialCellsgetSpecialCellsOrNullObject 方法与 Range 对象上的同名方法工作原理类似。 这些方法从 RangeAreas.areas 集合中所有区域返回包含指定特征的单元格。 有关特殊单元格的更多详细信息,请参阅 查找区域中的特殊单元格

调用 RangeAreas 对象上的 getSpecialCellsgetSpecialCellsOrNullObject 方法时:

  • 如果传递 Excel.SpecialCellType.sameConditionalFormat 作为第一个参数,该方法返回具有相同条件格式的所有单元格作为 RangeAreas.areas 集合第一个区域左上角单元格。
  • 如果传递 Excel.SpecialCellType.sameDataValidation 作为第一个参数,该方法返回具有相同数据验证规则的所有单元格作为 RangeAreas.areas 集合第一个区域左上角单元格。

读取 RangeAreas 的属性

读取 RangeAreas 的属性值时须小心操作,因为对于 RangeAreas 内的不同区域,给定的属性可能具有不同的值。 一般规则是,如果可以返回一致的值,则系统会返回该值。 例如,在以下代码中,粉色 (#FFC0CB 的 RGB 代码) 并且 true 将记录到控制台,因为 对象中的 RangeAreas 两个区域都有粉红色填充,并且都是整个列。

await Excel.run(async (context) => {
    let sheet = context.workbook.worksheets.getActiveWorksheet();

    // The ranges are the F column and the H column.
    let rangeAreas = sheet.getRanges("F:F, H:H");  
    rangeAreas.format.fill.color = "pink";

    rangeAreas.load("format/fill/color, isEntireColumn");
    await context.sync();

    console.log(rangeAreas.format.fill.color); // #FFC0CB
    console.log(rangeAreas.isEntireColumn); // true
});

由于属性值可能不同,因此请记住这些简单的规则。

  • 布尔属性 true 仅在所有范围内为 true 时为 ,否则为 false
  • address 始终返回逗号分隔的地址字符串。
  • 其他属性为 , null 除非所有区域共享相同的值。

例如,以下代码将创建 RangeAreas,其中只有一个区域是整列,并且只有一个区域具有粉色填充。 控制台将为填充颜色显示 null,为 isEntireRow 属性显示 false,并为 address 属性显示“Sheet1!F3:F5, Sheet1!H:H”(假设工作表名称为“Sheet1”)。

await Excel.run(async (context) => {
    let sheet = context.workbook.worksheets.getActiveWorksheet();
    let rangeAreas = sheet.getRanges("F3:F5, H:H");

    let pinkColumnRange = sheet.getRange("H:H");
    pinkColumnRange.format.fill.color = "pink";

    rangeAreas.load("format/fill/color, isEntireColumn, address");
    await context.sync();

    console.log(rangeAreas.format.fill.color); // null
    console.log(rangeAreas.isEntireColumn); // false
    console.log(rangeAreas.address); // "Sheet1!F3:F5, Sheet1!H:H"
});

另请参阅