Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Anzeige
Inhaltsverzeichnis

für mich nicht nachvollziehbare Änderung von Zahlen in PQ

Forumthread: für mich nicht nachvollziehbare Änderung von Zahlen in PQ

für mich nicht nachvollziehbare Änderung von Zahlen in PQ
24.05.2025 15:28:13
Christian
Hallo, bitte helft mir. ich versuche aus Tabelle1!A:B das zu machen, was ich nebendran in Spalte D geschrieben habe, also 6 Nachkommastellen, Punkt als Dezimaltrennung und beide Werte in einer Spalte mit Leerzeichen getrennt.

Im Blatt neu mein eigener Versuch mit Powerquery. Jetzt stehe ich vor dem Problem, dass die Werte in Spalte 2 plötzlich viel mehr Nachkommastellen haben, ohne dass ich erkennen könnte wo diese herkommen. Kann mir da jemand Licht ins Dunkel bringen? Wie kann ich dieses Problem lösen?

Danke
Christian

https://www.herber.de/bbs/user/177553.xlsx
Anzeige

12
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
kleiner Nachtrag
24.05.2025 15:32:46
Christian
dies ist ein kleiner Auszug aus einer Tabelle mit 26500 Zeilen, überall sonst funktioniert die Umwandlung, es muss also irgendwas speziell mit diesen Zahlen, so wie sie vorliegen, zu tun haben.
Um etwas Licht...
25.05.2025 20:44:51
Case
Moin Christian, :-)

... ins Dunkel zu bringen, musst du dich mit folgenden Themen befassen: ;-)
https://de.wikipedia.org/wiki/IEEE_754
https://de.wikipedia.org/wiki/Gleitkommazahl
https://learn.microsoft.com/de-de/office/troubleshoot/excel/floating-point-arithmetic-inaccurate-result

