【问题标题】:Factory can only process 10 orders per day. How to push dates ahead after 10 orders?工厂每天只能处理 10 个订单。如何在 10 个订单后将日期提前?
【发布时间】:2020-03-14 05:01:23
【问题描述】:

我正在处理一个只有两列的 Excel 文件:“订单号”和“日期”。

如果某一天的订单超过 10 个,则超过 10 个的订单需要“溢出”到下一个工作日。当然,已经有下一个工作日的订单了。因此,将原始日期移至下一个工作日可能会使天的订单超过 10 个。这是一个递归问题。

我从 Power Query 开始,并使用从 0 开始并为每组 10 个订单号重置为 0 的索引列。然后使用 Date.Add([Date],[Index]) 添加一个自定义列。然后我尝试了 Mod() 和其他一些失败。

答案似乎需要知道一行是否超过 10 个订单并且知道已经调整的日期(如果超过 10 个之前已经发生过。)

再一次,感觉是递归的。

我在 Power Query 中获得了一些真正的胜利,这是我第一个在现实世界中令人头疼的事情。

数据:

Order Number   Date
1            1/1/2020
2            1/1/2020
3            1/1/2020
...
10           1/1/2020
11           1/1/2020
12           1/1/2020
13           1/2/1020
14           1/2/2020

预期输出:

Order Number   Date
1            1/1/2020
2            1/1/2020
3            1/1/2020
...
10           1/1/2020
11           1/2/2020
12           1/2/2020
13           1/2/1020
14           1/2/2020
...
20           1/2/2020
21           1/3/2020
22           1/3/2020

【问题讨论】:

  • 您能否举例说明数据的外观,包括原始列和预期列?
  • @Jonee - 添加了样本

标签: excel powerbi powerquery powerbi-desktop


【解决方案1】:
  • 我不确定以下代码的扩展性如何(例如,如果您有数百万行),但您可以尝试该代码,看看它是否能提供预期的输出。 (我认为应该,但你没有给出你的桌子的例子和它应该是什么样子,所以我不能确定。)
  • 您没有定义“工作日”。我们是否可以无条件假设周一至周五,或者是否有应排除的公共假期(可能包括周一至周五)?
  • 下面的代码假定下一个工作日的定义是下一个可用订单日期(在表格本身中)。但是,使用此定义会引入以下问题:
    • 最后一个订单日期(显示在表格中)是否有可能超过 10 个订单?
    • 如果是这样,应该如何处理超出最后订单日期的订单?
    • 您的订单日期必须按升序排列(在开始循环之前)。
  • 目前,代码返回转换后的表和溢出到最后一个可用工作日之外的任何未使用的行。 (然后你可以选择对它们做任何你想做的事情。)

我假设您的表格如下所示:

以及下面的代码:

let
    initialTable = 
        let
            listsOfDates = List.Transform({1..20}, each List.Dates(#date(2020, 1, 1), _, #duration(1, 0, 0, 0))),
            combined = List.Combine(listsOfDates),
            dateColumn = Table.FromColumns({List.Sort(combined)}, type table [orderDate = date]),
            orderNumberColumn = Table.AddColumn(dateColumn, "orderNumber", each Text.NewGuid(), type text)
        in orderNumberColumn,
    grouped = Table.Group(initialTable, "orderDate", {"nested", each _, type table}),
    emptyTable = Table.FirstN(initialTable, 0),
    accumulated = List.Accumulate(
        List.Buffer(Table.ToRecords(grouped)),
        [
            spilledOver = emptyTable,
            result = emptyTable
        ],
        (state as record, row as record) =>
            let
                MAX_ROW_COUNT = 10,
                currentDate = row[orderDate],
                currentTable = Table.TransformColumns(state[spilledOver], {"orderDate", each currentDate, type date}) & row[nested],
                shouldSpillOver = Table.RowCount(currentTable) > MAX_ROW_COUNT,
                appended = state[result] & Table.FirstN(currentTable, MAX_ROW_COUNT),
                newState = if shouldSpillOver then 
                        [spilledOver = Table.Skip(currentTable, MAX_ROW_COUNT), result = appended]
                    else 
                        [spilledOver = emptyTable, result = appended]
            in newState
    ),
    result = accumulated[result]
in
    result

应该给你一个record,它有两个字段:spilledOverresult,其中:

  • spilledOver 应该是一个表,其中包含超出最后一个可用日期的任何行(因此是“未分配的”)。如果没有这样的行(最后一个可用日期),spilledOver 应该是一个空表。
  • result 应该是一个表格,其中每个订单日期不应超过 10 个订单。 (您应该能够通过将 result 分组到 "orderDate" 并通过 Table.RowCount 聚合来确认这一点,然后检查是否有超过 10 个。)

显然,您需要为自己的表的列名调整代码。

【讨论】:

  • 这超出了我的预期。可以从这段代码中学到很多东西。非常感谢!我迫不及待想在 Power Query(M 语言)方面表现出色。
  • 我现在正在逐步检查您的代码,这确实是一门关于如何创造性地解决 M 中的问题的课程。回答您的开放性问题: 1.“工作日”表示工作日(周一至周五)。有一个表格或列表形式的公共假期列表。2.没有结束日期限制。工厂将生产 10每天,直到所有订单完成。这些是我试图了解如何注入您现有代码库的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
相关资源
最近更新 更多