如何用Power Query将每日更新的CSV追加至Excel而非覆盖
解决Power Query刷新时追加CSV数据而非覆盖的问题
问题背景
每日凌晨1点更新的REPAIRS.csv维修记录文件,之前用Flow处理因文件数量多、体积大导致速度过慢。想通过Power Query实现点击刷新时,将CSV中的新数据行追加到Excel现有表格下方,但当前配置下Power Query会直接覆盖原有数据。试过双查询和追加功能,只能拼接两个静态文件,CSV内容更新后无法自动识别新增行。
核心解决方案
通过记录已导入数据的唯一标识(如维修ID)或时间戳,每次刷新仅导入CSV中比该标识新的数据,再追加到主表格。
步骤1:在Excel中存储已导入数据的最大标识
在Excel工作表(比如Sheet1)的空白单元格(例如Z1)中,添加表头最大维修ID,初始值设为0;如果用时间戳则设为最早的时间,比如2000-01-01。
步骤2:编写带筛选逻辑的Power Query代码
新建空白查询,粘贴以下代码(根据你的实际列名和文件路径修改):
let // 读取Excel中记录的已导入最大维修ID LastImportedID = Excel.CurrentWorkbook(){[Name="Sheet1"]}[Content]{0}[最大维修ID], // 加载目标CSV文件 Source = Csv.Document(File.Contents("C:\你的文件路径\REPAIRS.csv"), [Delimiter=",", Encoding=1252, QuoteStyle=QuoteStyle.Csv]), // 提升CSV的第一行为表头 PromotedHeaders = Table.PromoteHeaders(Source, [PromoteAllScalars=true]), // 转换列类型(根据你的实际列调整) ChangedType = Table.TransformColumnTypes(PromotedHeaders,{ {"维修ID", Int64.Type}, {"记录创建时间", type datetime}, {"设备编号", type text}, {"故障描述", type text} }), // 筛选出CSV中维修ID大于已导入最大值的新数据 FilteredNewRows = Table.SelectRows(ChangedType, each [维修ID] > LastImportedID), // 如果有新数据,更新Excel中的最大维修ID UpdateLastID = if Table.RowCount(FilteredNewRows) > 0 then Excel.CurrentWorkbook(){[Name="Sheet1"]}[Content]{0}[最大维修ID] = List.Max(FilteredNewRows[维修ID]) else null, // 返回筛选后的新数据 Result = FilteredNewRows in Result
步骤3:配置数据加载与追加
- 将上述查询设置为仅创建连接(加载时选择此选项)。
- 找到你的主数据表格,通过
数据选项卡的追加查询功能,将新查询的结果追加到主表格中。 - 后续每次点击刷新,Power Query只会导入CSV中的新增数据,不会覆盖原有内容。
无唯一ID时的替代方案(用时间戳)
如果维修记录没有唯一递增的ID,可以用记录创建时间作为筛选依据,代码如下:
let // 读取已导入的最晚记录时间 LastImportedTime = Excel.CurrentWorkbook(){[Name="Sheet1"]}[Content]{0}[最晚记录时间], Source = Csv.Document(File.Contents("C:\你的文件路径\REPAIRS.csv"), [Delimiter=",", Encoding=1252, QuoteStyle=QuoteStyle.Csv]), PromotedHeaders = Table.PromoteHeaders(Source, [PromoteAllScalars=true]), ChangedType = Table.TransformColumnTypes(PromotedHeaders,{ {"记录创建时间", type datetime}, {"设备编号", type text}, {"故障描述", type text} }), // 筛选出晚于已导入时间的新数据 FilteredNewRows = Table.SelectRows(ChangedType, each [记录创建时间] > LastImportedTime), // 更新最晚记录时间 UpdateLastTime = if Table.RowCount(FilteredNewRows) > 0 then Excel.CurrentWorkbook(){[Name="Sheet1"]}[Content]{0}[最晚记录时间] = List.Max(FilteredNewRows[记录创建时间]) else null, Result = FilteredNewRows in Result
关键注意点
- 确保CSV文件路径正确,若为网络共享路径需有读写权限。
- 首次运行前必须手动初始化
最大维修ID或最晚记录时间的单元格值。 - 主数据表格不要手动修改结构或删除行,避免筛选逻辑失效。
内容的提问来源于stack exchange,提问作者Ian
相关产品推荐
相关产品推荐

