Dynamo CSV Export => decimal separator

Hi,

I need to export number lists in CSV format (separator = comma). When exporting with the node data.exportCSV, the comma is also used to separate the decimals… Big problem !
Is it possible to use points as a decimal separator?

Thanks !

Vincent

Try making a tsv file instead. String join the datarows with a tab, join those with a linebreak snd then write text.

Or simply use the export to excel node:
In my case the csv is then tab delimited

EDIT#1:

Just tried @GavinCrump 's method and it works. BUT if I use codeblocks for the delimiters it does not work. You really need to use the string node:

2 Likes

Tsv is generally my goto as some regions use commas as decimals (e.g. france, spain) and it gets around dynamo export issues that are common pre 2022. Commas are also common in text based long form fields such as room descriptions.

My first go is to change the settings in excel, as most programms generate comma delimited csv files and in germany excel’s default setting is , instead of . for decimal values and the delimiter for germany is semicolon by default. I even change the keyboard layout/language to switzerland/suiss because then the comma on my num block is then a point, which makes entering numbers easier for me in dynamo

Thanks a lot for your answers. Indeed I could use another node or do a TSV export…

But I saw that on another PC (here a Windows 10 emulated on MacOS) I don’t have the same problem… So it must be possible to adjust somewhere what is the separator used for the decimals !

An idea ?

Its probably a windows region setting. Some countries use commas instead of decimals still (crazy!).

I don’t know how deep your knowledge is regarding python, but I’m shure you could build your own Data.ExportCSV node via python like @GavinCrump did here with exporting data to excel here:

If you have a look at the code on github you will see that you should be able to create your own method and replace the “,” with an semicolon “;” or anything you want:

public static class Data
    {
        /// <summary>
        ///     Write a list of lists into a file using a comma-separated values 
        ///     format. Outer list represents rows, inner lists represent columns. 
        /// </summary>
        /// <param name="filePath">Path to write to</param>
        /// <param name="data">List of lists to write into CSV</param>
        /// <search>write,text,file</search>
        public static void ExportCSV(string filePath, object[][] data)
        {
            using (var writer = new StreamWriter(DSCore.IO.FileSystem.AbsolutePath(filePath)))
            {
                foreach (var line in data)
                {
                    int count = 0;
                    foreach (var entry in line)
                    {
                        writer.Write(entry);
                        if (++count < line.Length)
                            writer.Write(",");
                    }
                    writer.WriteLine();
                }
            }
        }

Source: https://github.com/DynamoDS/Dynamo/blob/1167f83d53a5e327e2f13fbc9fec884bf1d7c6b6/src/Libraries/DSOffice/Excel.cs

But here ends my knowledge, as I am able to reference/use methods from the api in python, but recreating things like gavin did in the topic mentioned above is above my skill level :smiling_face_with_tear:

This does not solve your problem of getting commas as a decimal seperator for shure, but at least you can work with the csv then. In excel you could either way use the legacy import of csv’s where you can choose the delimiter or you could create and run a batch-file to replace every comma for a point and then replace every semicolon for a comma.
If you need a batch file that can do this, I can provide it, as I have already been in need for such a batch file before.

EDIT#1:
Thanks to ChatGPT this does create a csv with the delimiter you want:

import clr
import System
clr.AddReference("ProtoGeometry")
clr.AddReference("RevitAPI")
from Autodesk.DesignScript.Geometry import *
from Autodesk.Revit.DB import *
from System.Collections.Generic import List

def export_csv_file(file_path, data, delimiter):
    csv_str = ""
    for row in data:
        for i, val in enumerate(row):
            if i != 0:
                csv_str += delimiter
            csv_str += str(val)
        csv_str += "\n"
    System.IO.File.WriteAllText(file_path, csv_str)
    
""" Example usage
data = [["Name", "Age", "City"], ["John", 25, "New York"], ["Jane", 30, "Paris"], ["Bob", 40, "London"]]
file_path = "C:\\Temp\\data.csv"
delimiter = ";"
"""
data = IN[0]
file_path = IN[1]
delimiter = IN[2]
export_csv_file(file_path, data, delimiter)

If you have a list of lists you can make a separated file using string.join with strings @L2 and any separator you want. You can then string join those with a return (enter) and finally use the write file node including desired extension with that as the text.

There is also examples or reading/writing csv using Python here: csv — CSV File Reading and Writing — Python 3.11.2 documentation

Thank you very much again for all these detailed answers.
Indeed, Python or the string.join node are also good solutions…
But I will deepen this “windows region setting” : I have to teach in different schools with differents settings and I would like to understand why the different machines do not behave the same way!

Confirmation : it’s the “windows region setting” !

Thank you for your help !

1 Like