【问题标题】:How can I add a 1 to the most recent, repeated row in Excel?如何将 1 添加到 Excel 中最近的重复行?
【发布时间】:2014-01-10 07:11:28
【问题描述】:

我有一个数据集,其中 60+ 千行在 excel 中,大约 20 列。 “ID 列”有时会自我重复,我想添加一个仅在最近的行中返回 1 的列,如果它重复的话。

这是一个例子。我有……

    ID            DATE       ColumnX
    AS1         Jan-2013      DATA
    AS2         Feb-2013      DATA
    AS3         Jan-2013      DATA
    AS4         Dec-2013      DATA
    AS2         Dec-2013      DATA

我想要……

    ID            DATE       ColumnX      New Column
    AS1         Jan-2013      DATA            1
    AS2         Feb-2013      DATA            0
    AS3         Jan-2013      DATA            1
    AS4         Dec-2013      DATA            1
    AS2         Dec-2013      DATA            1 

我一直在尝试使用排序和嵌套 if 的组合,但这取决于我的数据始终处于相同的顺序(以便它查找前一行中的 ID)。

加分:如果我的数据集对于 excel 来说相当大,请考虑我的数据集,因此将不胜感激最高效且不会占用处理器的代码!

【问题讨论】:

  • 短语“最近的”在这个例子中并不明显。您添加了 1 行,其中包含 12 月和 1 月的行 - 最近仅表示 12 月(至少据我了解)。
  • @EmmadKareem 是同一 ID 的最新消息。 ID AS2 有两个条目:Feb-2013 和 Dec-2013,所以最近的是第二个。
  • 您的预期结果与您所说的业务规则不符。例如,您希望在“AS3”上为 1”,但此 ID 没有重复,那么为什么预期结果不是“0”?真正的问题:您只是想识别每个 ID 的最新条目,还是您除了过滤具有重复的 ID 之外,还尝试这样做吗?
  • @andyholaday 嗨,这是每个 ID 的最新条目,但我猜你在上一篇文章中已经弄清楚了!谢谢

标签: excel if-statement repeat


【解决方案1】:

您可以使用的一种方法是将 MSQuery 指向您的表并使用 SQL 来应用业务规则。从好的方面来说,这运行得非常快(在我对 64k 行的测试中只需要几秒钟)。一个巨大的缺点是查询引擎似乎不支持超过 64k 行的 Excel 表,但可能有办法解决这个问题。无论如何,我会提供解决方案,以防它给您一些想法。

首先要为您的数据集指定一个命名范围。我称它为MYTABLE。节省。接下来在第 1 行中选择表格右侧的一个单元格,然后单击 Data | From other sources | from Microsoft Query。选择Excel Files* | OK,浏览您的文件。查询向导应该打开,显示MYTABLE 可用,添加所有列。点击取消(真的),然后点击Yes,你要继续编辑。

MSQuery 界面应该会打开,单击SQL 按钮并将代码替换为以下代码。您将需要编辑一些细节,例如文件路径。 (另外,请注意我使用了不同的列名。这完全是我的偏执狂。Jet 引擎非常挑剔,我想在构建它时排除与保留字的冲突。)

SELECT 
    MYTABLE.ID_X, 
    MYTABLE.DATE_X, 
    MYTABLE.COLUMN_X, 
    IIF(MAXDATES.ID_x IS NULL,0,1) * IIF(DUPTABLE.ID_X IS NULL,0,1) AS NEW_DATA
