Attachment 'netCSV.v1.0.txt'

Download

   1 :Namespace netCSV
   2 
   3     ⎕USING←0⍴⊂''
   4 
   5     (⎕IO ⎕ML ⎕WX)←1 3 3
   6 
   7       TsToDateString←{
   8         ⍝ ⍵ = ⎕TS
   9         ⍝ Result = Date formatted to a String with no ambiguity.
  10      
  11           ⎕USING←'System,mscorlib.dll' 'System.Xml,System.Xml.dll'
  12           XmlConvert.ToString(((⎕NEW DateTime ⍵))(,'dd-MMM-yyyy'))
  13       }
  14 
  15       TsToTimeString←{
  16         ⍝ ⍵ = ⎕TS
  17         ⍝ Result = Date formatted to a String with no ambiguity.
  18      
  19           ⎕USING←'System,mscorlib.dll' 'System.Xml,System.Xml.dll'
  20           XmlConvert.ToString(((⎕NEW DateTime ⍵))(,'h:mm:ss tt'))
  21       }
  22 
  23       TsToDateTimeString←{
  24         ⍝ ⍵ = ⎕TS
  25         ⍝ Result = Date formatted to a String with no ambiguity.
  26      
  27           ⎕USING←'System,mscorlib.dll' 'System.Xml,System.Xml.dll'
  28           XmlConvert.ToString(((⎕NEW DateTime ⍵))(,'dd-MMM-yyyy h:mm:ss tt'))
  29       }
  30 
  31     ∇ records←{FieldDecSep}AplToCsvRecords aplArray;decimalSeparator;fieldSeparator;test;⎕PP
  32     ⍝ Convert an Apl array to individual CSV records (one record per row of the array).
  33     ⍝ Use the function 'CsvFileAddRecords' to Append the records to a CSV file.
  34     ⍝ Example:  fileName CsvFileAddRecords AplToCsvRecords aplArray
  35 
  36     ⍝ Use the function 'CsvFileNew' to Create the initial CSV file with a Header.
  37 
  38     ⍝ aplArray    = Apl array
  39     ⍝ FieldDecSep = Field and Decimal Separator (like ',.' or ';,' )
  40     ⍝ records     = one record per row of 'apl' formatted according to the CSV format
  41      
  42       :If 0≠⎕NC'FieldDecSep'
  43           (fieldSeparator decimalSeparator)←FieldDecSep
  44       :Else
  45         ⍝ Default values
  46           (fieldSeparator decimalSeparator)←',.' ⍝ North America
  47     ⍝     (fieldSeperator decimalSeparator)←';,' ⍝ Europe
  48       :End
  49      
  50     ⍝ Used by ⍕ to display the number of significant digits
  51       ⎕PP←5
  52      
  53       :If ~0∊test←{0=↑1↑0⍴⍵}¨,aplArray
  54         ⍝ 'apl' is all Numeric. This expression is optimize for all numeric array.
  55           records←fieldSeparator{p←⍵ ⋄ ((p=' ')/p)←⍺ ⋄ ((p='¯')/p)←'-' ⋄ p}¨⍕¨↓aplArray
  56           records←{(decimalSeparator,⍵)[('.',⍵)⍳⍵]}¨records
  57      
  58       :Else
  59         ⍝ 'apl' is all characters or a mixture of numeric and characters
  60         ⍝ Code inspired from: http://aplwiki.com/CsvToApl
  61           (test/,aplArray)←{('-',⍵)[('¯',⍵)⍳⍵]}¨⍕¨test/,aplArray             ⍝ Make numbers characters
  62           (test/,aplArray)←{(decimalSeparator,⍵)[('.',⍵)⍳⍵]}¨test/,aplArray  ⍝ Change the decimal separator
  63           test←,'"'∊¨,aplArray                                 ⍝ Double quotes in the text ?
  64           (test/,aplArray)←{⍵/⍨1+'"'=⍵}¨test/,aplArray         ⍝ Double the double quotes
  65           test←∨/¨(⊂fieldSeparator,'"',⎕UCS 13 10)∊¨,aplArray  ⍝ Special characters ?
  66           (test/,aplArray)←{'"',⍵,'"'}¨test/,aplArray          ⍝ Put double quotes on fields with special characters
  67           records←{⊃{⍺,fieldSeparator,⍵}/⍵}¨↓aplArray          ⍝ Separate fields with fieldSeparator
  68      
  69       :End
  70 
  71 
  72     ∇ r←fileName CsvFileAddRecords records;⎕USING
  73     ⍝ Function to Add Record(s) to a CSV file.
  74 
  75     ⍝ records =  Line(s) of text with a delimiter like ',' or ';'
  76     ⍝ fileName = Fully qualified file name with extension.
  77     ⍝ r        = 1 if successfull, 0 (ERROR) if failure
  78      
  79       :If 1=≡records
  80           records←⊂records
  81       :EndIf
  82      
  83     ⍝ Add a LF and CR to each record(s) and flatten the result.
  84       records←∊{⍵,⎕UCS 13 10}¨records
  85      
  86       :Trap 0
  87           ⎕USING←',mscorlib.dll'
  88           System.IO.File.AppendAllText((⊂,fileName),(⊂,records),(System.Text.Encoding.UTF8))
  89           r←1
  90       :Else
  91         ⍝ Failure: Unexpected Error While Writing the File
  92           r←0('EXCEPTION CsvFileAddRecords: ',⎕EXCEPTION.Message)
  93       :EndTrap
  94 
  95 
  96     ∇ r←fileName CsvFileNew header;⎕USING
  97     ⍝ Function to Create a New File with a CSV Header
  98 
  99     ⍝ header   = Columns Names separated by a delimiter like ',' or ';'
 100     ⍝ fileName = Fully qualified file name with extension.
 101     ⍝ r        = 1 if successfull, 0 (ERROR) if failure
 102      
 103       header,←⎕UCS 13 10 ⍝ Add CR and LF to the header
 104      
 105       :Trap 0
 106           ⎕USING←',mscorlib.dll'
 107           System.IO.File.WriteAllText((⊂,fileName),(⊂,header),(System.Text.Encoding.UTF8))
 108           r←1
 109       :Else
 110         ⍝ Failure: Unexpected Error While Writing the File
 111           r←0('EXCEPTION CsvFileNew: ',⎕EXCEPTION.Message)
 112       :EndTrap
 113 
 114 
 115     ∇ dt←{FieldDecSep}CsvFileToDT fileName;bufferSize;colNames;cols;colTypes;comment;csv;cultureInfo;escape;fieldCount;fields;firstRecord;hasHeaders;headerRecord;headers;ms;nullValue;quote;sr;streamReader;trimmingOptions;⎕USING;decimalSeparator;fieldSeparator
 116     ⍝ Parse a CSV file to a DataTable with DataTypes preserved
 117     ⍝ Based on: http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
 118     ⍝ and https://github.com/phatcher/CsvReader
 119     ⍝ The assembly LumenWorks.Framework.IO.dll needs to be in the same directory as Dyalog.exe
 120 
 121     ⍝ fileName    = fully qualified file name with extension
 122     ⍝ FieldDecSep = Field and Decimal Separator (like ',.' or ';,' )
 123     ⍝ dt          = DataTable with DataType preserved
 124 
 125     ⍝ The CSV file must have a Header record, it will be used to give the names to the DataCcolumns of the DataTable
 126     ⍝ The Header can have the DataType of the column within {}, otherwise the DataType will be detected automatically.
 127      
 128       :If 0≠⎕NC'FieldDecSep'
 129           (fieldSeparator decimalSeparator)←FieldDecSep
 130       :Else
 131         ⍝ Default values
 132           (fieldSeparator decimalSeparator)←',.' ⍝ North America
 133     ⍝     (fieldSeparator decimalSeparator)←';,' ⍝ Europe
 134       :End
 135      
 136       ⎕USING←'System.IO,mscorlib.dll' 'LumenWorks.Framework.IO.Csv,LumenWorks.Framework.IO.dll'
 137       ⎕USING,←'System.Data,System.Data.dll' 'System,mscorlib.dll' 'System.Globalization,mscorlib.dll'
 138      
 139     ⍝ Use your local Culture if not appropriate
 140     ⍝ To obtain the Default DecimalSeparator, ThousandsSeparator and CSVSeparator on this computer you can do:
 141     ⍝      ⎕USING←'System.Globalization,mscorlib.dll'
 142     ⍝      CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator
 143     ⍝      CultureInfo.CurrentCulture.NumberFormat.NumberGroupSeparator
 144     ⍝      CultureInfo.CurrentCulture.TextInfo.ListSeparator
 145     ⍝ To obtain your current culture you can do:
 146     ⍝      CultureInfo.CurrentCulture
 147     ⍝ See also https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo%28v=vs.110%29.aspx
 148       cultureInfo←⎕NEW CultureInfo(⊂'en-US')
 149       cultureInfo.NumberFormat.NumberDecimalSeparator←,decimalSeparator
 150      
 151     ⍝ Set-up those options before constructing the CsvReader. They cannot be setup later
 152       hasHeaders←0       ⍝ Must be zero to be able to define the DataType of the columns. If 1 all columns are automatically of String type.
 153       quote←'"'
 154       escape←'"'
 155       comment←'#'        ⍝ First character of a record that will not be parse
 156       trimmingOptions←1  ⍝ 0=None, 1=Unquoted Only, 2=Quoted Only, 3=All
 157       bufferSize←4096
 158       nullValue←⊂''
 159      
 160     ⍝ Construct the StreamReader
 161       streamReader←⎕NEW StreamReader(⊂,fileName)
 162      
 163     ⍝ Read the Header and remove all the blanks
 164       headerRecord←(streamReader.ReadLine)~' '
 165      
 166     ⍝ Read the first record. Could be multiline.
 167       firstRecord←''
 168       :While 0=streamReader.EndOfStream
 169           firstRecord,←streamReader.ReadLine
 170       :Until 0=1|0.5×+/firstRecord=quote ⍝ Read until even number of quotes
 171      
 172      ⍝ Reset the StreamReader to the beginning.
 173       streamReader.DiscardBufferedData
 174       {}streamReader.BaseStream.Seek((Convert.ToInt64 0),SeekOrigin.Begin)
 175       streamReader.BaseStream.Position←Convert.ToInt64 0
 176      
 177     ⍝ Construct the CsvReader
 178       csv←⎕NEW CsvReader(streamReader,hasHeaders,fieldSeparator,quote,escape,comment,trimmingOptions,bufferSize,nullValue)
 179       csv.MissingFieldAction←csv.MissingFieldAction.ReplaceByNull
 180       csv.DefaultParseErrorAction←csv.DefaultParseErrorAction.AdvanceToNextLine
 181       csv.SkipEmptyLines←1
 182       csv.SupportsMultiline←1
 183      
 184     ⍝ Split the headerRecord at the fieldSeparator character
 185       headers←(~fieldSeparator=headerRecord)⊂headerRecord
 186      
 187     ⍝ Split the first record at the fieldSeparator character
 188       fields←(~fieldSeparator=firstRecord)⊂firstRecord
 189      
 190     ⍝ Read the Header Record and discard it.
 191       {}csv.ReadNextRecord
 192      
 193     ⍝ Check if the DataType was specify in the Header, otherwise detect it on the first record.
 194       colTypes←''
 195       :For header field :In (headers{⍺ ⍵}¨fields)
 196           :If ∧/'{}'∊header
 197             ⍝ DataType is specified in the Header record
 198             ⍝ Could be: Boolean, Byte, Decimal, Double, Single, Int64, Int16, String, DateTime
 199               colTypes,←⊂{h←⌽(⍵⍳'{')↓⍵ ⋄ h←⌽(h⍳'}')↓h ⋄ h}header  ⍝ Get data type between {} of the header
 200      
 201           :Else
 202             ⍝ DataType was not specified in the Header record
 203             ⍝ Analyse the first record to find the DataType
 204             ⍝ The DataType detected will be either: DateTime, Double or String
 205             ⍝ If the first record has empty field(s) it will default to String
 206      
 207               colTypes,←⊂cultureInfo DetectDataType field
 208           :End
 209      
 210       :EndFor
 211      
 212     ⍝ Create the Columns with the DataType, Name and CultureInfo
 213       colNames←{h←(¯1+⍵⍳'{')↑⍵ ⋄ h}¨headers    ⍝ Get the column names from the split headerRecord
 214       cols←⎕NEW¨(⍴headers)⍴Column              ⍝ Instantiate the Columns
 215       cols.Culture←cultureInfo                 ⍝ Set the Culture for each columns for proper parsing
 216       cols.Name←colNames                       ⍝ Set the Columns Names
 217       cols.Type←⍎¨colTypes                     ⍝ Set the Columns Types
 218       csv.Columns.Add¨cols                     ⍝ Set all the Columns previously constructed
 219      
 220     ⍝ Cronstruct the DataTable from the CsvReader
 221       dt←⎕NEW DataTable
 222       dt.TableName←fileName
 223       dt.Load csv
 224      
 225     ⍝ ↓↓↓ Uncomment to see the DataType of each column(s).
 226       (⌷dt.Columns).DataType
 227      
 228     ⍝ Clean-up
 229       streamReader.Close ⋄ streamReader.Dispose ⋄ streamReader←⎕NULL
 230       csv.Dispose ⋄ csv←⎕NULL
 231 
 232 
 233     ∇ noRows←dt DTtoCsvFile fileName;application;excelEngine;workbooks;⎕USING;fieldDelimiter
 234     ⍝ Convert a DataTable to a CSV file.
 235     ⍝ Using the librairy of Syncfusion XlsIO.
 236     ⍝ It is using the Decimal Separator of the local culture.
 237 
 238     ⍝ fileName = fully qualified CSV file name with extension (could be different than .csv)
 239     ⍝ dt       = DataTable with columns as DateTime, String or Double types.
 240     ⍝ noRows   = Number of rows written to fileName.
 241      
 242       ⎕USING←'Syncfusion.XlsIO,Syncfusion/4.5/Syncfusion.XlsIO.Base.dll' 'System.Text,mscorlib.dll'
 243      
 244     ⍝ Default fieldDelimiter
 245       fieldDelimiter←,','
 246      
 247     ⍝ Instantiate the spreadsheet creation engine.
 248       excelEngine←⎕NEW ExcelEngine
 249      
 250     ⍝ Instantiate the excel application object.
 251       application←excelEngine.Excel
 252       application.DefaultVersion←application.DefaultVersion.Excel2013
 253      
 254     ⍝ Create one worksheet
 255       workbooks←application.Workbooks.Create 1
 256      
 257     ⍝ Import the DataTable to the worksheet
 258       noRows←workbooks.Worksheets[0].ImportDataTable dt 1 1 1 1 ⍝ DataTable, KeepHeader, FirstRow, FirstColumn, PreserveType
 259      
 260     ⍝ Save as CSV file with the UTF-8 format.
 261       workbooks.Worksheets[0].SaveAs(fileName fieldDelimiter Encoding.UTF8)
 262      
 263     ⍝ Clean-up
 264       workbooks.Close ⍬
 265       excelEngine.ThrowNotSavedOnDestroy←0
 266       excelEngine.Dispose
 267 
 268 
 269     ∇ dataType←culture DetectDataType string;dateStyle;numberStyle;ptr;⎕USING
 270     ⍝ Detect the DataType of 'string' using CultureInfo
 271     ⍝ The 3 types detected are: DateTime, Double and String
 272 
 273     ⍝ string  = vector of characters
 274     ⍝ culture = CultureInfo object
 275      
 276       ⎕USING←'System,mscorlib.dll' 'Dyalog' 'System.Globalization,mscorlib.dll'
 277      
 278       dateStyle←Globalization.DateTimeStyles.None
 279       numberStyle←culture.NumberStyles.Any
 280      
 281     ⍝ Test to detect if 'string' is a Double
 282       ptr←⎕NEW ByRef(0)
 283       :If 1=Double.TryParse((,string)numberStyle culture ptr)
 284     ⍝ Success
 285           dataType←'Double' ⋄ →0
 286       :EndIf
 287      
 288     ⍝ Test to detect if 'string' is a DateTime
 289       ptr←⎕NEW ByRef(⎕NEW DateTime ⎕TS)
 290       :If 1=DateTime.TryParse((,string)culture dateStyle ptr)
 291     ⍝ Success
 292           dataType←'DateTime' ⋄ →0
 293       :EndIf
 294      
 295     ⍝ Default value if DateTime or Double are not detected
 296       dataType←'String'
 297 
 298 
 299     ∇ ShowDT dt;dg;win;⎕USING
 300     ⍝ Show a DataTable in a Syncfusion's Grid
 301     ⍝ dt = DataTable to Show
 302      
 303       ⎕USING←'System.Windows,WPF/PresentationFramework.dll'
 304       ⎕USING,←⊂'Syncfusion.UI.Xaml.Grid,Syncfusion/4.5/Syncfusion.SfGrid.WPF.dll'
 305      
 306       win←⎕NEW Window
 307       win.(Width Height)←640 480
 308       win.Title←'Show DataTable [ ',(dt.TableName),' ]'
 309      
 310       dg←⎕NEW SfDataGrid
 311       dg.AutoGenerateColumns←1
 312       dg.ItemsSource←dt           ⍝ ← the DataTable is set here
 313       dg.AllowResizingColumns←1
 314       dg.(ColumnSizer←ColumnSizer.Star)
 315       dg.AllowEditing←1
 316      
 317       win.Content←dg
 318       win.Show
 319 
 320 
 321     ∇ dt←{fieldSeparator}SimpleCsvFileToDT fileName;bufferSize;comment;csv;escape;hasHeaders;nullValue;quote;streamReader;trimmingOptions;⎕USING
 322     ⍝ Simple CSV File parser to a DataTable where all the DataColumns are of DataType 'String'
 323     ⍝ Based on: http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader
 324     ⍝ and https://github.com/phatcher/CsvReader
 325     ⍝ The assembly LumenWorks.Framework.IO.dll needs to be in the same directory as Dyalog.exe
 326 
 327     ⍝ fieldSeparator = Typically ',' or ';'
 328     ⍝ fileName       = fully qualified file name with extension
 329 
 330     ⍝ Note: The CSV file must have a Header record, it will be used to give the names to the DataColumns.
 331      
 332       ⎕USING←'System.IO,mscorlib.dll' 'LumenWorks.Framework.IO.Csv,LumenWorks.Framework.IO.dll' 'System.Data,System.Data.dll'
 333      
 334       :If 0=⎕NC'fieldSeparator'
 335           fieldSeparator←',' ⍝ Default value if absent
 336       :End
 337      
 338     ⍝ Set-up those options before constructing the CsvReader
 339       hasHeaders←1
 340       quote←'"'
 341       escape←'"'
 342       comment←'#' ⍝ First character of a record that will not be parse
 343       trimmingOptions←1 ⍝ 0=None, 1=Unquoted Only, 2=Quoted Only, 3=All
 344       bufferSize←4096
 345       nullValue←⊂''
 346      
 347     ⍝ Construct the StreamReader
 348       streamReader←⎕NEW StreamReader(⊂,fileName)
 349      
 350     ⍝ Construct the CsvReader
 351       csv←⎕NEW CsvReader(streamReader,hasHeaders,fieldSeparator,quote,escape,comment,trimmingOptions,bufferSize,nullValue)
 352       csv.MissingFieldAction←csv.MissingFieldAction.ReplaceByNull
 353       csv.DefaultParseErrorAction←csv.DefaultParseErrorAction.AdvanceToNextLine
 354       csv.SkipEmptyLines←1
 355       csv.SupportsMultiline←1
 356      
 357     ⍝ Create the DataTable from the CsvReader
 358       dt←⎕NEW DataTable
 359       dt.TableName←fileName
 360       dt.Load csv
 361      
 362     ⍝ Clean-up
 363       streamReader.Close ⋄ streamReader.Dispose ⋄ streamReader←⎕NULL
 364       csv.Dispose ⋄ csv←⎕NULL
 365 
 366 
 367 :EndNamespace

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2016-02-07 13:38:03, 0.7 KB) [[attachment:Client.csv]]
  • [get | view] (2016-02-07 13:24:16, 34.8 KB) [[attachment:Client.png]]
  • [get | view] (2016-02-09 22:08:03, 4027.0 KB) [[attachment:FL_insurance_sample.csv]]
  • [get | view] (2016-02-06 13:49:06, 45.0 KB) [[attachment:LumenWorks.Framework.IO.dll]]
  • [get | view] (2016-02-07 14:39:38, 137.9 KB) [[attachment:ZipCode.csv]]
  • [get | view] (2016-02-07 14:39:58, 54.9 KB) [[attachment:ZipCode.png]]
  • [get | view] (2016-02-07 14:13:44, 10.7 KB) [[attachment:msft.csv]]
  • [get | view] (2016-02-07 14:18:30, 53.4 KB) [[attachment:msft.png]]
  • [get | view] (2016-02-10 03:02:48, 16.0 KB) [[attachment:netCSV.v1.0.txt]]
  • [get | view] (2016-04-29 13:48:55, 16.9 KB) [[attachment:netCSV.v1.1.txt]]
 All files | Selected Files: delete move to page

You are not allowed to attach a file to this page.