我有两本工作簿,比如:工作簿_a.xlsx和工作簿_b.xlsx并且都包含不同的工作表。其中两个工作表已经通过几个查找使用唯一键的公式,该键是卡斯蒂德列。通过此设置,我可以让用户在工作簿然后我可以在工作簿。现在,我做的最乏味的事情之一就是寻找新的高风险客户工作簿所以我可以手动将它们添加到工作簿.我想做以下事情:
- 从工作簿抬头卡斯蒂德在工作簿。
- 如果存在,则不执行任何操作(我已经添加了客户和 查找公式将负责更新 客户风险单元格值)。
- 如果不存在,则从工作簿到 工作簿(甚至可能不是整行而只是一个单元格?)。
这可能吗?我正在使用 Excel 2007。
答案1
是的,您可以为此创建一个 VBA 宏。
我将创建一个按钮,并在单击事件中,首先确保 workbook_b 已打开,然后使用以下代码复制 workbook_a 中存在 custid 但不在 workbook_b 中的行(请注意,最后您只会在 workbook_b 中得到 workbook_a 的副本,因此复制整个数据范围会简单得多)。
Dim i As Integer, workingCol1 As Integer, workingCol2 As Integer
Dim workingRange1 As Range, workingRange2 As Range
workingCol1 = WorksheetFunction.Match("custid", Sheets("Sheet1").UsedRange.Rows(1), 0)
Set workingRange1 = Sheets("Sheet1").Range("AllCustomers").Columns(workingCol1)
workingCol2 = WorksheetFunction.Match("custid", Sheets("Sheet2").UsedRange.Rows(1), 0)
Set workingRange2 = Sheets("Sheet2").Range("CriticalCustomers").Columns(workingCol2)
For i = 2 To workingRange1.Rows.Count
If Not IsError(Application.Match(workingRange1.Cells(i, 1), workingRange2, 0)) Then
workingRange1.Rows(i).EntireRow.Copy
Sheets("Sheet2").UsedRange.Rows(Sheets("Sheet2").UsedRange.Rows.Count).Offset(1, 0).EntireRow.PasteSpecial (xlPasteValues)
End If
Next i
如果您确实只需要复制一个单元格,那么您可以使用工作表函数来完成,但这会有点复杂。
答案2
如果您有兴趣,另一种方法是首先在 workbook_a 中设置一个动态命名范围,该范围涵盖了您允许用户输入数据的区域。然后,使用该动态命名范围作为 workbook_b 中数据透视表的来源。
当您刷新 workbook_b 中的数据透视表时,您对 workbook_a 中的数据所做的任何更改(包括新客户)都会被应用。
请注意,两个工作簿都需要打开。
具体来说,当我尝试这个时,我将 workbook_a 中的动态范围命名为“AllCustomerData”,数据从 sheet1 上的单元格 A1 开始,并将“AllCustomerData”的公式定义为
=OFFSET(Sheet1!$A$1,0,0,COUNTA(Sheet1!$A:$A),COUNTA(Sheet1!$1:$1))
接下来,对于 workbook_b 中的数据透视表源,我使用
workbook_a.xlsx!AllCustomerData
然后,当我构建数据透视表时,我选择了“经典数据透视表布局”。我将所有字段放在数据透视表字段列表框的“RowLabels”部分中,按照原始 workbook_a 中字段的顺序排列。当然,您可以根据需要对它们进行排序 - 或者只选择您需要的字段。
当我测试这个时,我确实看到,如果我删除了一个客户,刷新了数据透视表,然后在源范围的底部重新使用了该已删除客户的 CUSTID,并再次刷新了数据透视表,那么重新使用的 CUSTID 不会出现在数据透视表中的底部,而是出现在删除之前的原始位置。(我希望这很清楚!)我不知道您的业务规则是否允许重新使用 CUSTID,但如果您这样做,请注意这一点。
希望这能有所帮助。@Lance Roberts 的 VBA 方法也非常好。与此数据透视表方法相比,它的优势在于不会产生所有“数据透视表开销”。