从两个源工作表提取数据写入目标表时出现覆盖问题,求排查
问题排查:多工作簿数据迁移时后续数据覆盖前期数据
我编写了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
相关产品推荐
相关产品推荐