In der Beispieldatei habe ich ein paar Spielereien drin: ;-)
https://www.herber.de/bbs/user/177561.xlsx

  • tblErg_Q - so hast du es ja schon.

  • tblErg - nimmt es aus einer Funktion (fncFormLatLon).

  • tblErg_1 - wird auf 4 Stellen gerundet.

  • tblErg_2 - nur eine Zahl ist FALSE. Vermutlich kann sie in PQ als exakte Binärzahl erkannt werden bzw. exakt auf 6 Stellen so rauskommt, dass G17 und 0.###### dasselbe ergeben (G17 ist ein numerischer Format-String und sorgt dafür, dass bis zu 17 signifikante Stellen ausgegeben werden - und zwar so präzise, dass man den Unterschied zur internen IEEE-754-Darstellung einer Double-Zahl sehen kann).

  • tblErg_4 - du siehst deine Zahlen im Original und gerundet.


  • Zu den tblErg_x gehört immer die Funktion darüber. ;-)

    Wenn du es brauchen kannst - OK. Wenn nicht einfach den Nachmittag, Abend weiter entspannt geniessen - Hände in die Taschen und Lapaloma pfeifen. :-)

    Servus
    Case
    Anzeige
    also verstehe ich das richtig
    25.05.2025 21:41:30
    Christian
    Computer können Zahlen mit Nachkommastellen (z. B. 0,1) nicht immer exakt speichern. Das liegt daran, dass Computer intern mit dem Binärsystem arbeitet nicht wie wir mit dem Dezimalsystem.

    Ich kann 1/10 im Dezimalsystem leicht als 0,1 schreiben.
    Im Binärsystem geht das nicht exakt, das ergibt eine endlose Folge von Nullen und Einsen, z. B.:

    0.0001100110011…

    Wenn ich in Power Query z. B. eine Zahl wie 0,1 oder 1,225 in ein anderes Format (z. B. von Text zu Zahl) umwandele, wird diese intern in die binäre Gleitkommazahl umgerechnet – dabei entsteht z. B. so etwas wie:

    1,225 -> 1,2249999999999996

    Power Query zeigt mir dann plötzlich viele Nachkommastellen mit lauter 9er und am Ende eine 6, weil es mir die exakte binäre Zahl anzeigt, die intern gespeichert wurde.

    so hab ich den link zu Microsft verstanden. Korrekt?

    Dann schaue ich mir jetzt mal deine Datei an.
    Anzeige
    AW: Um etwas Licht...
    25.05.2025 21:49:54
    Christian
    Hallo Case,

    so erstmal danke für deine viele Mühe. Wie vorhin schon gesagt, ich sehe den Fehler jetzt darin, dass Excel in Binärdaten rechnet und sich dadurch ungenauigkeiten ergeben, weil es nur eine gewisse Anzahl von Nachkommastellen verarbeiten kann, sowie eine Dezimalzahl mit einer Nachkommastelle in binär meist unendlich viele Nachkommastellen hat.
    Danke für deine Hilfe und noch einen schönen Sonntag
    Christian
    Anzeige
    Also viel...
    25.05.2025 22:06:55
    Case
    Moin Christian, :-)

    ... Mühe hat mich das nun nicht gekostet. Habe mir Funktionen angelegt, welche die ganzen Formatstrings beinhalten. Dann brauche ich nur noch die Zahl und den Formatstring angeben und fertig. ;-)

    Und im Prinzip hast du es erkannt (0,1 (1/10) ist im Binärsystem eine periodische Zahl, also eine unendliche Folge). Du verstehst dann auch den uralten ITler Witz - und fragst nicht "Warum10?": ;-)
    "Es gibt 10 Arten von Menschen: Die, die Binär verstehen, und die, die es nicht tun."

    Servus
    Case
    Anzeige
    AW: Also viel...
    25.05.2025 22:09:38
    Christian
    haha ja hab ihn verstanden, er stimmt aber auch nur, wenn man davon ausgeht dass es eine Binärzahl ist.. wenigstens hab ich etwas geschmunzelt...

    1*2^1+0*2^0=2

    hab mal 3 Semester Wirtschaftsmathematik studiert, ist aber auch schon fast 20 Jahre her.
    AW: kleiner Nachtrag
    24.05.2025 17:16:27
    Eifeljoi 5
    Hallo
    Wenn es hilft so.
    let in
    
    Table.AddColumn(Table.TransformColumns(Excel.CurrentWorkbook(){[Name="Tabelle3"]}[Content],{{"Spalte1", each Number.ToText(
    Number.Round(_, 6), "0.000000"), type text},{"Spalte2", each Number.ToText(Number.Round(_, 6), "0.000000"), type text}}),
    "Kombiniert", each Text.Combine({[Spalte1], [Spalte2]}, " "), type text)
    Anzeige
    AW: kleiner Nachtrag
    24.05.2025 18:35:18
    Christian
    Hallo Eifeljoi,

    erstmal vielen Dank.
    Hast du denn eine Idee, wo die Rattenschwänze herkommen?

    Mache mich dann mal an den Versuch, noch aus dem , einen . zu machen.

    Gruß
    Christian
    Testergebnis (funktioniert)
    24.05.2025 18:46:04
    Christian
    Hallo Eifeljoi,

    der finale Code in der Originaldatei sieht jetzt so aus:

    let
    
    A = Date.ToText(Date.From(DateTime.LocalNow()), "yyyy-MM-dd"),

    Quelle = Csv.Document(
    File.Contents("C:\Users\chris\Downloads\zHV_aktuell_csv." & A & "\zHV_aktuell_csv." & A & ".csv"),
    [Delimiter=";", Columns=17, Encoding=65001, QuoteStyle=QuoteStyle.None]
    ),

    #"Höher gestufte Header" = Table.PromoteHeaders(Quelle, [PromoteAllScalars=true]),

    #"Geänderter Typ" = Table.TransformColumnTypes(#"Höher gestufte Header", {
    {"SeqNo", Int64.Type}, {"Type", type text}, {"DHID", type text}, {"Parent", type text},
    {"Name", type text}, {"Latitude", type number}, {"Longitude", type number},
    {"MunicipalityCode", Int64.Type}, {"Municipality", type text},
    {"DistrictCode", type text}, {"District", type text}, {"Description", type text},
    {"Authority", type text}, {"DelfiName", type text}, {"THID", type text},
    {"TariffProvider", type text}, {"LastOperationDate", type datetime}
    }),

    #"Entfernte Spalten" = Table.RemoveColumns(#"Geänderter Typ", {
    "Type", "DHID", "Parent", "MunicipalityCode", "DistrictCode", "District",
    "Description", "Authority", "DelfiName", "THID", "TariffProvider"
    }),

    #"Gefilterte Zeilen" = Table.SelectRows(#"Entfernte Spalten", each [Municipality] > "-"),

    #"Geänderter Typ1" = Table.TransformColumnTypes(#"Gefilterte Zeilen", {
    {"LastOperationDate", type date}
    }),

    latRef = 50.762407,
    lonRef = 6.999864,

    MitEntfernung = Table.AddColumn(#"Geänderter Typ1", "Entfernung_km", each
    let
    lat1 = latRef * Number.PI / 180,
    lon1 = lonRef * Number.PI / 180,
    lat2 = [Latitude] * Number.PI / 180,
    lon2 = [Longitude] * Number.PI / 180,
    dLat = lat2 - lat1,
    dLon = lon2 - lon1,
    a = Number.Power(Number.Sin(dLat / 2), 2) +
    Number.Cos(lat1) * Number.Cos(lat2) * Number.Power(Number.Sin(dLon / 2), 2),
    c = 2 * Number.Atan2(Number.Sqrt(a), Number.Sqrt(1 - a)),
    r = 6371,
    dist = r * c
    in
    Number.Round(dist, 7)
    ),

    Ergebnis = Table.ReorderColumns(MitEntfernung,{"SeqNo", "Name", "Latitude", "Longitude", "Municipality", "LastOperationDate", "Entfernung_km"}),

    #"Sortierte Zeilen" = Table.Sort(Ergebnis,{{"Entfernung_km", Order.Ascending}}),

    #"Gefilterte Zeilen1" = Table.SelectRows(#"Sortierte Zeilen", each [Entfernung_km] = 80),

    // Angepasst: "Koordinaten" mit Punkt als Dezimaltrennzeichen >>>
    MitKoordinatenSpalte = Table.AddColumn(#"Gefilterte Zeilen1", "Koordinaten", each
    Number.ToText([Latitude], "0.000000", "en-US") & " " & Number.ToText([Longitude], "0.000000", "en-US"),
    type text
    ),

    #"Neu angeordnete Spalten" = Table.ReorderColumns(MitKoordinatenSpalte,{
    "SeqNo", "Name", "Latitude", "Longitude", "Koordinaten", "Municipality", "LastOperationDate", "Entfernung_km"
    })
    in
    #"Neu angeordnete Spalten"


    funktioniert, danke würde mich aber trotzdem mal interessieren, wo diese Rattenschwänze 9999.....6 herkamen
    Schönes Wochenende

    Christian
    Anzeige
    AW: Testergebnis (funktioniert)
    25.05.2025 00:27:44
    Luschi
    Hallo Christian,

    wenn man 26.500 Zeilen aus 1 csv-Datei einliest, dann sollte man seine PQ-Schritte besser strukturieren
    - erst legst die Datentypen aller Spalten fest
    - und anschließend entfernst Du 11 Spalten davon
    - das ist so, als ob man das Zimmer erst aufräumt und dann erst teilweise entrümpelt

    - erst ordnest Du die Spaltenreihenfolge neu
    - dann fügst Du 1 neue Spalten hinten an
    - und dann ordnest Du die Spaltenreihenfolge nochmals
    - da kann man sich doch die erste Reihenfolge-Festlegung sparen

    - bei der hinzugefügten Spalte 'Entfernung_km' sollte man im Table.AddColumn()-Befehl den Datentyp gleich mitgeben.

    Gruß von Luschi
    aus klein-Paris


    Anzeige
    AW: Testergebnis (funktioniert)
    25.05.2025 10:03:09
    Christian
    Hallo Luschi, meinst du so? Danke für die Tipps Gruß Christian

    let
    
    A = Date.ToText(Date.From(DateTime.LocalNow()), "yyyy-MM-dd"),

    Quelle = Csv.Document(
    File.Contents("C:\Users\chris\Downloads\zHV_aktuell_csv." & A & "\zHV_aktuell_csv." & A & ".csv"),
    [Delimiter=";", Columns=17, Encoding=65001, QuoteStyle=QuoteStyle.None]
    ),

    #"Header gesetzt" = Table.PromoteHeaders(Quelle, [PromoteAllScalars=true]),

    // Entferne unnötige Spalten frühzeitig
    #"Spalten reduziert" = Table.RemoveColumns(#"Header gesetzt", {
    "Type", "DHID", "Parent", "MunicipalityCode", "DistrictCode", "District",
    "Description", "Authority", "DelfiName", "THID", "TariffProvider"
    }),

    // Nur gültige Zeilen mit Municipality
    #"Nur gültige Zeilen" = Table.SelectRows(#"Spalten reduziert", each [Municipality] > "-"),

    // Typen erst jetzt konvertieren (nur für noch relevante Spalten)
    #"Typen konvertiert" = Table.TransformColumnTypes(#"Nur gültige Zeilen", {
    {"SeqNo", Int64.Type}, {"Name", type text}, {"Latitude", type number},
    {"Longitude", type number}, {"Municipality", type text},
    {"LastOperationDate", type datetime}
    }),

    // LastOperationDate in Datum umwandeln
    #"LastOperationDate als Datum" = Table.TransformColumnTypes(#"Typen konvertiert", {
    {"LastOperationDate", type date}
    }),

    latRef = x,
    lonRef = y,

    // Entfernung berechnen (inkl. Typdefinition)
    MitEntfernung = Table.AddColumn(#"LastOperationDate als Datum", "Entfernung_km", each
    let
    lat1 = latRef * Number.PI / 180,
    lon1 = lonRef * Number.PI / 180,
    lat2 = [Latitude] * Number.PI / 180,
    lon2 = [Longitude] * Number.PI / 180,
    dLat = lat2 - lat1,
    dLon = lon2 - lon1,
    a = Number.Power(Number.Sin(dLat / 2), 2) +
    Number.Cos(lat1) * Number.Cos(lat2) * Number.Power(Number.Sin(dLon / 2), 2),
    c = 2 * Number.Atan2(Number.Sqrt(a), Number.Sqrt(1 - a)),
    r = 6371.0088,
    dist = r * c
    in
    Number.Round(dist, 7),
    type number
    ),

    // Filter auf 80 km Umkreis
    #"Gefiltert auf Umkreis" = Table.SelectRows(MitEntfernung, each [Entfernung_km] = 80),

    // Koordinaten-Spalte ergänzen
    MitKoordinaten = Table.AddColumn(#"Gefiltert auf Umkreis", "Koordinaten", each
    Number.ToText([Latitude], "0.000000", "en-US") & " " & Number.ToText([Longitude], "0.000000", "en-US"),
    type text
    ),

    // Endgültige Spaltenreihenfolge
    Ergebnis = Table.ReorderColumns(MitKoordinaten, {
    "SeqNo", "Name", "Latitude", "Longitude", "Koordinaten", "Municipality", "LastOperationDate", "Entfernung_km"
    }),

    // Nach Entfernung sortieren
    Sortiert = Table.Sort(Ergebnis,{{"Entfernung_km", Order.Ascending}})
    in
    Sortiert
    Anzeige
    AW: kleiner Nachtrag
    24.05.2025 18:38:07
    Christian
    ok, numbertoText mit "en-US" hat funktioniert.

    Dann teste ich jetzt mal an der Originaldatei
    Anzeige
    Anzeige
    Live-Forum - Die aktuellen Beiträge
    Datum
    Titel
    14.05.2026 13:31:09
    14.05.2026 09:50:42
    13.05.2026 19:14:18