Hello Rochdi,

Have you resolved this? If not, are you using a report that is derived from %ZEN.Report.reportPage? If you are, you can use the "GenerateReport()" instance method to create an "xlsx" Excel file, which can then be exported to ".csv" after opening it from Excel.

https://docs.intersystems.com/latest/csp/documatic/%25CSP.Documatic.cls?...

Alternatively, the following code highlights how to generate a CSV file containing the results of a query:

ClassMethod ExportCSV(/* some args */) As %String [ ZenMethod ]
{
/* get a results set named "rs" from a query (sql statement, or, in this example a query class):
Set rs=##class(%ResultSet).%New("<some query class")
Do rs.Prepare()
Do rs.Execute(/*some args*/)
*/
// Define the delimeter to be used in CSV file (usually comma)
Set Delim = ","

// Define the file and its name
Set File = ##class(%FileCharacterStream).%New()
Set Filename = "filename.csv"
Set File.BOM = $C(239,187,191)
Set File.Filename = "C:\temp\"_Filename 
Set File.TranslateTable = "UTF8" 
// Define the names of the columns (should match up with the values in each row of the result 
// set. In this example, there are 3 columns
Set FileHeader = $LB("Name","Rank","","SerialNumber")

Do File.WriteLine($ZCVT($LTS(FileHeader, Delim), "O", "UTF8")) 
While rs.%Next()
{
    Set Row = ""
    For = 1:1:$LL(FileHeader) 
    {
        Set col = $LG(FileHeader, i) 
        Set Data = rs.%Get(col)
        // Replace characters that may mess up the CSV file (e.g., embedded commas in a data field)
        Set Data = $REPLACE(Data, $C(13), " ")
        Set Data = $REPLACE(Data, $C(10), " ")
        Set Data = $REPLACE(Data, """", "'")
        Set:(Data [ ",") Data = """"_Data_"""" 
        Set Data = $ZCVT(Data, "O", "UTF8") 
        // Add the datum to the row's list
        Set Row = Row_$LB(Data)
     } 
     // Each element in the "row list" is written, separated by "Delim" (comma) on one line 
     // in the file 
     Do File.WriteLine($LTS(Row, Delim))
} 
// Set attributes of the file for easier reading by the right apps later.
Do File.SetAttribute("ContentType","application/octet-stream; charset=utf-8")
Do File.SetAttribute("ContentDisposition","attachment; filename="""_Filename_"""")
Do File.SetAttribute("Expires",600)
    Do File.SetAttribute("Content-Length",File.Size)
        
    Do File.%Save()
 // Return the name of the full path to the CSV file
 Quit File.Filename
}

Please confirm if this is helpful or if you have other questions.

Thank you 

The above solution is great if you’d like to keep the list in each record of one table. Depending on the nature of the data in your application, another option is to “normalize” the data a bit and create a separate table for the “numDossiersMER” values and link them back to the original “Titre” table as follows.

Convert the planned updated table from this:

User.TestList.Data.Titre

numTitre

millesime

codeProduit

numDossiersMER (list)

1

2021

X

1  2  3

2

2021

X

4  5  6

3

2021

X

4  2  3

4

2022

X

2  5  7  8

To the following 2 normalized tables

User.TestList.Data.TitreNew

Id (IRIS)

numTitre

millesime

codeProduit

1

1

2021

X

2

2

2021

X

3

3

2021

X

4

4

2022

X

User.TestList.Data.DossierMER

Id (IRIS)

titreID

numDossierMER

1

1

1

2

1

2

3

1

3

4

2

4

5

2

5

6

2

6

7

3

4

8

3

2

9

3

3

10

4

2

11

4

5

12

4

7

13

4

8

The “id (IRIS)” in each table is the “ROWID” assigned by IRIS as each entry is created in the table.

Using these two tables, the following “JOIN” query will get the results to be formatted as you like:

select numTitre, millesime, codeProduit, numDossierMER from User_TestList_Data.TitreNew t JOIN User_TestList_Data.DossierMER d on d.TitreId = t.id

Please note that this “normalized” solution is great if the “numDossierMER” values can be shared among various “Titre” records as shown in my made-up example above.

Sample code here:

Class User.TitreNew Extends (%Persistent, %Populate)
{ 
Property numTitre As %Integer; 
Property millesime As %Integer; 
Property codeProduit As %String; 
Index titreIdx On (numTitre, millesime, codeProduit) [ PrimaryKey ]; 
}
Class User.DossierMER Extends (%Persistent, %Populate) 
{ 
Property titreID As %Integer; 
Property numDossierMER As %Integer; 
}

(Please excuse the formatting)

Thank you Evgeny and Stefan, very helpful. A minor note: There is a typo at the end of the control panel url (cspv->csp).