delimiterpowerqueryregional-settings

Power Query - regional settings


I've made a best practice sheet for my department, which works perfectly on my own computer (en-US regional settings), but when I sent it to a coworker, everything blew up (da-DK regional settings).

Half the department uses en-US and the other half uses da-DK. It's not an option for everybody to use the same, so I'd like to create a sheet that can handle both automatically.

The csv files created in en-US uses "," delimiter and a "." for decimal, while the da-DK settings uses ";" as delimiter and "," for decimals.

How would I best go about this issue?

I have the following two identical data queries

Data1.csv:

    Panel/Node/Case,    MXX (kNm/m),    MYY (kNm/m)
    1/ 1/ 1,            145.46,         145.46  
    1/ 1/ 2,            98.83,          98.83   
    1/ 1/ 3 (C),        244.30,         244.30  
    1/ 2/ 1,            19.80,          19.80   
    1/ 2/ 2,            13.46,          13.46   
    1/ 2/ 3 (C),        33.26,          33.26   
    1/ 3/ 1,            19.80,          19.80   
    1/ 3/ 2,            13.46,          13.46   
    1/ 3/ 3 (C),        33.26,          33.26   
    1/ 4/ 1,            145.46,         145.46  
    1/ 4/ 2,            98.83,          98.83   
    1/ 4/ 3 (C),        244.30,         244.30

Data2.csv:

    Panel/Node/Case;    MXX (kNm/m);    MYY (kNm/m)
    1/ 1/ 1;            145,46;         145,46
    1/ 1/ 2;            98,83;          98,83
    1/ 1/ 3 (C);        244,30;         244,30
    1/ 2/ 1;            19,80;          19,80
    1/ 2/ 2;            13,46;          13,46
    1/ 2/ 3 (C);        33,26;          33,26
    1/ 3/ 1;            19,80;          19,80
    1/ 3/ 2;            13,46;          13,46
    1/ 3/ 3 (C);        33,26;          33,26
    1/ 4/ 1;            145,46;         145,46
    1/ 4/ 2;            98,83;          98,83
    1/ 4/ 3 (C);        244,30;         244,30

I was considering to use a replace values function to replace the characters I need, but as both queries contain a "," that proves difficult.


Solution

  • Maybe there is some dynamic/built-in means of detecting a file's content's locale and delimiter. I haven't found one yet. Until someone comes along and points out a better way of doing this, maybe the below can serve as an interim solution.


    let
        data1 = Text.ToBinary(
        "Panel/Node/Case,    MXX (kNm/m),    MYY (kNm/m)
        1/ 1/ 1,            145.46,         145.46  
        1/ 1/ 2,            98.83,          98.83   
        1/ 1/ 3 (C),        244.30,         244.30  
        1/ 2/ 1,            19.80,          19.80   
        1/ 2/ 2,            13.46,          13.46   
        1/ 2/ 3 (C),        33.26,          33.26   
        1/ 3/ 1,            19.80,          19.80   
        1/ 3/ 2,            13.46,          13.46   
        1/ 3/ 3 (C),        33.26,          33.26   
        1/ 4/ 1,            145.46,         145.46  
        1/ 4/ 2,            98.83,          98.83   
        1/ 4/ 3 (C),        244.30,         244.30", TextEncoding.Utf8),
    
        data2 = Text.ToBinary(
        "Panel/Node/Case;    MXX (kNm/m);    MYY (kNm/m)
        1/ 1/ 1;            145,46;         145,46
        1/ 1/ 2;            98,83;          98,83
        1/ 1/ 3 (C);        244,30;         244,30
        1/ 2/ 1;            19,80;          19,80
        1/ 2/ 2;            13,46;          13,46
        1/ 2/ 3 (C);        33,26;          33,26
        1/ 3/ 1;            19,80;          19,80
        1/ 3/ 2;            13,46;          13,46
        1/ 3/ 3 (C);        33,26;          33,26
        1/ 4/ 1;            145,46;         145,46
        1/ 4/ 2;            98,83;          98,83
        1/ 4/ 3 (C);        244,30;         244,30", TextEncoding.Utf8),
    
        parseCsv = (someFile as binary) =>
            let
                lines = Lines.FromBinary(someFile, QuoteStyle.Csv, false, TextEncoding.Utf8),
                firstLine = List.First(lines),
                expectedDelimiterPosition = Text.Length("Panel/Node/Case"), 
                delimiterInferred = Text.At(firstLine, expectedDelimiterPosition),
                csv = Csv.Document(someFile, [Delimiter = delimiterInferred, Encoding = TextEncoding.Utf8, QuoteStyle = QuoteStyle.Csv]),
                promoted = Table.PromoteHeaders(csv, [PromoteAllScalars=true]),
                lastTwoColumnsAsNumbers = 
                    let
                        lastTwoHeaders = List.LastN(Table.ColumnNames(promoted), 2),
                        replaceAndConvertToNumber = (someText as text) as number => Number.From(Text.Replace(someText, ",", ".")),
                        transformers = List.Transform(lastTwoHeaders, each {_, replaceAndConvertToNumber, type number}),
                        transformed = Table.TransformColumns(promoted, transformers)
                    in transformed
            in lastTwoColumnsAsNumbers,
        parsed1 = parseCsv(data1),
        parsed2 = parseCsv(data2),
        parsed3 = parseCsv(File.Contents("C:\Users\MRCH\Desktop\Data1.csv"))
    in
        parsed3
    

    If that doesn't help, let me know where I can improve my explanation.