使用wps 建设宏当前工作簿中所有工作表表头占4行,跳过每张表的最后一行并合并所有工作表,并将内容输出到一张新表命名为“四好合并”,并在追加一列注明源表名,比较合并后表内第二列数据,将重复数据所在行所有数据输出到一张新表,并命名为“四好重复”,并在最后统计重复数据相关信息
时间: 2025-07-20 08:26:31 浏览: 6
<think>我们使用WPS JS宏来实现以下任务:
1. 合并当前工作簿中所有工作表(跳过隐藏工作表),每张工作表表头占4行(即从第5行开始读取数据),并跳过每张表的最后一行。
2. 在合并后的数据中追加一列注明源表名。
3. 将合并后的数据输出到新表“四好合并”。
4. 比较合并后表内第二列(即B列)数据,将重复数据所在行的所有数据输出到新表“四好重复”。
5. 在“四好重复”工作表的最后统计重复数据相关信息(例如重复值、重复次数等)。
注意:整个过程不生成新的工作簿,都在当前工作簿内操作。
我们将分步骤实现:
步骤1:创建“四好合并”工作表,并合并数据。
步骤2:创建“四好重复”工作表,提取重复行并输出。
步骤3:在“四好重复”工作表底部添加重复数据的统计信息。
由于WPS JS宏与Excel VBA有相似之处,但语法是JavaScript,我们将使用WPS提供的JS API。
注意:在WPS中,索引从1开始,而JavaScript数组索引从0开始,因此需要注意转换。
我们将编写以下函数:
- 主函数:协调整个流程。
- 创建合并表函数:遍历所有工作表,合并数据到“四好合并”。
- 创建重复数据表函数:从“四好合并”中提取重复行到“四好重复”。
- 添加统计信息函数:在“四好重复”表底部添加统计。
另外,注意避免重复创建同名工作表,因此先删除已存在的表(如果存在)。
由于WPS JS宏中,删除工作表可能会引发错误,我们需要捕获异常。
代码实现如下:</think># WPS JS宏实现工作表合并与重复数据分析
下面是一个完整的WPS JS宏解决方案,用于合并当前工作簿中所有工作表,添加源表名,识别重复数据,并生成统计信息。
```javascript
function MergeAndAnalyzeSheets() {
const wb = Application.ActiveWorkbook;
try {
Application.ScreenUpdating = false; // 提高性能
// 步骤1: 创建"四好合并"表
const mergedSheet = CreateMergedSheet(wb);
// 步骤2: 创建"四好重复"表
const duplicateSheet = CreateDuplicateSheet(wb, mergedSheet);
// 步骤3: 添加重复数据统计
AddDuplicateStatistics(duplicateSheet);
Application.StatusBar = "操作完成!已创建'四好合并'和'四好重复'工作表";
} catch (e) {
Application.StatusBar = "发生错误: " + e.message;
} finally {
Application.ScreenUpdating = true;
}
}
// 创建合并表
function CreateMergedSheet(wb) {
// 删除可能已存在的旧表
DeleteSheetIfExists(wb, "四好合并");
// 创建新表
const mergedSheet = wb.Sheets.Add();
mergedSheet.Name = "四好合并";
mergedSheet.Move(wb.Sheets[wb.Sheets.Count]); // 移到工作表末尾
// 添加标题
mergedSheet.Range("A1").Value = "四好合并数据表";
mergedSheet.Range("A1").Font.Bold = true;
mergedSheet.Range("A1").Font.Size = 16;
mergedSheet.Range("A1").HorizontalAlignment = -4108; // 居中
// 初始化合并数据
let allData = [];
let headersAdded = false;
// 遍历所有工作表
for (let i = 1; i <= wb.Sheets.Count; i++) {
const sheet = wb.Sheets.Item(i);
// 跳过隐藏工作表
if (sheet.Visible !== -1) continue;
// 获取已使用区域
const usedRange = sheet.UsedRange;
if (!usedRange || usedRange.Count === 0) continue;
// 获取数据数组
const data = usedRange.Value;
const rowCount = data.length;
// 跳过表头(前4行)和最后一行
const startRow = 4; // 第5行开始(索引4)
const endRow = rowCount - 2; // 倒数第二行(索引length-2)
if (startRow <= endRow) {
// 如果是第一个工作表,添加表头
if (!headersAdded && rowCount > 0) {
const headers = data[0].slice(); // 复制第一行作为表头
headers.push("源表名"); // 添加源表名列
allData.push(headers);
headersAdded = true;
}
// 处理数据并添加源表名
for (let r = startRow; r <= endRow; r++) {
if (r >= data.length) continue; // 确保行存在
const rowData = data[r].slice(); // 复制行数据
rowData.push(sheet.Name); // 添加源表名
allData.push(rowData);
}
}
}
// 写入合并数据
if (allData.length > 0) {
// 写入数据
const outputRange = mergedSheet.Range(
mergedSheet.Cells(3, 1),
mergedSheet.Cells(3 + allData.length - 1, allData[0].length)
);
outputRange.Value = allData;
// 设置格式
outputRange.Borders.LineStyle = 1; // 添加边框
mergedSheet.Columns.AutoFit(); // 自动调整列宽
// 设置表头格式
if (allData.length > 0) {
mergedSheet.Rows("3:3").Font.Bold = true; // 表头加粗
mergedSheet.Rows("3:3").Interior.Color = 13434828; // 浅蓝色背景
// 冻结表头
mergedSheet.Activate();
mergedSheet.Range("A4").Select();
Application.ActiveWindow.FreezePanes = true;
}
} else {
mergedSheet.Range("A3").Value = "没有找到可合并的数据";
}
return mergedSheet;
}
// 创建重复数据表
function CreateDuplicateSheet(wb, mergedSheet) {
// 删除可能已存在的旧表
DeleteSheetIfExists(wb, "四好重复");
// 创建新表
const duplicateSheet = wb.Sheets.Add();
duplicateSheet.Name = "四好重复";
duplicateSheet.Move(wb.Sheets[wb.Sheets.Count]); // 移到工作表末尾
// 添加标题
duplicateSheet.Range("A1").Value = "四好重复数据表";
duplicateSheet.Range("A1").Font.Bold = true;
duplicateSheet.Range("A1").Font.Size = 16;
duplicateSheet.Range("A1").HorizontalAlignment = -4108; // 居中
// 获取合并表数据
const mergedData = mergedSheet.UsedRange.Value;
if (!mergedData || mergedData.length < 2) {
duplicateSheet.Range("A3").Value = "没有重复数据";
return duplicateSheet;
}
// 找出第2列(B列)的重复值
const colIndex = 1; // 第2列索引(0-based)
const valueMap = new Map(); // 使用Map存储值及其行索引
// 第一遍:统计每个值出现的行
for (let r = 1; r < mergedData.length; r++) { // 跳过标题行
const value = mergedData[r][colIndex];
if (value === null || value === undefined) continue;
if (!valueMap.has(value)) {
valueMap.set(value, []);
}
valueMap.get(value).push(r);
}
// 收集重复行
const duplicateRows = [];
const duplicateValues = [];
for (const [value, rows] of valueMap) {
if (rows.length > 1) { // 重复值
duplicateValues.push(value);
for (const row of rows) {
duplicateRows.push(mergedData[row]);
}
}
}
// 如果没有重复数据
if (duplicateRows.length === 0) {
duplicateSheet.Range("A3").Value = "没有重复数据";
return duplicateSheet;
}
// 写入重复数据
// 添加标题行
const headers = mergedData[0];
duplicateSheet.Range("A3").Resize(1, headers.length).Value = [headers];
// 写入重复数据
const outputRange = duplicateSheet.Range(
duplicateSheet.Cells(4, 1),
duplicateSheet.Cells(4 + duplicateRows.length - 1, headers.length)
);
outputRange.Value = duplicateRows;
// 设置格式
outputRange.Borders.LineStyle = 1;
duplicateSheet.Columns.AutoFit();
// 设置表头格式
duplicateSheet.Rows("3:3").Font.Bold = true;
duplicateSheet.Rows("3:3").Interior.Color = 13434828; // 浅蓝色背景
// 高亮显示重复值
const colLetter = String.fromCharCode(65 + colIndex); // B列
const duplicateRange = duplicateSheet.Range(
`${colLetter}4:${colLetter}${3 + duplicateRows.length}`
);
duplicateRange.Interior.Color = 13431551; // 浅黄色背景
// 冻结表头
duplicateSheet.Activate();
duplicateSheet.Range("A4").Select();
Application.ActiveWindow.FreezePanes = true;
return duplicateSheet;
}
// 添加重复数据统计信息
function AddDuplicateStatistics(sheet) {
if (!sheet || !sheet.UsedRange || sheet.UsedRange.Count === 0) return;
// 获取重复数据
const data = sheet.UsedRange.Value;
if (data.length < 4) return; // 无重复数据
// 统计重复项(第2列)
const colIndex = 1; // 第2列(B列)
const valueCount = new Map();
// 统计重复次数(从第4行开始)
for (let r = 3; r < data.length; r++) {
const value = data[r][colIndex];
if (value === null || value === undefined) continue;
if (!valueCount.has(value)) {
valueCount.set(value, 0);
}
valueCount.set(value, valueCount.get(value) + 1);
}
// 找到最后一行
const lastRow = sheet.UsedRange.Row + sheet.UsedRange.Rows.Count;
// 添加统计标题
sheet.Cells(lastRow + 2, 1).Value = "重复数据统计:";
sheet.Cells(lastRow + 2, 1).Font.Bold = true;
sheet.Cells(lastRow + 2, 1).Font.Size = 12;
// 写入统计信息
let rowOffset = 3;
for (const [value, count] of valueCount) {
sheet.Cells(lastRow + rowOffset, 1).Value = `值: ${value}`;
sheet.Cells(lastRow + rowOffset, 2).Value = `重复次数: ${count}`;
rowOffset++;
}
// 添加总计
sheet.Cells(lastRow + rowOffset, 1).Value = "总计:";
sheet.Cells(lastRow + rowOffset, 1).Font.Bold = true;
sheet.Cells(lastRow + rowOffset, 2).Value = `重复数据行数: ${valueCount.size} 个值, ${data.length - 3} 行`;
// 设置统计区域格式
const startRow = lastRow + 2;
const endRow = lastRow + rowOffset;
const statRange = sheet.Range(
sheet.Cells(startRow, 1),
sheet.Cells(endRow, 2)
);
statRange.Borders.LineStyle = 1;
statRange.Font.Bold = true;
statRange.Interior.Color = 13434828; // 浅蓝色背景
// 自动调整列宽
sheet.Columns("A:B").AutoFit();
}
// 辅助函数:删除已存在的工作表
function DeleteSheetIfExists(wb, sheetName) {
try {
const sheet = wb.Sheets.Item(sheetName);
sheet.Delete();
return true;
} catch (e) {
// 工作表不存在,忽略错误
return false;
}
}
// 执行主函数
MergeAndAnalyzeSheets();
```
## 代码功能详解
### 1. 主流程 `MergeAndAnalyzeSheets()`
- 禁用屏幕刷新提高性能
- 创建合并表
- 创建重复数据表
- 添加统计信息
- 异常处理和状态更新
### 2. 创建合并表 `CreateMergedSheet()`
- **表头处理**:只从第一个工作表中提取表头
- **数据过滤**:跳过前4行表头和最后一行
- **源表名添加**:在每行末尾添加源工作表名称
- **格式优化**:自动调整列宽、添加边框、冻结表头
### 3. 创建重复数据表 `CreateDuplicateSheet()`
- **重复检测**:使用Map数据结构高效检测重复值
- **高亮显示**:对重复值所在单元格添加黄色背景
- **格式优化**:自动调整列宽、添加边框、冻结表头
### 4. 添加统计信息 `AddDuplicateStatistics()`
- **重复值统计**:计算每个重复值的出现次数
- **数据汇总**:显示重复值总数和重复行总数
- **可视化展示**:使用浅蓝色背景突出统计区域
### 5. 辅助函数 `DeleteSheetIfExists()`
- 安全删除已存在的工作表,避免命名冲突
## 使用说明
1. 打开包含多个工作表的工作簿
2. 确保需要合并的工作表为可见状态(非隐藏)
3. 运行此宏
4. 宏将在当前工作簿内创建两个新表:
- **"四好合并"表**:包含所有工作表的合并数据
- **"四好重复"表**:包含第2列重复的数据行及统计信息
## 工作流程示意图
```mermaid
graph TD
A[开始] --> B[遍历所有工作表]
B --> C{工作表是否可见?}
C -->|是| D[跳过表头4行和最后1行]
C -->|否| B
D --> E[添加源表名列]
E --> F[合并数据到新表]
F --> G[创建'四好合并'表]
G --> H[分析第2列重复数据]
H --> I[创建'四好重复'表]
I --> J[统计重复数据信息]
J --> K[结束]
```
## 统计信息格式
在"四好重复"表底部会生成如下统计信息:
```
重复数据统计:
值: ABC123 重复次数: 3
值: XYZ789 重复次数: 2
总计: 重复数据行数: 2 个值, 5 行
```
## 特点与优势
1. **高效处理**:使用`ScreenUpdating = false`提升性能
2. **智能识别**:自动跳过隐藏工作表
3. **数据完整性**:保留原始数据格式和类型
4. **可视化设计**:使用颜色和格式增强可读性
5. **错误处理**:完善的异常捕获和状态反馈
阅读全文
相关推荐



















