excel - 比较、更新或复制外部报告中的数据
问题描述
我正在尝试比较一个主要的计划文件(我们称之为 Main.xlsm)和我们的 ERP 系统(ERP.xlsm)提供的数据。
我正在寻找:
1)打开一个窗口选择源文件(ERP系统转储)。
2) 比较两个文件中 F 列的唯一 ID 值(Main.xlsm 中的 Sheet RAPORT 和 ERP.xlsm 中的 Sheet1),并且:
如果 Main.xlsm 和 ERP.xlsm 之间存在匹配 - 使用来自 ERP 的值更新 Main 中的值(所有数据 - A:AK 行)
如果 ERP 中有条目但 Main 中没有条目 - 添加具有该 ID 的整行 (A:AK)
如果 Main 中有条目但 ERP 中没有数据 - 在 Main 文件的“R”行中放置值“0”
奖励回合:每次发生上述情况时,在其更改的唯一 ID 的行中的“AL”列中放置一个时间/日期戳。
我尝试了下面的代码(原始版本,我没有更改)。我无法弄清楚如何从上面实现所有目标。
Sub import_tickets()
'run this when the active file is the main ticket list and the active sheet is the ticket list
'exported file must be open already, and the ticket list must be the active sheet
Dim exported_file As String
exported_file = "exported file.xlsx"
header_exists = True 'if exported file doesn't have a header, set this to false!
starting_row = 1
If header_exists Then starting_row = 2
Dim first_blank_row As Long
first_blank_row = Cells.SpecialCells(xlCellTypeLastCell).Offset(1, 0).Row
Dim r As Long
r = starting_row
Dim found As Range
cur_ticket_num = Workbooks(exported_file).ActiveSheet.Range("a" & r).Value
Do While Not cur_ticket_num = ""
'look for current ticket number in main file
Set found = Columns("a:a").Find(what:=cur_ticket_num, LookIn:=xlValues, lookat:=xlWhole)
If found Is Nothing Then
'add info to end of main file
write_line_from_export exported_file, r, first_blank_row
first_blank_row = first_blank_row + 1
Else
'overwrite existing line of main file
write_line_from_export exported_file, r, found.Row
End If
r = r + 1
cur_ticket_num = Workbooks(exported_file).ActiveSheet.Range("a" & r).Value
Loop
End Sub
Sub write_line_from_export(src_filename As String, src_r As Long, dest_r As Long)
For c = 1 To 24
Cells(dest_r, c).Value = Workbooks(src_filename).ActiveSheet.Cells(src_r, c).Value
Next c
End Sub
解决方案
这是一个使用 Dictionary 对象比较两张工作表之间的 ID 列的示例。
Sub import_tickets()
Dim sERPFileName As String
Dim wbERP As Workbook, wsERP As Worksheet
Dim wbMain As Workbook, wsMain As Worksheet
Dim r, startrow, lastrow As Long
Dim ID
Dim dictERP
Set dictERP = CreateObject("Scripting.Dictionary")
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Show
sERPFileName = .SelectedItems(1)
End With
Application.ScreenUpdating = False
' process ERP workbook
Set wbERP = Workbooks.Open(sERPFileName, , xlReadOnly)
Set wsERP = wbERP.Sheets("Sheet1")
startrow = 2 ' assume has header
lastrow = wsERP.Cells(Rows.Count, "F").End(xlUp).Row
For r = startrow To lastrow
ID = wsERP.Range("F" & r).Value
If dictERP.exists(ID) Then
MsgBox "Duplicate ID (" & ID & ") found in " & sERPFileName
Else
dictERP.Add ID, r
End If
Next r
' process MAIN workbook
Set wbMain = ThisWorkbook
Set wsMain = wbMain.Sheets("RAPORT")
startrow = 2 ' assume has header
lastrow = wsMain.Cells(Rows.Count, "F").End(xlUp).Row
For r = startrow To lastrow
ID = wsMain.Range("F" & r).Value
If dictERP.exists(ID) Then
' update
wsERP.Rows(dictERP(ID)).Columns("A:AK").Copy wsMain.Range("A" & r)
wsMain.Range("L" & r) = "Updated " & Now
dictERP.Remove (ID)
Else
' set col R = 0
wsMain.Range("R" & r).Value = 0
wsMain.Range("L" & r) = "No Change " & Now
End If
Next r
' add from ERP those not matched
If dictERP.Count > 0 Then
For Each ID In dictERP.keys
r = dictERP(ID)
lastrow = lastrow + 1
wsERP.Rows(r).Columns("A:AK").Copy wsMain.Range("A" & lastrow)
wsMain.Range("L" & lastrow) = "Added " & Now
Next
End If
wbERP.Close
Application.ScreenUpdating = True
If dictERP.Count Then
MsgBox dictERP.Count & " rows added"
Else
MsgBox "Done"
End If
End Sub
推荐阅读
- javascript - Discord.js 将多个用户从一个语音通道转移到另一个
- java - +e vs , e 在 throw Exception 之间的区别
- latex - LaTex/tikZ:如何从南的 2 个节点到北的 1 个节点绘制 2 个垂直箭头?
- php - 安装包时如何解决 Laravel 中的 Guzzle 错误
- python - Python PIL - 绘图线无法按预期工作
- apache-superset - 有没有办法在 Apache Superset 中删除视图或表?
- java - dismess BottomSheetDialogFragment
- maven - 在一个多模块的maven项目中,我可以制作一个模块来根据另一个模块的DependencyReducedPom计算传递依赖吗?
- javascript - React:为什么在每次重新渲染时调用初始化函数时,从 useState 返回的状态保持不变?
- javascript - 如何在 discord.js 中创建一个等待消息的循环