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

从两个源工作表提取数据写入目标表时出现覆盖问题,求排查

问题排查:多工作簿数据迁移时后续数据覆盖前期数据

我编写了Python程序,用于从两个源工作表的指定列提取数据并迁移至目标工作表,但第二个工作簿的数据会覆盖第一个工作簿的数据。后续计划添加更多工作簿,现附上代码、控制台输出及截图描述,请求协助排查问题原因。

代码

import openpyxl
import calendar

# 打开目标工作簿
dest_wb = openpyxl.load_workbook('Liquid Portfolio Attribution Analysis - Blank.xlsx')

# 指定目标工作表及起始行
dest_sheet = dest_wb['Data']

def get_maximum_rows(*, sheet_object):
    rows = 0
    for max_row, row in enumerate(sheet_object, 1):
        if not all(col.value is None for col in row):
            rows += 1
    return rows

# 获取目标工作表已有数据的最后一行
dest_last_row = get_maximum_rows(sheet_object=dest_sheet)

# 设置数据迁移的起始行
dest_row = dest_last_row + 1

# 遍历工作簿集合
for month in ['01']:
    for alpha in ['I', 'II']:
        # 打开源工作簿
        wb_name = f'2022-{month} Alpha {alpha} - Workbook - MTester.xlsx'
        wb = openpyxl.load_workbook(wb_name, data_only=False)

        # 获取PCAP工作表
        sheet_name = f'2022-{month} PCAP (R)'
        sheet = wb[sheet_name]
        last_row = sheet.max_row

        # 复制数据到目标工作表
        # 写入日期到B列
        last_day = calendar.monthrange(2022, int(month))[1]
        date_str = f'{int(month)}/{last_day}/2022'
        dest_sheet[f'B{dest_row+1}'].value = date_str

        # 定义源列到目标列的映射字典
        data_map = {'A': 'C', 'B': 'E', 'D': 'F', 'F': 'G', 'H': 'H', 'U': 'J', 'AI': 'I', 'AO': 'K'}

        # 获取源工作表数据的最后一行
        last_row = sheet.max_row
        print(f"Source sheet last row: {sheet.max_row}")
        print(f"Destination row: {dest_row}")
        
        for row in range(6, last_row + 1):
            dest_row += 1
            print(f"Destination row: {dest_row}")
            # 提取源工作表当前行的所有数据
            source_row_data = [col.value for col in sheet[f'A{row}:AO{row}'][0]]
            if any(col_value is not None for col_value in source_row_data):
                for source_col, dest_col in data_map.items():
                    # 处理单列号的列
                    if len(source_col) == 1:
                        source_col_val = source_row_data[ord(source_col) - 65]  
                    # 处理双列号的列
                    else:
                        col_num = (ord(source_col[0]) - 64) * 26 + (ord(source_col[1]) - 65)
                        source_col_val = source_row_data[col_num - 1]
                    # 错误:使用源表行号而非目标表递增行号
                    dest_col_val = dest_sheet[f'{dest_col}{row}']
                    if source_col in ['H', 'U', 'AI'] and row == last_row:
                        dest_col_val.value = None
                    else:
                        dest_col_val.value = source_col_val
            else:
                print(f'Row{row} has blank data')
        # 关闭当前源工作簿
        wb.close()

# 保存目标工作簿
dest_wb.save('Liquid Portfolio Attribution Analysis - Copy - Tester Big.xlsx')

控制台输出

Source sheet last row: 11
Destination row: 4
Destination row: 5
Destination row: 6
Destination row: 7
Destination row: 8
Destination row: 9
Destination row: 10
Source sheet last row: 11
Destination row: 10
Destination row: 11
Destination row: 12
Destination row: 13
Destination row: 14
Destination row: 15
Destination row: 16

截图描述

  • 源工作表1:展示2022-01 Alpha I的PCAP工作表数据,有效数据行范围为第6行至第11行
  • 源工作表2:展示2022-01 Alpha II的PCAP工作表数据,有效数据行范围为第6行至第11行
  • 目标工作表:仅保留了第二个工作簿的数据,第一个工作簿的迁移数据被完全覆盖

问题原因及修复方案

核心问题

代码写入目标工作表时,错误使用了源表的行号row,而非专门维护的目标表递增行号dest_row:

dest_col_val = dest_sheet[f'{dest_col}{row}']

第一个工作簿写入目标表的行是6-11,第二个工作簿同样写入6-11区间,直接覆盖了前期迁移的数据。

修复后的关键代码

将上述错误行替换为:

dest_col_val = dest_sheet[f'{dest_col}{dest_row}']

同时修正日期写入逻辑(原代码仅写入第一行日期,若需每行对应日期,需将日期写入放在循环内):

for row in range(6, last_row + 1):
    dest_row += 1
    # 为当前目标行写入日期
    dest_sheet[f'B{dest_row}'].value = date_str
    # 后续数据迁移逻辑...

额外优化建议

  • 使用openpyxl.utils.cell.column_index_from_string替代手动计算列号,避免双列号处理出错
  • 将wb.close()放在for alpha内层循环内,避免资源泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:19:58