用JS宏合并当前工作簿中的所有工作表,其中源表头占前三行,跳过最后三行数据不合并,将合并后的内容输出为新的工作表,新合并的表格表头占两行,并且第二行的内容与源表格第三行内容一致,并追加一列用于标识合并前的工作表名。在合并完成后,再比对合并后表格的除表头外所有第三列内容,将重复数据所在行全部输出到一张新表格中,并命名为“日期重复”,再将第三列内容与第四列内容都重复的行再输出为一张新表格,并命名为“双重重复”,并将在最后统计所有重复信息
时间: 2025-07-20 17:30:39 浏览: 10
<think>我们面临的任务比较复杂,需要分步骤完成:
1. 合并当前工作簿中所有工作表的数据,要求:
- 源表头占前三行,但合并后新表格表头占两行(即只取源表的前两行?但是要求第二行内容与源表格第三行内容一致,这里可能描述有歧义。根据问题描述,合并后的表头占两行,并且第二行的内容与源表格第三行内容一致。所以合并后的表头应该是:
第一行:源表第一行
第二行:源表第三行(注意:这里跳过了源表第二行?)但问题没有明确说明源表第二行如何处理。根据要求,我们跳过源表第二行,只取第一行和第三行作为合并后的两行表头。
- 跳过源表最后三行数据(即不合并最后三行)
- 追加一列用于标识合并前的工作表名
2. 合并完成后,进行重复数据检查:
a. 创建“日期重复”表:比对合并后表格的除表头外所有第三列内容,将重复数据所在行全部输出(注意:重复数据是指第三列内容重复,但输出整行)
b. 创建“双重重复”表:将第三列内容与第四列内容都重复的行输出
c. 统计所有重复信息(可能是指输出重复的次数或详细列表?但问题没有明确,我们暂时理解为在最后输出重复的统计信息,但具体形式未定,我们可以考虑在控制台输出或创建统计表)
由于环境是WPS JS宏,我们使用JavaScript编写。
步骤:
第一步:合并所有工作表
- 遍历工作簿中的每个工作表
- 对于每个工作表:
a. 获取数据区域(假设数据连续,从A1开始)
b. 获取整个数据区域,但排除最后三行(如果总行数小于等于3,则跳过该表)
c. 取前三行作为表头,但合并后的表头只需要前两行(第一行和第三行)?但问题要求合并后表头占两行,且第二行与源表第三行一致,所以:
合并后表头第一行 = 源表第一行
合并后表头第二行 = 源表第三行(注意:源表第二行被跳过)
d. 数据部分:从第4行开始(跳过前三行)到倒数第4行(跳过最后三行)
e. 在每一行数据后面追加工作表名称(作为新列)
第二步:创建合并后的新工作表,写入合并后的数据(包括新表头和数据)
第三步:在合并后的数据中检查重复:
a. 创建“日期重复”表:检查合并后数据(除表头)的第三列(即C列,索引2),记录重复行(整行)
b. 创建“双重重复”表:检查合并后数据(除表头)的第三列和第四列(即C列和D列,索引2和3)同时重复的行
注意:重复的判断是指同一列内出现相同值,但重复行可能有多于两个,需要记录所有重复行(包括第一次出现和后续重复的)。
第四步:输出统计信息
由于代码较长,我们将分函数实现。
注意:在WPS JS宏中,操作Excel对象的方式与VBA类似,但语法是JavaScript。
开始编写代码:</think>### 解决方案:JS宏合并工作表并处理重复数据
以下代码实现了合并当前工作簿中所有工作表、处理表头、跳过尾行、添加来源标识,并分析重复数据的功能:
```javascript
function 合并并分析重复数据() {
try {
// 创建结果工作簿
const resultWorkbook = Workbooks.Add();
const mainSheet = resultWorkbook.Sheets(1);
mainSheet.Name = "合并数据";
// 准备合并数据结构
const mergedData = [];
const sheetNames = [];
let headers = [];
// 遍历所有工作表
for (let sheet of ThisWorkbook.Sheets) {
sheetNames.push(sheet.Name);
// 获取数据区域(跳过最后三行)
const dataRange = sheet.Range("A1").CurrentRegion;
const totalRows = dataRange.Rows.Count;
if (totalRows <= 3) continue; // 跳过不足4行的工作表
const sourceData = dataRange.Rows("1:" + (totalRows - 3)).Value2;
// 处理表头(前三行)
if (headers.length === 0) {
// 新表头:第一行 + 第三行
headers = [
...sourceData[0],
...sourceData[2]
];
// 添加来源标识列标题
headers.push("来源工作表");
}
// 添加数据行(跳过前三行)
for (let i = 3; i < sourceData.length; i++) {
const rowData = [...sourceData[i], sheet.Name];
mergedData.push(rowData);
}
}
// 写入合并数据
const outputRange = mainSheet.Range("A1").Resize(
mergedData.length + 1,
headers.length
);
outputRange.Value2 = [headers, ...mergedData];
// ==== 分析重复数据 ====
// 1. 创建"日期重复"表
const dateDupSheet = resultWorkbook.Sheets.Add();
dateDupSheet.Name = "日期重复";
createDuplicateSheet(mainSheet, dateDupSheet, 3); // 检查第三列
// 2. 创建"双重重复"表
const doubleDupSheet = resultWorkbook.Sheets.Add();
doubleDupSheet.Name = "双重重复";
createDoubleDuplicateSheet(mainSheet, doubleDupSheet, 3, 4); // 检查第三列和第四列
// 3. 统计重复信息
const stats = calculateDuplicateStats(mainSheet, 3);
console.log("重复数据统计结果:");
console.log(`总行数: ${stats.totalRows}`);
console.log(`日期重复行数: ${stats.dateDupCount}`);
console.log(`双重重复行数: ${stats.doubleDupCount}`);
console.log(`重复日期值: ${stats.dupDates.join(", ")}`);
return "处理完成!";
} catch (error) {
console.error("处理出错: " + error.message);
return "处理失败!";
}
}
// 创建单列重复数据表
function createDuplicateSheet(sourceSheet, targetSheet, colIndex) {
const data = sourceSheet.UsedRange.Value2;
const header = data[0];
const dupRows = [];
const seen = new Map();
// 跳过表头行
for (let i = 1; i < data.length; i++) {
const cellValue = data[i][colIndex - 1];
if (seen.has(cellValue)) {
// 添加当前行和之前匹配的行
if (seen.get(cellValue) !== -1) {
dupRows.push(data[seen.get(cellValue)]);
seen.set(cellValue, -1); // 标记为已处理
}
dupRows.push(data[i]);
} else {
seen.set(cellValue, i);
}
}
// 写入重复数据
if (dupRows.length > 0) {
targetSheet.Range("A1").Resize(dupRows.length + 1, header.length).Value2 = [header, ...dupRows];
}
}
// 创建双列重复数据表
function createDoubleDuplicateSheet(sourceSheet, targetSheet, colIndex1, colIndex2) {
const data = sourceSheet.UsedRange.Value2;
const header = data[0];
const dupRows = [];
const seen = new Map();
// 跳过表头行
for (let i = 1; i < data.length; i++) {
const key = `${data[i][colIndex1 - 1]}|${data[i][colIndex2 - 1]}`;
if (seen.has(key)) {
if (seen.get(key) !== -1) {
dupRows.push(data[seen.get(key)]);
seen.set(key, -1);
}
dupRows.push(data[i]);
} else {
seen.set(key, i);
}
}
// 写入重复数据
if (dupRows.length > 0) {
targetSheet.Range("A1").Resize(dupRows.length + 1, header.length).Value2 = [header, ...dupRows];
}
}
// 统计重复信息
function calculateDuplicateStats(sheet, dateColIndex) {
const data = sheet.UsedRange.Value2;
const stats = {
totalRows: data.length - 1, // 减表头行
dateDupCount: 0,
doubleDupCount: 0,
dupDates: []
};
const dateMap = new Map();
const doubleMap = new Map();
// 分析数据行
for (let i = 1; i < data.length; i++) {
const dateVal = data[i][dateColIndex - 1];
const doubleKey = `${dateVal}|${data[i][dateColIndex]}`; // 第三列和第四列
// 统计日期重复
if (dateMap.has(dateVal)) {
stats.dateDupCount++;
if (!stats.dupDates.includes(dateVal)) {
stats.dupDates.push(dateVal);
}
} else {
dateMap.set(dateVal, true);
}
// 统计双重复
if (doubleMap.has(doubleKey)) {
stats.doubleDupCount++;
} else {
doubleMap.set(doubleKey, true);
}
}
return stats;
}
// 执行函数
合并并分析重复数据();
```
### 代码功能详解
#### 1. 主函数 `合并并分析重复数据()`
- **创建工作簿**:创建包含"合并数据"表的新工作簿
- **遍历工作表**:处理当前工作簿的所有工作表
- **数据处理**:
- 跳过每张表的最后3行数据
- 合并表头:使用源表第1行和第3行作为新表头(占两行)
- 添加"来源工作表"列标识数据来源
- **重复分析**:
- 创建"日期重复"表(基于第3列重复)
- 创建"双重重复"表(基于第3列和第4列同时重复)
- 统计重复信息并输出到控制台
#### 2. 辅助函数功能
- **`createDuplicateSheet()`**:创建单列重复数据表
- 使用Map跟踪已出现的值
- 收集所有重复行(包括首次出现的行)
- **`createDoubleDuplicateSheet()`**:创建双列重复数据表
- 使用复合键(列1|列2)跟踪重复
- 处理多重复合重复情况
- **`calculateDuplicateStats()`**:统计重复信息
- 计算总行数、日期重复数、双重重复数
- 收集所有重复日期值
#### 3. 关键处理逻辑
1. **表头处理**:
```javascript
// 合并源表第1行和第3行
headers = [...sourceData[0], ...sourceData[2]];
headers.push("来源工作表"); // 添加来源列
```
2. **跳过最后三行**:
```javascript
// 只取1到(总行数-3)的行
const sourceData = dataRange.Rows("1:" + (totalRows - 3)).Value2;
```
3. **重复检测**:
```javascript
// 单列重复检测
if (seen.has(cellValue)) {
// 处理重复行...
}
// 双列重复检测
const key = `${data[i][colIndex1 - 1]}|${data[i][colIndex2 - 1]}`;
```
4. **统计输出**:
```javascript
console.log(`总行数: ${stats.totalRows}`);
console.log(`日期重复行数: ${stats.dateDupCount}`);
console.log(`双重重复行数: ${stats.doubleDupCount}`);
```
### 特殊处理说明
1. **表头结构**:
- 合并后表头占两行:第1行=源表第1行,第2行=源表第3行
- 源表第2行被跳过(根据需求)
2. **数据范围**:
- 源表数据从第4行开始(跳过前三行表头)
- 源表最后三行被排除
3. **重复处理**:
- "日期重复":基于第3列(索引2)内容重复
- "双重重复":基于第3列和第4列同时重复
- 包含所有重复行(包括首次出现的行)
4. **错误处理**:
- 使用try-catch捕获异常
- 跳过行数不足的工作表
- 控制台输出详细错误信息
### 使用说明
1. 在WPS中打开JS宏编辑器
2. 粘贴完整代码
3. 运行`合并并分析重复数据()`函数
4. 结果包含:
- "合并数据"表:合并后的完整数据
- "日期重复"表:第三列重复的行
- "双重重复"表:第三列和第四列都重复的行
- 控制台输出重复统计信息
阅读全文
相关推荐



















