You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将两日期间的在船工时按天分配(PowerBI M语言)

船员在船工时按实际日期拆分的M语言代码修改方案

问题核心

现有M语言代码将船员在船工时全部关联至月末日期,无法满足按实际日期统计工时的需求。需要调整代码,使工时按实际日期拆分:

  • 起始日:统计从登船时间到当日结束的剩余时长
  • 中间日:按24小时计算
  • 结束日:统计从当日开始到下船时间的时长

关键修改点

原代码中生成日期列时,使用Date.EndOfMonth将所有日期转换为月末日期,只需移除该转换,直接使用原始的每日日期列表即可:

// 原错误代码
List.Transform ( LD, Date.EndOfMonth )

// 修改后代码
LD

修改后的完整M代码

let
    Kilde = Sql.Database("XXXXX", "YYYYYY"),
        CREW_CrewActivity = Kilde{[Schema="CREW",Item="CrewActivity"]}[Data],
    #"Fjernede kolonner" = Table.RemoveColumns(CREW_CrewActivity,{"LastModified", "X_CREATED", "X_CREATED_BY", "X_DEFAULT_TZ", "CompanyId", "LocationCompany", "LocationFlagState", "LocationImo", "LocationMainType", "LocationManager", "LocationMmsi", "LocationName", "LocationOwner", "LocationSegment", "LocationTypes", "Bunk", "Cabin", "Company", "CompanyName", "GangwayLog", "SignOffPlace", "SignOnPlace", "TagId", "FirstName", "LastName", "MiddleName", "Position", "Vessel"}),
    #"Filtrerte rader" = Table.SelectRows(#"Fjernede kolonner", each ([SignOff] <> null)),

    // 处理SignOff字段格式
    #"Erstattet verdi SignOff" = Table.ReplaceValue(#"Filtrerte rader", "T", " ", Replacer.ReplaceText, {"SignOff"}),
    #"Uttrekte første tegn SignOff" = Table.TransformColumns(#"Erstattet verdi SignOff", {{"SignOff", each Text.Start(_, 16), type text}}),

    // 处理SignOn字段格式
    #"Erstattet verdi SignOn" = Table.ReplaceValue(#"Uttrekte første tegn SignOff", "T", " ", Replacer.ReplaceText, {"SignOn"}),
    #"Uttrekte første tegn SignOn" = Table.TransformColumns(#"Erstattet verdi SignOn", {{"SignOn", each Text.Start(_, 16), type text}}),
    
    // 拆分日期与时间字段
    #"Del kolonne med skilletegn" = Table.SplitColumn(#"Uttrekte første tegn SignOn", "SignOn", Splitter.SplitTextByEachDelimiter({" "}, QuoteStyle.Csv, false), {"SignOn.1", "SignOn.2"}),
    #"Del kolonne med skilletegn1" = Table.SplitColumn(#"Del kolonne med skilletegn", "SignOff", Splitter.SplitTextByEachDelimiter({" "}, QuoteStyle.Csv, false), {"SignOff.1", "SignOff.2"}),
    // 转换字段类型
    #"Endret type" = Table.TransformColumnTypes(#"Del kolonne med skilletegn1",{{"SignOn.1", type date}, {"SignOn.2", type text}, {"SignOff.1", type date}, {"SignOff.2", type text}}),
    // 移除时间字段的冒号
    #"Erstattet verdi" = Table.ReplaceValue(#"Endret type",":","",Replacer.ReplaceText,{"SignOn.2", "SignOff.2"}),
    // 重命名字段
    #"Kolonner med nye navn" = Table.RenameColumns(#"Erstattet verdi",{{"SignOn.1", "Start Date"}, {"SignOn.2", "Start Time"}, {"SignOff.1", "Stop Date"}, {"SignOff.2", "Stop Time"}}),
    // 生成按日拆分的工时数据(核心修改部分)
    #"Egendefinert lagt til" = Table.AddColumn(#"Kolonner med nye navn", "Egendefinert", each 
        [
            SD = [Start Date],
            ST = Number.Round(Number.From([Start Time])/100,0),
            ED = [Stop Date],
            ET = Number.Round(Number.From([Stop Time])/100,0),
            LD = List.Dates( SD, Number.From ( ED-SD ) +1, Duration.From(1)),
            LT = if SD = ED then { ET - ST } else { 24-ST } & List.Repeat( { 24 }, List.Count( LD )-2 ) & { ET },
            t = Table.FromColumns(
                {
                    LD, // 核心修改:移除Date.EndOfMonth转换,直接使用实际日期列表
                    LT
                },  type table [ Date = Date.Type, Hrs = Int8.Type ]
            )
        ][t]
    )[[Id],[CrewUNID],[Egendefinert]],
    // 移除错误行
    #"Fjernede feil" = Table.RemoveRowsWithErrors(#"Egendefinert lagt til", {"Egendefinert"}),
    // 展开嵌套表
    #"Utvidet Egendefinert" = Table.ExpandTableColumn(#"Fjernede feil", "Egendefinert", {"Date", "Hrs"}, {"Date", "Hrs"})
in
    #"Utvidet Egendefinert"

修改说明

  1. 核心调整:移除日期列表的Date.EndOfMonth转换,直接使用List.Dates生成的实际每日日期,确保工时与对应日期正确关联
  2. 保留原有工时计算逻辑:
    • 登船与下船为同一天时,直接计算时间差
    • 跨天情况下,起始日统计剩余时长、中间日按24小时计算、结束日统计当日时长
  3. 其余数据清洗、格式转换步骤保持不变,确保原有数据处理流程的一致性

内容的提问来源于stack exchange,提问作者exxons

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:20:28