使用 Power Query 将格式化字符串分析为货币 (MS Excel)

Parsing a formatted string into Currency with Power Query (MS Excel)

提问人:Hazard 提问时间:11/18/2023 最后编辑:Hazard 更新时间:11/23/2023 访问量:68

问:

我正在尝试将数据从 REST API 导入 MS Excel 工作表。货币字段的格式为“十进制数|ISO 3 字符货币代码“等。123.45|USD678.90|EUR

如何将这些值解析为“货币(Excel 类型)”列?我尝试用空格替换竖线字符并选择自定义货币格式类型,但无济于事。我认为它需要货币符号,而不是货币代码。

Excel PowerQuery

评论

0赞 Davide Bacci 11/18/2023
您的数据中有多少种货币类型?只是美元?
0赞 Hazard 11/18/2023
@DavideBacci不仅仅是美元;我抽样了数据,目前有 9 种不同的货币。
0赞 horseyride 11/18/2023
我不明白所需的结果。你只想要号码吗?您想要基于 alpha 部分的数字前面带有 $ 或 € 字符吗?
0赞 Hazard 11/18/2023
@horseyride 所需的结果是一个单元格格式为“Currency”的数字(管道前的小数部分)(手动过程如下:i.stack.imgur.com/NuTcW.png)
1赞 Ron Rosenfeld 11/18/2023
Excel 没有数据类型。您看到的是一个十进制数,格式化为包含货币符号。如果这是您想要的,您将需要使用VBA,因为所有单元格的格式都不相同。您可以在 PQ 中执行此操作,将 ISO 代码替换为符号,并将字符串作为文本返回,但您不能将此类数据的数字格式从 PQ 返回到 Excel。Currency

答:

0赞 user9237034 11/18/2023 #1

我假设您正在使用 PQE 转换脚本? 如果是这样,则可以使用“转换>提取>分隔符前的文本”来拆分管道上的单元格并忽略货币代码字段。将剩余字段强制转换为货币。

Screen shot of Transform step

评论

0赞 Hazard 11/18/2023
谢谢;但如果可能的话,我想将货币保留在同一个 Excel 单元格中(带格式)。您的建议将从一个字段中创建两列,不幸的是,数据中有许多货币字段。
0赞 user9237034 11/18/2023
如果使用 TRANSFORM 功能区版本的 Extract,它将在原地编辑单元格,将结果保留在所需的位置。使用 ADD COLUMN 版本将创建多个列。
1赞 horseyride 11/18/2023 #2

在 powerquery 中,可以转换列以提取管道之前的所有内容,并将其转换为货币值,但货币字符在加载回 Excel 时不会保留

  Split = Table.TransformColumns(#"PriorStepNameHere",{{"ColumnNameHere", each Number.From(Text.BeforeDelimiter(_,"|")), Currency.Type}})
1赞 ninMonkey 11/18/2023 #3

下面是一个完全独立的查询,可以正常工作。选择“new query => blank file”。然后单击高级编辑器,并粘贴此内容。

@horseyride使用了类似的路线。我保留了货币类型以供使用。

这个参数很重要,它改变了数字的转换方式。否则,它将使用运行查询的系统上的默认值。Currency

您可以从“add column”或“Transform column”调用转换函数。主要区别在于一个替换了原来的列,另一个保留了它。

可以使用函数的回退,或设置如下区域性:

AsCurrency( row[Text] )
AsCurrency( row[Text], [ Culture = "de-de" ] )
let
    Json = Table.FromRows(Json.Document(Binary.Decompress(Binary.FromText("i45WMjO30LM0qHENDVKK1YlWMjQy1jMxrQkNdlGKjQUA", BinaryEncoding.Base64), Compression.Deflate)), let _t = ((type nullable text) meta [Serialized.Text = true]) in type table [Text = _t]),
    Source = Table.TransformColumnTypes(Json,{{"Text", type text}}),

    // converts "678.90|EUR" to [ Unit = "EUR", Amount = "678.90" ]
    AsCurrency = ( source as text, optional options as nullable record ) as any => [
        Culture = options[Culture]? ?? "en-us",
        RoundingMode = options[Culture]? ?? null,
        segments = Text.Split( source, "|"),
        return = [
            Unit = segments{1},
            Amount = Currency.From( segments{0}, Culture, RoundingMode )
        ]
    ][return],

    convertFromCurrency = Table.AddColumn( Source, "CoerceCurrency", (row) as record => AsCurrency( row[Text] ), Record.Type ),
    #"Expanded CoerceCurrency" = Table.ExpandRecordColumn( 
        convertFromCurrency, "CoerceCurrency", {"Unit", "Amount"}, {"Unit", "Amount"}),

    #"Changed Type" = Table.TransformColumnTypes(#"Expanded CoerceCurrency",
        {{"Unit", type text}, {"Amount", Currency.Type}}, "en-us")
in
    #"Changed Type"