使用wps的JS宏处理工作簿,该工作簿中的表中前三行为表头,数据行出现在第四行,现在将该工作簿中所有除最后三行的表格内容合并到一张新工作表中,将其命名为“合并数据”表格,并在最后一列显示数据来源表,并将该列命名为“源表”。在“合并数据”的表格中将第三列数据重复所在行的数据全部输出到一张命名为“日期重复”的新工作表中,在“日期重复”的表格中再将第四列内容重复的数据所在行数据输出到命名为“双重重复”的新工作表中。并分别在“合并数据”表中统计合并数据条数,在“日期重复”表与“双重重复”表下方统计重复日期及次数,并高亮显示大于2次的数据,并同时显示重复行中G列的数据。
时间: 2025-07-20 14:28:54 浏览: 9
<think>由于我们是在WPS的JS宏环境中操作,因此我们将使用WPS提供的API来操作工作簿和工作表。
任务分解:
1. 遍历工作簿中所有的工作表(排除“合并数据”、“日期重复”、“双重重复”等我们即将创建的表,以免重复处理)。
2. 对于每个工作表,跳过前三行表头,从第四行开始读取数据直到倒数第三行(即去掉最后三行)。
3. 将读取的数据添加一列“源表”,值为当前工作表的名称。
4. 将所有工作表的数据合并到一个数组,然后写入到新工作表“合并数据”中。
5. 在“合并数据”表中,统计合并的数据条数(可以直接在某个单元格中写入计数)。
6. 从“合并数据”表中,找出第三列(即C列,因为JS宏中列从1开始)数据重复的行,将这些行(包括所有列)复制到新工作表“日期重复”中。
7. 在“日期重复”表中,统计重复日期及次数,并高亮显示重复次数大于2的日期(注意:这里要求显示重复行中G列的数据,但根据任务描述,我们可能需要同时显示重复日期和对应的G列数据?但任务描述是在表下方统计重复日期及次数,并高亮显示大于2次的数据,同时显示重复行中G列的数据。这里可能需要在统计区域列出重复日期、次数以及对应的G列数据?但具体输出位置未明确,我们按照在表格下方输出统计信息,并高亮显示重复次数大于2的日期所在行?但是注意,任务要求高亮显示的是大于2次的数据,并且显示重复行中G列的数据。这里可能有两种理解:
a) 在“日期重复”表中,将重复日期次数大于2的行高亮,并在统计区域列出这些重复日期、次数以及对应的G列数据(可能是每个重复日期对应多个G列数据,需要展示出来?)
b) 或者,在统计区域只统计重复日期和次数,高亮的是重复日期次数大于2的日期(在统计区域高亮?),同时要求显示重复行中G列的数据(可能是在原表中高亮行,然后G列数据自然就显示了?)
由于任务描述有些模糊,我们按照以下方式处理:
- 在“日期重复”表中,我们将重复日期(第三列)重复的行提取出来形成新表,然后在这个表的下方(从数据行下方开始)统计每个重复日期出现的次数,以及这个重复日期对应的所有G列的值(用逗号分隔?)。同时,对于重复次数大于2的日期,在统计区域中将其所在行高亮(注意:这里统计区域是单独的区域,不是原数据区域,所以高亮的是统计区域中重复次数大于2的那一行)。
8. 在“日期重复”表中,再根据第四列(D列)内容重复的数据所在行,输出到“双重重复”表中。
9. 在“双重重复”表中,同样在下方统计重复日期(这里应该是第四列重复的值)及次数,并高亮显示大于2次的数据,同时显示重复行中G列的数据(同样,在统计区域显示重复值、次数和对应的G列数据)。
注意:由于我们是在JS宏中操作,所以需要用到以下API:
- Application.ActiveWorkbook 获取当前工作簿
- Worksheets 工作表集合
- Range 区域
- 等等
由于代码较长,我们将分步骤编写。
步骤:
1. 创建“合并数据”表,并设置表头(包括原表所有列加上“源表”列)。
2. 循环每个工作表,读取数据,并添加“源表”列,将数据添加到合并数组。
3. 将合并数组写入“合并数据”表。
4. 在“合并数据”表统计总行数(排除表头)并显示在某个位置(比如A1单元格上方或下方,但注意表头占一行,数据从第四行开始?这里合并数据表表头应该是原表前三行?不,根据要求,新表“合并数据”应该包含原表的所有列加上“源表”列,并且表头就是原表前三行加上“源表”列的表头。但是原表每个工作表表头可能相同,我们取第一个工作表的表头?但是要求前三行是表头,所以合并数据表的前三行也是表头,数据从第四行开始。所以统计行数应该是第四行开始的数据行数,我们可以在表头的下方(比如第四行开始)写数据,然后在表头上面写统计?比如在A1单元格写“总数据条数:xxx”)。
5. 创建“日期重复”表,从“合并数据”表中读取数据,找出第三列重复的行(注意:重复是指在这一列中出现过两次或以上)。注意,重复的行我们都要提取出来,包括第一次出现和后面的重复出现。
6. 将重复的行写入“日期重复”表,同样包含表头(即合并数据表的前三行)。
7. 在“日期重复”表的数据下方,统计每个重复日期(第三列的值)出现的次数,并列出该日期对应的所有G列的值(注意:同一个日期可能对应多个G列的值,我们可以用逗号连接)。同时,对于出现次数大于2的日期,在统计区域中高亮显示(即设置背景色)。
8. 创建“双重重复”表,从“日期重复”表中读取数据,找出第四列重复的行(同样,重复的行都要提取)。
9. 在“双重重复”表中做类似的统计。
由于代码量较大,我们将分函数实现。
注意:在JS宏中,数组操作和Excel的行列索引有所不同:
- 工作表行和列从1开始。
- 数组是0开始。
另外,为了避免重复创建表,我们在操作前先删除可能存在的旧表(如果存在则删除)。
开始编写代码:</think>下面我将提供一个完整的WPS JS宏解决方案,用于处理您描述的工作簿合并和重复数据处理需求。代码已添加详细注释说明每个步骤的功能。
```javascript
function main() {
const workbook = Application.ActiveWorkbook;
const allSheets = workbook.Worksheets;
let mergedData = []; // 存储合并后的数据
const headerRows = 3; // 表头行数
// 步骤1:遍历所有工作表,合并数据(排除最后三行)
for (let i = 1; i <= allSheets.Count; i++) {
const sheet = allSheets.Item(i);
// 跳过即将创建的新表
if (["合并数据", "日期重复", "双重重复"].includes(sheet.Name)) continue;
const usedRange = sheet.UsedRange;
const rowCount = usedRange.Rows.Count;
// 排除最后三行
const dataRowCount = Math.max(rowCount - 3 - headerRows, 0);
if (dataRowCount > 0) {
// 读取数据范围(从第4行开始到倒数第4行)
const dataRange = sheet.Range(
sheet.Cells(headerRows + 1, 1),
sheet.Cells(rowCount - 3, usedRange.Columns.Count)
);
const data = dataRange.Value();
// 添加源表列
for (let j = 1; j <= dataRowCount; j++) {
const rowData = [];
for (let k = 1; k <= usedRange.Columns.Count; k++) {
rowData.push(data[j][k]);
}
rowData.push(sheet.Name); // 添加源表信息
mergedData.push(rowData);
}
}
}
// 步骤2:创建"合并数据"表并写入数据
let mergedSheet = createOrClearSheet(workbook, "合并数据");
// 添加表头(包括"源表"列)
const headerRange = mergedSheet.Range("A1").Resize(headerRows, mergedData[0].length);
headerRange.Value = [["合并数据表头"], ...Array(headerRows - 1).fill([])];
mergedSheet.Cells(headerRows, mergedData[0].length).Value = "源表";
// 写入数据
if (mergedData.length > 0) {
const dataRange = mergedSheet.Range(
mergedSheet.Cells(headerRows + 1, 1),
mergedSheet.Cells(headerRows + mergedData.length, mergedData[0].length)
);
dataRange.Value = mergedData;
}
// 统计合并数据条数
mergedSheet.Cells(1, mergedData[0].length + 1).Value = "总数据条数:";
mergedSheet.Cells(1, mergedData[0].length + 2).Value = mergedData.length;
// 步骤3:创建"日期重复"表(基于第三列重复)
const dateCol = 3; // 第三列(C列)
const dateDupData = findDuplicateRows(mergedData, dateCol);
const dateDupSheet = createOrClearSheet(workbook, "日期重复");
writeDataWithHeader(dateDupSheet, dateDupData, headerRows);
// 统计日期重复次数并高亮
const dateStats = countDuplicates(dateDupData, dateCol);
writeStatsWithHighlight(dateDupSheet, dateStats, dateDupData.length + headerRows + 2, dateCol, 6); // G列为第7列
// 步骤4:创建"双重重复"表(基于第四列重复)
const doubleCol = 4; // 第四列(D列)
const doubleDupData = findDuplicateRows(dateDupData, doubleCol);
const doubleDupSheet = createOrClearSheet(workbook, "双重重复");
writeDataWithHeader(doubleDupSheet, doubleDupData, headerRows);
// 统计双重重复次数并高亮
const doubleStats = countDuplicates(doubleDupData, doubleCol);
writeStatsWithHighlight(doubleDupSheet, doubleStats, doubleDupData.length + headerRows + 2, doubleCol, 6); // G列为第7列
// 自动调整列宽
[mergedSheet, dateDupSheet, doubleDupSheet].forEach(sheet => {
sheet.UsedRange.EntireColumn.AutoFit();
});
}
// 创建或清空工作表
function createOrClearSheet(workbook, sheetName) {
let sheet;
try {
sheet = workbook.Worksheets.Item(sheetName);
sheet.UsedRange.Clear();
} catch (e) {
sheet = workbook.Worksheets.Add();
sheet.Name = sheetName;
}
return sheet;
}
// 查找指定列重复的行
function findDuplicateRows(data, colIndex) {
const countMap = {};
const dupRows = [];
const colIdx = colIndex - 1; // 转换为0-based索引
// 第一次遍历:统计出现次数
data.forEach(row => {
const key = row[colIdx];
countMap[key] = (countMap[key] || 0) + 1;
});
// 第二次遍历:收集重复行
data.forEach(row => {
if (countMap[row[colIdx]] > 1) {
dupRows.push(row);
}
});
return dupRows;
}
// 计算重复项统计信息
function countDuplicates(data, colIndex) {
const stats = {};
const colIdx = colIndex - 1;
data.forEach(row => {
const key = row[colIdx];
if (!stats[key]) {
stats[key] = { count: 0, gValues: new Set() };
}
stats[key].count++;
// 收集G列数据(第7列,索引6)
if (row[6] !== undefined) stats[key].gValues.add(row[6]);
});
return stats;
}
// 写入数据(含表头)
function writeDataWithHeader(sheet, data, headerRows) {
if (data.length > 0) {
const dataRange = sheet.Range(
sheet.Cells(headerRows + 1, 1),
sheet.Cells(headerRows + data.length, data[0].length)
);
dataRange.Value = data;
}
}
// 写入统计信息并高亮
function writeStatsWithHighlight(sheet, stats, startRow, colIndex, gColIndex) {
let rowIndex = startRow;
sheet.Cells(rowIndex, 1).Value = "重复统计(列" + String.fromCharCode(64 + colIndex) + ")";
sheet.Cells(rowIndex, 2).Value = "出现次数";
sheet.Cells(rowIndex, 3).Value = "G列值";
rowIndex++;
for (const [key, info] of Object.entries(stats)) {
sheet.Cells(rowIndex, 1).Value = key;
sheet.Cells(rowIndex, 2).Value = info.count;
sheet.Cells(rowIndex, 3).Value = Array.from(info.gValues).join(", ");
// 高亮显示大于2次的数据
if (info.count > 2) {
sheet.Range(
sheet.Cells(rowIndex, 1),
sheet.Cells(rowIndex, 3)
).Interior.ColorIndex = 6; // 黄色高亮
}
rowIndex++;
}
}
```
### 代码功能详解:
1. **数据合并流程**:
- 遍历所有工作表(跳过目标表)
- 读取每张表从第4行开始的数据(排除最后三行)
- 添加"源表"列标记数据来源
- 创建"合并数据"表并写入所有数据
2. **重复数据处理**:
- **日期重复表**:基于第三列(C列)值重复筛选
- **双重重复表**:基于第四列(D列)值重复筛选(在日期重复基础上)
- 使用`findDuplicateRows`函数高效检测重复行
3. **统计与高亮**:
- 在每张表底部添加统计区域
- 统计重复项的出现次数
- 收集并显示对应G列的值
- 对出现次数>2的统计行进行黄色高亮
4. **辅助函数**:
- `createOrClearSheet`: 创建/清空目标表
- `countDuplicates`: 计算重复统计信息
- `writeStatsWithHighlight`: 格式化输出统计结果
### 使用说明:
1. 在WPS中打开目标工作簿
2. 按`Alt+F11`打开宏编辑器
3. 插入新模块并粘贴完整代码
4. 按`F5`运行`main`函数
### 输出效果:
- 📊 **合并数据表**:包含所有有效数据 + "源表"列 + 数据条数统计
- ⚠️ **日期重复表**:包含第三列重复的行 + 重复统计(带G列值)
- ⚠️⚠️ **双重重复表**:包含第四列重复的行 + 重复统计(带G列值)
- >2次的重复项自动黄色高亮显示
### 注意事项:
1. 确保工作簿未被保护
2. 原始数据表前三行为表头
3. 输出表位置:新建工作表置于最后
4. G列索引:第7列(根据需求可修改代码中的`gColIndex`参数)
---
阅读全文
相关推荐



















