[TOC]
> Sat May 01 2021 20:55:51 GMT+0800 (GMT+08:00)
为工作表创建目录(实质是跳转到指定工作表的超链接),我们用宏的方式批量创建,并利用工作表新增、删除、重命名事件自动更新目录。
> 跨工作簿的链接无法更新,因为工作表事件仅针对当前工作簿(除非双向部署)
其实吧,目录就是由超链接构成的,当工作表变多的时候定位比较困难,有个目录就很方便了。
这里先提供低级版的(占用单元格)
> 可能会出加载项版的,窗体版的因 WPS JSAPI 缺少 UserForm 的说明,还不知道如何进行。
## 低配版目录
> 会占用单元格。后续的章节提供“中配版”——窗体目录。
为 WPS 表格 工作表插入目录
注意,**目录所在列不应再填入数据(它们会随工作表数量变化而变化),有被覆盖、清除的可能性。**
使用方法:
* 复制当前代码到 WPS JS宏编辑器的模块内。
* 新建你自己的宏,然后通过 new 使用。
* 要想变成"智能"目录,请将宏加入到Application、Workbook级别的事件内部。
> "智能":随工作簿工作表的增、删、隐藏(取消隐藏)而更新目录。
**Kind**: global class
* [shSummary](#shSummary)
* [new shSummary(anchor, options)](#new_shSummary_new)
* [.selectRange](#shSummary+selectRange)
* [.addToFirRange](#shSummary+addToFirRange)
* [.sHname](#shSummary+sHname)
* [.sH](#shSummary+sH)
* [.wb](#shSummary+wb)
* [._getWbNames()](#shSummary+_getWbNames)
* [._getSheetNames(wbName, ignoreHiddenOne)](#shSummary+_getSheetNames)
* [._clearRanges()](#shSummary+_clearRanges)
* [.thisWorkbookSummary()](#shSummary+thisWorkbookSummary)
* [.otherWorkbookSummary()](#shSummary+otherWorkbookSummary)
* [.addSummary()](#shSummary+addSummary)
<a name="new_shSummary_new"></a>
### new shSummary(anchor, options)
| Param | Type | Description |
| --- | --- | --- |
| anchor | <code>string</code> | 目录插入点,例如:'Sheet1!A1' |
| options | <code>object</code> | |
| options.selectRange | <code>string</code> | 跳转到的具体单元格名,例如:'A3',即跳转后被选中的单元格,默认每个工作表的 A1 单元格。 |
| options.useNameAsLinkText | <code>boolean</code> | 仅使用工作表名称作为链接文本(false则带`selectRange`的值,true则只显示表名),其他工作簿的链接始终带有工作簿名(如果`forAllOpenedWorkbook`为 true的话)。 |
| options.ignoreHiddenSheets | <code>boolean</code> | 是否忽略隐藏工作表,默认 true:忽略(因为隐藏的工作表是无法显示的,结果是“死链”点击时会提示引用无效) |
| options.forAllOpenedWorkbook | <code>boolean</code> | 是否将所有的打开的工作簿都纳入目录(注意:本工作簿以外的工作簿的工作表事件无法监测,但会在生成更新本工作簿目录时跑一遍其他工作簿),默认 false;不加入目录。 |
**Example**
```js
function _m_addSummary(){
let summary = new shSummary("Sheet1!A1",{selectRange="A1"}) // 具体配置可以自行查看文档(都有默认值,可不配置,仅提供目录插入点即可)
summary.addSummary() // 创建目录
}
```
<a name="shSummary+selectRange"></a>
### shSummary.selectRange
链接目标单元格
**Kind**: instance property of [<code>shSummary</code>](#shSummary)
<a name="shSummary+addToFirRange"></a>
### shSummary.addToFirRange
插入目录区域的第一格
**Kind**: instance property of [<code>shSummary</code>](#shSummary)
<a name="shSummary+sHname"></a>
### shSummary.sHname
工作表名
**Kind**: instance property of [<code>shSummary</code>](#shSummary)
<a name="shSummary+sH"></a>
### shSummary.sH
目录所在工作表
**Kind**: instance property of [<code>shSummary</code>](#shSummary)
<a name="shSummary+wb"></a>
### shSummary.wb
目录所在工作簿
**Kind**: instance property of [<code>shSummary</code>](#shSummary)
<a name="shSummary+_getWbNames"></a>
### shSummary.\_getWbNames()
获取当前打开的所有工作簿名称(新建未保存工作簿将忽略)
**Kind**: instance method of [<code>shSummary</code>](#shSummary)
<a name="shSummary+_getSheetNames"></a>
### shSummary.\_getSheetNames(wbName, ignoreHiddenOne)
获取某一工作簿所有工作表名称。
**Kind**: instance method of [<code>shSummary</code>](#shSummary)
| Param | Type | Description |
| --- | --- | --- |
| wbName | <code>string</code> | 工作簿名称 |
| ignoreHiddenOne | <code>boolean</code> | 是否忽略隐藏工作表 |
<a name="shSummary+_clearRanges"></a>
### shSummary.\_clearRanges()
清除目录
**Kind**: instance method of [<code>shSummary</code>](#shSummary)
<a name="shSummary+thisWorkbookSummary"></a>
### shSummary.thisWorkbookSummary()
创建本(宏所在的)工作簿的目录
**Kind**: instance method of [<code>shSummary</code>](#shSummary)
<a name="shSummary+otherWorkbookSummary"></a>
### shSummary.otherWorkbookSummary()
将其他工作簿纳入目录
**Kind**: instance method of [<code>shSummary</code>](#shSummary)
<a name="shSummary+addSummary"></a>
### shSummary.addSummary()
创建目录
**Kind**: instance method of [<code>shSummary</code>](#shSummary)
## 代码
```js
/**
* 为 WPS 表格 工作表插入目录
*
* 注意,**目录所在列不应再填入数据(它们会随工作表数量变化而变化),有被覆盖、清除的可能性。**
*
*
* 使用方法:
*
* * 复制当前代码到 WPS JS宏编辑器的模块内。
* * 新建你自己的宏,然后通过 new 使用。
* * 要想变成"智能"目录,请将宏加入到Application、Workbook级别的事件内部。
*
* > "智能":随工作簿工作表的增、删、隐藏(取消隐藏)而更新目录。
*
* @example
*
* function _m_addSummary(){
* let summary = new shSummary("Sheet1!A1",{selectRange="A1"}) // 具体配置可以自行查看文档(都有默认值,可不配置,仅提供目录插入点即可)
* summary.addSummary() // 创建目录
* }
*
* @class
*/
class shSummary {
/**
*
* @param {string} anchor 目录插入点,例如:'Sheet1!A1'
* @param {object} options
* @param {string} options.selectRange 跳转到的具体单元格名,例如:'A3',即跳转后被选中的单元格,默认每个工作表的 A1 单元格。
* @param {boolean} options.useNameAsLinkText 仅使用工作表名称作为链接文本(false则带`selectRange`的值,true则只显示表名),其他工作簿的链接始终带有工作簿名(如果`forAllOpenedWorkbook`为 true的话)。
* @param {boolean} options.ignoreHiddenSheets 是否忽略隐藏工作表,默认 true:忽略(因为隐藏的工作表是无法显示的,结果是“死链”点击时会提示引用无效)
* @param {boolean} options.forAllOpenedWorkbook 是否将所有的打开的工作簿都纳入目录(注意:本工作簿以外的工作簿的工作表事件无法监测,但会在生成更新本工作簿目录时跑一遍其他工作簿),默认 false;不加入目录。
*/
constructor(anchor, options = { selectRange: "A1", useNameAsLinkText: true, ignoreHiddenSheets: true, forAllOpenedWorkbook: false }) {
let a, b, c;
if (options.useNameAsLinkText == undefined || options.useNameAsLinkText == null) {
a = true
} else {
a = options.useNameAsLinkText
}
if (options.ignoreHiddenSheets == undefined || options.ignoreHiddenSheets == null) {
b = true
} else {
b = options.ignoreHiddenSheets
}
if (options.forAllOpenedWorkbook == undefined || options.forAllOpenedWorkbook == null) {
c = false
} else {
c = options.forAllOpenedWorkbook
}
/** 链接目标单元格*/
this.selectRange = options.selectRange || "A1"; // 默认为 A1
/** 插入目录区域的第一格*/
this.addToFirRange = Range(anchor)
/** 工作表名*/
this.sHname = this.addToFirRange.Parent.Name;
/** 目录所在工作表*/
this.sH = Worksheets.Item(this.sHname)
this.wbName = this.sH.Parent.Name;
/** 目录所在工作簿*/
this.wb = Workbooks.Item(this.wbName)
this.useNameAsLinkText = a;
this.ignoreHiddenSheets = b;
this.forAllOpenedWorkbook = c;
/* this.useNameAsLinkText = options.useNameAsLinkText ?? true;
this.ignoreHiddenSheets = options.ignoreHiddenSheets ?? true;
this.forAllOpenedWorkbook = options.forAllOpenedWorkbook ?? false; */
}
/** 获取当前打开的所有工作簿名称(新建未保存工作簿将忽略)*/
_getWbNames() {
let n = [];
for (let i = 1; i <= Application.Workbooks.Count; i++) {
let item = Workbooks.Item(i).Name
if (item !== "") {
n.push(Workbooks.Item(i).Name)
}
}
return n;
}
/**
* 获取某一工作簿所有工作表名称。
* @param {string} wbName 工作簿名称
* @param {boolean} ignoreHiddenOne 是否忽略隐藏工作表
*/
_getSheetNames(wbName, ignoreHiddenOne) {
let wb = wbName || this.wbName
let curWb = Workbooks.Item(wb)
let n = []
for (let i = 1; i <= curWb.Worksheets.Count; i++) {
let item = curWb.Worksheets.Item(i)
let ishidden = item.Visible
let iname = item.Name
if (ishidden && !ignoreHiddenOne) {
n.push([wbName, iname])
}
if (ishidden) {
n.push([wbName, iname])
}
}
return n;
}
/**
* 清除目录
*/
_clearRanges() {
let summRang = this.addToFirRange;
let nextRisBlank = summRang.Offset(1, 0).Value() == null;
if (!nextRisBlank) {
Range(summRang, summRang.End(xlDown)).Value2 = undefined;
}
}
/**
* 创建本(宏所在的)工作簿的目录
*/
thisWorkbookSummary() {
let TR = this.selectRange
let SR = this.addToFirRange
let igHidden = this.ignoreHiddenSheets
let useName = this.useNameAsLinkText
this._clearRanges()
// 开始写入
let links = this._getSheetNames(this.wbName, igHidden)
if (links.length == 0) { return }
for (let i = 0; i < links.length; i++) {
let link_text;
let item = links[i][1]
if (useName) {
link_text = item
} else {
link_text = `${item}!${TR}`
}
let fo = {
link: `${item}!${TR}`,
text: link_text
}
let summitem = SR.Offset(i, 0)
let tSh = this.sH
tSh.Hyperlinks.Add(summitem, "", fo.link, "", fo.text)
}
}
/**
* 将其他工作簿纳入目录
*/
otherWorkbookSummary() {
if (this.forAllOpenedWorkbook == false) {
return
}
let allWb = this._getWbNames()
let fo = allWb.indexOf(this.sHname)
allWb.splice(fo, 1)// 剔除当前工作簿
let allWb_sheets = []
for (let i = 1; i <= a.length; i++) {
let item = a[i]
let item_SheetNames = this._getSheetNames(item, this.ignoreHiddenSheets)
allWb_sheets.push(item_SheetNames)
}
// 查找目录末尾单元格
let lastRange = this.addToFirRange.End(xlDown)
for (let p = 0; p < allWb_sheets.length; p++) {
let ptem = allWb_sheets[i] // [wbname,shname]
let summaryLi_text
if (this.useNameAsLinkText) {
summaryLi_text = ptem.join('!')
} else {
summaryLi_text = `${ptem.join('!')}${this.selectRange}`
}
let summaryLi = {
text: summaryLi_text,
link: `[${ptem[0]}]${ptem[1]}!${this.selectRange}`
}
let nextSummaryAddTo = lastRange.Item(i, 0)
let summarySh = this.sH;
summarySh.Hyperlinks.Add(nextSummaryAddTo, "", summaryLi.link, "", summaryLi.text)
}
}
/**
* 创建目录
*/
addSummary() {
// 先添加本工作表
this.thisWorkbookSummary()
// 接着补其他工作簿
this.otherWorkbookSummary()
}
}
```
- 1-概述
- 2-升级吧
- 3-阅读指南
- 4-答萌新问
- 5-iTool 加载项
- 6-iTool下载安装
- 7-Gitee token 生成
- 8-喜欢用表格当下载器的小伙伴看过来
- 9-喜欢扒数据的小伙伴跟上
- 10-了解 WPS JS宏编辑器
- 11-快捷键
- 12-立即窗口
- 13-断点调试
- 14-如何在 VB、JS 环境之间切换
- 15-如何快速进入使用、编辑JS宏
- 16-使用宏编辑器需要注意的点
- 17-保存&导出&使用宏
- 18-全局隐藏函数名(仅WPS)
- 19-如何命名自己的全局函数的名称(宏名)
- 20-如何使用别人写的宏
- 21-如何修改录制好的宏
- 22-WPS 宏中可用的 JS 库
- 23-将 Lodash 装进 WPS JS宏
- 24-使用 Moment.js
- 25-用 Papa Parse 进行JSON、CSV 互转
- 26-Lodash.js源码
- 27-Moment.js源码
- 28-papaparse.js源码
- 29-WPS JSAPI
- 30-对象名中英文对照表
- 31-事件汇总
- 32-对象属性的使用
- 33-从 Excel VBA 宏到 WPS JS宏
- 34-从 Visual Basic Script 转到 JavaScript
- 35-fileSystem文件系统
- 36-Open 与 Write
- 37-将内容写入 TXT 文件
- 38-Dir 函数读文件夹
- 39-关于颜色
- 40-表单、ActiveX控件
- 41-控件样式
- 42-数据绑定
- 43-解决“我是谁,我在哪”的问题
- 44-绕坑:那些奇奇怪怪的问题
- 45-警惕:宏操作对象限制
- 46-别造轮子了,用现成的吧
- 47-Item 属性快把你逼疯了吧
- 48-空单元格的值是什么
- 49-单元格区域(多个单元格)的值
- 50-编译参数禁止项开关导致的问题
- 51-代码上下文带来的问题
- 52-API 中方法函数参数的问题
- 53-结束进程吧
- 54-福利:WPS 表格 Modules 开箱即用
- 55-最后一格可用空单元格总在变?帮你追上它
- 56-判断一个单元格是不是在指定区域里
- 57-工作表类
- 58-单元格读取封装
- 59-WPS JS 加载项
- 60-加载项开发绕坑
- 61-开发
- 62-部署、分发
- 63-安装、卸载加载项
- 64-更智能的处理加载项的安装
- 65-WPS 控件点击之后报错:Error: arguments error
- 66-对 wpsjs npm 包的一些改进
- 67-加载项中 TaskPane 和 Dialog之间的差别
- 68-怎么解决 ShowDialog 窗口无限弹出?
- 69-Custom UI
- 70-控制控件在不同应用上的显示和隐藏
- 71-本地化处理
- 72-加载项示例和自建工具
- 73-如何保证在无 WEB 环境下加载项依旧正常工作
- 74-WPS 对 customUI 组件的支持程度
- 75-如何让加载项的 input 类元素准确关联 SheetSelectionChange 事件
- 76-从零开始开发一个简易的 JS 加载项
- 77-搭建项目
- 78-插件规划
- 79-第一个 ribbonUI 控件
- 80-第一个弹窗 confirm
- 81-第一个 Web 弹窗: ShowDialog
- 82-第一个侧栏 TaskPane
- 83-打包第一个版本
- 84-RibbonUI 控件不完全示例
- 85-基本结构
- 86-WPS JS加载项 RibbonUI 控件 API 与 VBE API 的差别
- 87-控件属性设计"误区"
- 88-主控:有条件加载 customUI.onLoad
- 89-布局盒子(父元素)
- 90-控件属性·事件·动作
- 91-简单示例
- 92-WPS 表格
- 93-单元格
- 94-如何描述单元格对象
- 95-单元格读写
- 96-单元格信息
- 97-关于合并单元格
- 98-合并单元格,I hate it!
- 99-单元格复制粘贴
- 100-选择性粘贴
- 101-自定义序列
- 102-单元格的删除/插入
- 103-单元格填充
- 104-单元格去重和高亮突出显示
- 105-单元格条件格式
- 106-数据透视表
- 107-自动筛选
- 108-通过 JS 宏处理 DISPIMG 函数
- 109-计时器:OnTime 和 Wait
- 110-探索: Range.Offset 如何安全“漂移”
- 111-表格自动化事件
- 112-创建一个事件记录日志工作表
- 113-实现类 Vlookup 单条件提取内容
- 114-代码和宏说明
- 115-创建工作表目录
- 116-将所有批注汇总成列表
- 117-JS宏代码
- 118-剥离 UDF 公式(数值化处理)
- 119-单元格区域转 JSON 并写入文件
- 120-JS宏代码
- 121-设置工作表标签(Tab)颜色
- 122-插入日历 calendar
- 123-再偷懒些
- 124-示例代码
- 125-WPS 表格函数表
- 126-JS 宏中可用的表格函数
- 127-WPS 表格-工作表-工作簿
- 128-通用简易工作表目录
- 129-工作表排序
- 130-巧用 Parent 进行对象锁定
- 131-我想要的 WPS 表格函数
- 132-单元格字符匹配统计
- 133-基于正则表达式的 Replace
- 134-身份证
- 135-控件 API 精讲(以表格为例)
- 136-窗体控件
- 137-ActiveX 控件
- 138-WPS 文档
- 139-"定位"专题
- 140-视图切换
- 141-别被 paragraph 骗了
- 142-无效脚注、尾注检测
- 143-获取所有标题
- 144-答网友问
- 145-轮序键入——键入完成自动切换单元格
- 146-又是一个很会偷懒的 Bigger Cousin
- 147-给你演示什么叫"画地为牢"
- 148-示例代码
- 149-如何批量超链接到同名的sheet?
- 150-如何将一个表中一个列的值合并到另一个表中的一个单元格中?
- 151-多个字符都往一个单元格里塞
- 152-wps如何将A列里包含B列的单元格高亮显示?
- 153-excel中随着打印份数渐序更新日期的函数?
- 154-就是玩儿
- 155-挖宝:寻找API文档中没有的接口
- 156-通过 Application 对象的属性获取信息
- 157-呵呵,失败的抽奖!
- 158-哪里不会点哪里
- 159-芝麻开门
- 160-乖,别闹,Stay here
- 161-JS宏 实现【WPS 表格 VIP 专享】功能挑战
- 162-工作表批量重命名
- 163-工作表标签批量着色
- 164-工作表拆分为工作簿
- 165-工作簿合并为工作表
- 166-WPS 表格 API 参考
- 167-Application.InpuBox
- 168-Worksheet(s)、Sheets
- 169-Range.End 精讲
- 170-Cells 精讲
- 171-WPS 文字 API 参考
- 172-怎么快速掌握 文字 宏API
- 173-WPS 宏编辑器 API 参考
- 174-InputBox
- 175-MsgBox
- 176-alert
- 177-WPS 扩展 API 参考
- 178-WebShape
- 179-通用 API 参考
- 180-WPS Office文件上传&下载 JavaScript 宏 API
- 181-JS宏API:Office(全网独一份)
- 182-公共部分
- 183-文字独有
- 184-JavaScript 语言基础笔记
- 185-国际化API(格式化处理)
- 186-数组
- 187-日期时间
- 188-数学计算
- 189-外接输入设备(读卡器、扫码枪)数据写进 WPS 可行性
- 190-鸣谢