FROM ((`C:\Users\andy3h\Desktop\SOTEST1.xlsx`.MYTABLE MYTABLE 
        LEFT OUTER JOIN (
            SELECT MYTABLE1.ID_X, MAX(MYTABLE1.DATE_X) AS MAXDATE
            FROM `C:\Users\andy3h\Desktop\SOTEST1.xlsx`.MYTABLE MYTABLE1
            GROUP BY MYTABLE1.ID_X
            ) AS MAXDATES
        ON MYTABLE.ID_X = MAXDATES.ID_X
        AND MYTABLE.DATE_X = MAXDATES.MAXDATE)
    LEFT OUTER JOIN (
        SELECT MYTABLE2.ID_X
        FROM `C:\Users\andy3h\Desktop\SOTEST1.xlsx`.MYTABLE MYTABLE2
        GROUP BY MYTABLE2.ID_X
        HAVING COUNT(1) > 1
        ) AS DUPTABLE
    ON MYTABLE.ID_X = DUPTABLE.ID_X)

使用适当的代码 MSQuery 将抱怨无法以图形方式表示查询。这是OK。查询将执行 - 在此阶段运行可能需要比预期更长的时间。我不知道为什么,但它应该在后续刷新时运行得更快。一旦结果返回,File | Return data to Excel。接受“导入数据”对话框中的默认值。

这就是技术。要针对新数据刷新查询,只需 Data | Refresh。如果您需要调整查询,您可以通过 Excel 通过Data | Connections | Properties | Definition tab 回到它。

我提供的代码返回您的原始数据加上 NEW_DATA 列,如果 ID 重复并且日期是该 ID 的最大日期,则其值为 1,否则为 0。如果 ID 的最大日期在多行上,则此代码不会整理平局。所有这些行都将被标记为1

编辑:很容易修改代码以忽略重复逻辑并显示所有 ID 的最新行。只需将SELECT 子句的最后一位更改为阅读

IIF(MAXDATES.ID_x IS NULL,0,1) AS NEW_DATA

在这种情况下,您还可以删除带有别名 DUPTABLE 的最后一个 LEFT JOIN

【讨论】:

  • 谢谢!这种解决方法效果不错。我想我只是简单地将整个数据库迁移到 SQL,Excel 对这些事情来说很麻烦......
  • 是的,数据库是完成这项工作 IME 的更好工具。
【解决方案2】:

按 ID 排序,然后按 DATE(升序)。如果上一行具有相同的 ID 而下一行具有不同的 ID 或为空(对于最后一行),则将新列中的条目定义为 1,否则为 0。

【讨论】:

  • 这正是我现在正在做的,但我每个月都会添加数据,所以我每次都必须进行排序和拖动公式(60+千行,它会吃掉处理器)。
【解决方案3】:

它可以在 VBA 中完成。我很想知道这是否可能仅使用公式,我以前必须做一次类似的事情。

Sub Macro1()

Dim rowCount As Long

Sheets("Sheet1").Activate
rowCount = Cells(Rows.Count, 1).End(xlUp).Row

Columns("A:D").Select
Selection.AutoFilter

Range("D2:D" & rowCount).Select
Selection.ClearContents

Columns("A:D").Select

ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add Key:=Range _
    ("B1:B" & rowCount), SortOn:=xlSortOnValues
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add Key:=Range _
    ("A1:A" & rowCount), SortOn:=xlSortOnValues
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.Apply

Dim counter As Integer

For counter = 2 To rowCount

    Cells(counter, 4) = 1
    If Cells(counter, 1) = Cells(counter + 1, 1) Then Cells(counter, 4) = 0

Next counter

End Sub

因此您激活工作表并获取行数。

然后选择并自动筛选结果,并清除包含 0 或 1 的 D 列。然后过滤 mbroshi 建议您说您已经在使用的值。然后对每条记录执行一个循环,将值更改为 1,但如果前面的值具有相同的 ID,则返回 0。

根据您的处理器,我认为这不会花费超过一两分钟的时间来运行。如果您确实使用公式找到了一些东西,我会很感兴趣!

【讨论】:

  • 很想知道您是否对此进行了测试。我希望counter 溢出到 64k 以上(简单修复:将数据类型更改为Long)。除此之外,在超过 50k 行的 IME 范围内,使用过滤列表会变得非常缓慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2016-04-10
  • 1970-01-01
  • 1970-01-01
  • 2020-08-01
  • 1970-01-01
相关资源
最近更新 更多