从 Power Query 中的单元格值中提取数据类型?

Extract Datatype from Cell Values in PowerQuery?

如何将每个单元格的数据类型保存到新列中?我希望 'Custom' 列显示“值”列中每个项目的数据类型。我试过使用 Value.Type([values]) 但输出只显示此 'Type' 值。如果我单击 'Type',它会创建一个新的导航查询,我可以看到数据类型保存在其中,但我似乎无法提取它们。

原始类型与归属类型

@AlexisOlson:

This is a possible solution but I don't like it.

你是对的,这个答案不正确。它使用 Table.Schemawhich tests for ascribed types That's usually the right type, but if data isn't transformed correctly, it can be wrong

你需要使用Value.Type()来获取真实/实际primitive type

查询

let
    Sample = {
        123, 0.45, true,
        "text",
        Currency.From(12.34),
        Int64.From(91),
        DateTime.LocalNow(), DateTimeZone.FixedLocalNow(), #date(2021,1,3),
        #duration(0,0,1,3), #binary({2,3,4}),
        #table(type table[Foo=text], {{"bar"}}),
        [ a = "b" ],
        each "x",
        {0..3}
    },
    records = List.Transform(
        Sample,
        (item) => [
            Original = item, 
            Name = TypeToText( Value.Type( item )) 
        ]
    ),
    Final = Table.FromRecords( records, type table[Original = any, Name = text])
in
    Final

Type.ToText.pq

这是 _serialize_typename() 的简化版本,在 DataConnectors/UnitTesting.query.pq

处包含真正的序列化
let
    Type.ToText =  (x, optional funtype as logical) =>
        let
            isFunctionType = (x as type) => try if Type.FunctionReturn(x) is type then true else false otherwise false,
            isTableType = (x as type) =>  try if Type.TableSchema(x) is table then true else false otherwise false,
            isRecordType = (x as type) => try if Type.ClosedRecord(x) is type then true else false otherwise false,
            isListType = (x as type) => try if Type.ListItem(x) is type then true else false otherwise false
        in
            if funtype = null and isTableType(x) then "Table"
            else if funtype = null and isListType(x) then "list"
            else if funtype = null and isFunctionType(x) then "Function"
            else if funtype = null and isRecordType(x) then "Record"
            else if x = type any then "any"
            else let base = Type.NonNullable(x) in
                (if Type.IsNullable(x) then "nullable " else "") &
                (if base = type anynonnull then "anynonnull" else
                if base = type binary then "binary" else
                if base = type date   then "date"   else
                if base = type datetime then "datetime" else
                if base = type datetimezone then "datetimezone" else
                if base = type duration then "duration" else
                if base = type logical then "logical" else
                if base = type none then "none" else
                if base = type null then "null" else
                if base = type number then "number" else
                if base = type text then "text" else
                if base = type time then "time" else
                if base = type type then "type" else

                /* Abstract types: */
                if base = type function then "function" else
                if base = type table then "table" else
                if base = type record then "record" else
                if base = type list then "list"
                else "any /*Actually unknown type*/")
in
    Type.ToText