You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OfficeExtension.TrackedObjects跨Word.run上下文操作Range求助

Word加载项:跨上下文选中搜索结果实现方案

问题描述

需要实现Word任务窗格展示搜索结果,点击列表项时选中文档内对应的搜索结果(JavaScript)。尝试使用OfficeExtension.TrackedObjects类跨Word.run上下文访问Range对象,但运行代码时出现ReferenceError: Can't find variable: results错误。

用户原代码:

var items = [];
function basicSearch() {
   Word.run(function (context) {
    const results = context.document.body.search("Online");
    results.load("length, text, items");
     return context.sync().then(function () {
      context.trackedObjects.add(results);
    for (let i = 0; i < results.items.length; i++) {
      let x = results.items[i].text;
      createtable("TestList", i, x, x);
      items.push(results.items[i]);
    }
     });
    return context.sync();
   });
}

function createtable(id, x, y, z) {
  var table = document.getElementById(id);
  var row = table.insertRow(-1);
  var cell1 = row.insertCell(0);
  var cell2 = row.insertCell(1);
  var cell3 = row.insertCell(2);
  cell1.type = "button";
  cell1.onclick = function () { selectrange(x) };
  cell2.type = "button";
  cell2.onclick = function () { selectrange(x) };
  cell3.type = "button";
  cell3.onclick = function () { selectrange(x) };
  cell1.innerHTML = x;
  cell2.innerHTML = y;
  cell3.innerHTML = z;
}


function selectrange(x) {
  results.load("text");
  results.items[x].select();
  results.context.sync();
}

代码问题分析

  1. 变量作用域错误:results是Word.run回调内部的局部变量,外部的selectrange函数无法访问,导致ReferenceError。
  2. TrackedObjects使用不当:
    • 跟踪时机错误:应该在加载对象前就添加到跟踪集合,而非sync之后。
    • 跟踪对象错误:仅跟踪results集合无法确保其内部的items(Range对象)被跨上下文保留,需要逐个跟踪单个Range对象。
  3. 跨上下文操作逻辑错误:selectrange未在新的Word.run上下文中执行操作,直接访问未跟踪的对象会失效。
  4. 存储未跟踪对象:items数组存储的是未被跟踪的Range对象,跨上下文访问时会丢失与Office文档的关联。

完整可运行示例

<!-- 任务窗格HTML部分 -->
<table id="TestList">
  <tr>
    <th>索引</th>
    <th>文本</th>
    <th>操作</th>
  </tr>
</table>

<script>
// 全局变量存储被跟踪的Range对象数组
var trackedRanges = [];

function basicSearch() {
  Word.run(function (context) {
    // 执行搜索
    const results = context.document.body.search("Online");
    results.load("items");
    
    return context.sync().then(function () {
      // 逐个跟踪每个搜索结果的Range对象
      for (let i = 0; i < results.items.length; i++) {
        const range = results.items[i];
        // 加载需要的属性(比如text)
        range.load("text");
        // 添加到跟踪集合,确保跨上下文有效
        context.trackedObjects.add(range);
        // 存储到全局数组
        trackedRanges.push(range);
        
        // 生成列表项
        createTableItem("TestList", i, range.text);
      }
    });
  })
  .catch(function (error) {
    console.log(error);
    if (error instanceof OfficeExtension.Error) {
      console.log("Debug info: " + JSON.stringify(error.debugInfo));
    }
  });
}

function createTableItem(tableId, index, text) {
  const table = document.getElementById(tableId);
  const row = table.insertRow(-1);
  
  const indexCell = row.insertCell(0);
  const textCell = row.insertCell(1);
  const actionCell = row.insertCell(2);
  
  indexCell.textContent = index;
  textCell.textContent = text;
  
  // 创建按钮并绑定点击事件
  const selectBtn = document.createElement("button");
  selectBtn.textContent = "选中";
  selectBtn.onclick = function() { selectRange(index); };
  actionCell.appendChild(selectBtn);
}

function selectRange(index) {
  // 在新的Word.run上下文中操作跟踪的Range对象
  Word.run(function (context) {
    // 获取全局数组中被跟踪的Range
    const targetRange = trackedRanges[index];
    // 执行选中操作
    targetRange.select();
    
    return context.sync();
  })
  .catch(function (error) {
    console.log(error);
    if (error instanceof OfficeExtension.Error) {
      console.log("Debug info: " + JSON.stringify(error.debugInfo));
    }
  });
}

// 可选:当不再需要跟踪对象时,清理跟踪集合
function cleanupTrackedObjects() {
  Word.run(function (context) {
    trackedRanges.forEach(range => {
      context.trackedObjects.remove(range);
    });
    trackedRanges = [];
    return context.sync();
  });
}
</script>

关键说明

  • TrackedObjects核心作用:将Office.js对象(如Range)与上下文解绑,允许在多个Word.run调用中保持对象有效性,避免"对象已失效"错误。
  • 逐个跟踪单个对象:集合对象(如SearchResults)的跟踪不会自动应用到其内部元素,必须单独跟踪每个需要跨上下文使用的Range对象。
  • 全局存储跟踪对象:通过全局数组保存被跟踪的Range,确保点击事件触发时能访问到有效对象。
  • 错误处理:所有Word.run调用都应添加catch块,便于调试Office.js相关错误。
  • 资源清理:当不再需要使用跟踪对象时,调用context.trackedObjects.remove清理,避免内存泄漏。

内容的提问来源于stack exchange,提问作者FelixKing

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 21:25:16