Attachment 'sfExcel.v2.0.txt'

Download

   1 :Class sfExcel
   2 
   3 ⍝ Cover Class for using the Syncfusion XlsIO namespace.
   4 ⍝ Essential XlsIO is a 100% native .NET library that generates fully functional Microsoft Excel Spreadsheets
   5 ⍝ in native Excel format without depending on Microsoft Excel.
   6 ⍝ Essential XlsIO is a perfect solution for the users who need to read and write Microsoft Excel files.
   7 ⍝ It does not require MS Excel to be installed in the Report generation machine or server.
   8 ⍝ See individual comments of each methods for more info.
   9 
  10 ⍝ Typical usage:
  11 ⍝    xl←⎕NEW sfExcel    ⍝ Instanciate a New Workbook with the default amount of Worksheets (3)
  12 ⍝ or xl←⎕NEW sfExcel 1  ⍝ Instanciate a New Workbook with 1 Worksheet
  13 
  14 ⍝  'A1' xl.SetValue (⊂'Hello World')   ⍝ Set the value of a single cell in A1 notation
  15 ⍝  'B2' xl.SetValue (10 10⍴⍳100)       ⍝ Set the value of a range in A1 notation
  16 ⍝  2 2  xl.SetValue (10 10⍴⍳100)       ⍝ Set the value of a range in RC notation
  17 
  18 ⍝   dt←xl.AplToDT 10 10⍴⍳100                ⍝ Get a .Net DataTable
  19 ⍝   (row col) xl.ImportDataTable dt         ⍝ To import a DataTable at position [row;col]
  20 
  21 ⍝  xl.GetValue 'C4'        ⍝ Get the value of a cell in A1 notation
  22 ⍝  xl.GetValue 4 3         ⍝ Get the value of a single cell in RC notation
  23 ⍝  xl.GetValue 'B2:K11'    ⍝ Get the value of a range in A1 notation
  24 ⍝  xl.GetValue 2 2 11 11   ⍝ Get the value of a range in RC notation
  25 
  26 ⍝  xl.LoadFile fileName    ⍝ Load a Workbook from file
  27 ⍝  xl.SaveAsXlsx fileName  ⍝ Save the Workbook to fileName as .xlsx format
  28 ⍝  xl.SaveAsPdf fileName   ⍝ Save the Workbood to fileName as .pdf format
  29 
  30 ⍝  xl.Dispose              ⍝ To dispose of the class
  31 
  32 ⍝  A range can be defined using:
  33 ⍝   A1 notation (ex.: 'D5:F8')
  34 ⍝   With Row and Column Index (RC notation) (ex.: 'D5:F8' is 5 4 8 6)
  35 ⍝   As a single positive number for the Column index base 1
  36 ⍝   As a single negative number for the Row index base 1
  37 ⍝   With .SetNumber, .SetText, .SetValue you can use the Upper Left position of the range
  38 
  39 ⍝  The methods .SetText and .SetNumber are faster than .SetValue and are preferred when possible.
  40 ⍝  The methods .SetText2/.GetText2 and .SetNumber2/.GetNumber2 are very fast for a large set of number and text.
  41 
  42 ⍝  Known limitations:
  43 ⍝   Shapes are not supported.
  44 
  45 ⍝ Methods in sfExcel:
  46 ⍝  AddAfterLastColumn     - Add a range after the last column.
  47 ⍝  AddAfterLastRow        - Add a range after the last row.
  48 ⍝  AddWorksheet           - Add a new Worksheet.
  49 ⍝  AplToDT                - Create a DataTable from an Apl Array. Each column must be of the same type.
  50 ⍝  AutoFitColumns         - Adjust Width of Column to the Widest Value.
  51 ⍝  AutoFitRows            - Adjust Hight of Rows to the Highest Value.
  52 ⍝  ConvertA1toRC          - Convert from Excel A1 notation to Row and Column Index notation (RC) (base 1).
  53 ⍝  ConvertRCtoA1          - Convert from Row and Column Index notation to Excel A1 notation.
  54 ⍝  DeleteWorksheet        - Delete a Worksheet from Active Workbook.
  55 ⍝  Dispose                - Quit Excel and Dispose of the "XL" object.
  56 ⍝  DTtoApl                - Convert a .Net DataTable to APL.
  57 ⍝  ExportDataSet          - Export the Workbook as a DataSet (collection of DataTables).
  58 ⍝  ExportDataTable        - Export the spreadsheet data as a DataTable.
  59 ⍝  FreezeRows             - Freeze Rows from the Top of WorkSheet.
  60 ⍝  GetActiveWorksheetName - Get the Active Sheet in Active Workbook.
  61 ⍝  GetDisplayText         - Gets the text that is displayed in the cell.
  62 ⍝  GetNumber              - Get data of Active WorkSheet. The data must be only numeric.
  63 ⍝  GetNumber2             - Same as GetNumber but using a DataTable for large array.
  64 ⍝  GetText                - Get data of Active WorkSheet. The data must be only characters.
  65 ⍝  GetText2               - Same as GetText but using a DataTable for large array.
  66 ⍝  GetValue               - Get data of Active WorkSheet. The data can be numeric or text.
  67 ⍝  GetWorksheetsNames     - Get All the Worksheets Names.
  68 ⍝  ImportDataTable        - Import a DataTable at [row;col] position in the Active Worksheet.
  69 ⍝  LastColumn             - Get the Last Column of a Worksheet.
  70 ⍝  LastRow                - Get the Last Row of a Worksheet.
  71 ⍝  LoadFile               - Load an Excel Workbook file.
  72 ⍝  LoadFromStream         - Load an Excel Workbook from a Stream obtained by the method 'SaveAsStream'
  73 ⍝  Merge                  - Merge Text in Range.
  74 ⍝  OADateToTs             - ⎕TS from OA Date.
  75 ⍝  Print                  - Print using XlsIo (without Excel).
  76 ⍝  RangeDimension         - Get the dimension of a range (no of rows, no of columns).
  77 ⍝  SaveAsCSV              - Save to file the specify worksheet with the CSV format.
  78 ⍝  SaveAsHtml             - Save to file the specify worksheet with the HTML format.
  79 ⍝  SaveAsPdf              - Save the Current WorkSheet As fileName in .Pdf format.
  80 ⍝  SaveAsStream           - Save the Current WorkBook As a Stream in .Xlsx format.
  81 ⍝  SaveAsXls              - Save the Current WorkBook As fileName in .Xls format.
  82 ⍝  SaveAsXlsx             - Save the Current WorkBook As fileName in .Xlsx format.
  83 ⍝  SetActiveWorksheet     - Activate specific Worksheet in active workbook.
  84 ⍝  SetBackgroundColor     - Set a Range Font Background Color.
  85 ⍝  SetBorderAround        - Set the Border Around the specify range.
  86 ⍝  SetFontBold            - Set a Range Font in Bold.
  87 ⍝  SetFontColor           - Set a Range Font Color.
  88 ⍝  SetFontItalic          - Set a Range Font in Italic.
  89 ⍝  SetFontName            - Set a Range Font Name.
  90 ⍝  SetFontSize            - Set a Range Font Size in Points.
  91 ⍝  SetFormat              - Set a Range Format.
  92 ⍝  SetHAlignment          - Set Horizontal Alignment of Range.
  93 ⍝  SetNumber              - Set data of Active WorkSheet. The data must be numeric.
  94 ⍝  SetNumber2             - Same as SetNumber but using a DataTable for large array.
  95 ⍝  SetText                - Set data of Active WorkSheet. The data must be Text only.
  96 ⍝  SetText2               - Same as SetText but using a DataTable for large array.
  97 ⍝  SetVAlignment          - Set Vertical Alignment of Range.
  98 ⍝  SetValue               - Set data of Active WorkSheet.
  99 ⍝  SetWorksheetName       - Set the WorkSheet Name.
 100 ⍝  Show                   - Show the workbook in a window.
 101 ⍝  ShowExcelFile          - To View only an Excel file.
 102 ⍝  TsToOADate             - OA Date from ⎕TS.
 103 ⍝  UsedRange              - Get the Range Used by the Active Worksheet.
 104 ⍝  UsedRangeDimension     - Get the Dimension of the Used Range Used by the Active Worksheet.
 105 ⍝  WrapText               - Set if Text in Range is Wrapped.
 106 
 107 ⍝ Version 1.0 November 2014, Pierre Gilbert
 108 ⍝ Version 1.1 November 2014, Typo corrections suggested by Daniel Baronet
 109 ⍝ Version 1.2 November 2014, Typo corrections suggested by Daniel Baronet
 110 ⍝ Version 1.3 May 2015
 111 ⍝   Methods Improved: GetNumber, GetText, GetValue, GetDisplayText
 112 ⍝   Methods Added:    SaveAsCSV, SaveAsStream, LoadFromStream, AddAfterLastRow
 113 ⍝                     AddAfterLastColumn, ExportDataSet
 114 ⍝   Methods Modified: ExportDataTable, ImportDataTable
 115 
 116 ⍝ Version 1.4 May 2015
 117 ⍝   Methods Improved: GetNumber, GetText, ParseRange
 118 
 119 ⍝ Version 1.5 May 2015
 120 ⍝   Method ExportDataSet corrected for empty worksheet
 121 
 122 ⍝ Version 1.6 June 2015
 123 ⍝   Methods Improved: SetNumber, SetText, SetValue, AplToDT
 124 ⍝   Methods Added:    SetNumber2, SetText2, GetNumber2, GetText2 for large array
 125 ⍝   Methods Modified: DTtoApl returns numeric 0 on empty cells
 126 ⍝                     All the SetXXX methods accept now the upper left corner position of the array
 127 ⍝                     like:  1 1 xl.SetNumber 5 4⍴⍳20
 128 ⍝   Bug corrected in: SetWorksheetName, DeleteWorksheet, SaveAsCSV, SaveAsHtml, SetActiveWorksheet
 129 
 130 ⍝   ⎕USING is now Global instead of Local for most of the Methods
 131 
 132 ⍝ Version 1.7 September 2015
 133 ⍝   Additional comments added on methods: ExportDataTable and ExportDataSet
 134 
 135 ⍝ Version 1.8 October 2015
 136 ⍝   Bug corrected in ParseRange when using RC notation on single value
 137 
 138 ⍝ Version 1.9 August 2017
 139 ⍝   Bug corrected in RangeDimension: did not reported the correct dimensions on empty range (thanks to Michael Baas)
 140 ⍝   Bug corrected in GetNumber: will return a number on a cell with a formula (thanks to Michael Baas)
 141 
 142 ⍝ Version 2.0 August 2017
 143 ⍝   Bug corrected in GetText: will return a text on a cell with a formula (thanks to Michael Baas)
 144 
 145     (⎕IO ⎕ML ⎕WX)←1 3 3
 146 
 147     sfDir←'Syncfusion/4.5/'                 ⍝ Location of the Syncfusion assemblies
 148     ⎕USING←'System' 'System.IO' 'System.Data,System.Data.dll' 'System.Drawing,System.Drawing.dll'
 149     ⎕USING,←⊂'Syncfusion.XlsIO,',sfDir,'Syncfusion.XlsIO.Base.dll'
 150 
 151     :Field Public XL                        ⍝ Syncfusion.XlsIO.ExcelEngine to experiment with other methods
 152 
 153     :Field Public Win                       ⍝ Windows .Net object
 154 
 155       isString←{0 2∊⍨10|⎕DR ⍵               ⍝ Test to detect characters from numbers
 156       }
 157 
 158       rangeRect←{                           ⍝ Get position and size of range
 159           ⍵.IsBlank:0 0 0 0
 160           1+∊⍵.GetRectangles.(Y X Height Width)}
 161 
 162 
 163     ∇ Init0;sink
 164       :Access Public
 165       :Implements Constructor
 166      
 167      ⍝ Initialize a Syncfusion ExcelEngine object and creates a Workbook
 168      ⍝  with the default amount of Worksheets (typically 3).
 169       :Trap 0
 170           XL←⎕NEW ExcelEngine
 171           sink←XL.Excel.Workbooks.Create ⍬
 172           InitOptions
 173       :End
 174 
 175 
 176     ∇ Init noOfWorksheets;sink
 177       :Access Public
 178       :Implements Constructor
 179      
 180      ⍝ Initialize a Syncfusion ExcelEngine object and creates a Workbook
 181      ⍝ with the the specify number of Worksheets.
 182       :Trap 0
 183           XL←⎕NEW ExcelEngine
 184           sink←XL.Excel.Workbooks.Create noOfWorksheets
 185           InitOptions
 186       :End
 187 
 188 
 189     ∇ InitOptions
 190      ⍝ Continue the Initialization with the following options:
 191      
 192      ⍝ When using the Value2 property, set to 0 if you are sure that the given
 193      ⍝ value is not of DateTime data type which improves time performance (default is 1).
 194       XL.Excel.ActiveWorkbook.DetectDateTimeInValue←0
 195      
 196      ⍝ Indicates if all values in the workbook are preserved as strings.(default is 0)
 197      ⍝ XL.Excel.(⌷Worksheets).IsStringsPreserved←1
 198      
 199      ⍝ MS Excel supports 16,384 columns by 1,048,576 rows in Excel 2007 and above formats (*.xlsx),
 200      ⍝ and 256 columns by 65,536 rows in Excel97to2003 format (*.xls). XlsIO allows the same limit
 201      ⍝ in its respective formats. By default, the Excel version is Excel97to2003 (*.xls) in XlsIO.
 202      ⍝ So, you have to set the ExcelVersion property of IWorkbook to Excel2007 or above to use entire 1,048,576 rows.
 203 ⍝     XL.Excel.ActiveWorkbook.Version←XL.Excel.ActiveWorkbook.Version.Excel97to2003  ⍝ ← This version for 65,536 rows maximum
 204       XL.Excel.ActiveWorkbook.Version←XL.Excel.ActiveWorkbook.Version.Excel2007      ⍝ ← This version for 1,048,576 rows maximum
 205 
 206 
 207     ∇ AddAfterLastColumn array
 208       :Access Public
 209     ⍝ Add array after the last column
 210      
 211       (LastColumn+1)SetValue array
 212 
 213 
 214     ∇ AddAfterLastRow array
 215       :Access Public
 216    ⍝ Add array after the last row
 217      
 218       (-LastRow+1)SetValue array
 219 
 220 
 221     ∇ AddWorksheet sheetName;sink
 222       :Access Public
 223     ⍝ Add a new Worksheet.
 224     ⍝ sheetName = Name of the new sheet
 225      
 226       sink←XL.Excel.ActiveWorkbook.Worksheets.Create(⊂,sheetName)
 227 
 228 
 229     ∇ dt←{colNames}AplToDT aplArray;colType;index;IsChar;IsNum;tableName
 230       :Access Public
 231      ⍝ Create a DataTable from an Apl Array.
 232      ⍝ EACH COLUMN MUST BE OF THE SAME TYPE.
 233      ⍝ For dates, convert ⎕TS to an OADate before making the DataTable.
 234      ⍝ apl      = An APL array of Numbers and Characters.
 235      ⍝ colNames = Column names for the DataTable. Works best with 2 characters per name.
 236      ⍝ dt       = Resulting DataTable
 237      
 238      ⍝ If a Vector, set as a one row matrix:
 239       :If 1=⍴⍴aplArray
 240           aplArray←(1,⍴aplArray)⍴aplArray
 241       :EndIf
 242      
 243      ⍝ Check if aplArray is a 2 dimensional array:
 244       :If 2≠⍴⍴aplArray
 245           ⎕←'AplToDT Error: Argument must be of rank equal or smaller than 2'
 246           →0
 247       :End
 248      
 249      ⍝ Check if columnNames is properly formed:
 250       :If 0=⎕NC'colNames'            ⍝ There is no columnNames
 251       :OrIf (⍴colNames)≠1↓⍴aplArray  ⍝ Wrong Shape
 252       :OrIf 1∊0=1↑¨0⍴¨colNames       ⍝ Not characters
 253       :OrIf 0∊≡¨colNames             ⍝ Wrong Depth
 254      
 255         ⍝ 'colNames' is not supplied or invalid:
 256         ⍝ Generate the Column Names as 'C1' 'C2', etc.:
 257           colNames←'C',¨⍕¨⍳1↓⍴aplArray
 258       :End
 259      
 260       tableName←'Data'  ⍝ Default TableName
 261       IsChar←{' '=↑1↑0⍴⍵}
 262       IsNum←{0=↑1↑0⍴⍵}
 263      
 264     ⍝ Default value in case of error:
 265       dt←⎕NEW DataTable(⊂tableName)
 266      
 267       :Trap 0
 268          ⍝ Determine the Type of each column:
 269           colType←''
 270           :For index :In ⍳2⌷⍴aplArray
 271               :If ∧/IsNum¨aplArray[;index]
 272                 ⍝ Default Type for numbers
 273                   colType,←Double
 274      
 275               :ElseIf ∧/IsChar¨aplArray[;index]
 276                 ⍝ Default Type for characters
 277                   colType,←String
 278      
 279               :Else
 280                 ⍝ Mixed Type in the same column
 281                   ⎕←'AplToDT: Don''t know what to do with column no: ',⍕index
 282                   aplArray[;index]←⍕¨aplArray[;index]
 283                   colType,←String
 284      
 285               :EndIf
 286           :EndFor
 287      
 288          ⍝ Set the Column's Types and Names of the DataTable:
 289           {}colNames{dt.Columns.Add ⍺ ⍵}¨colType
 290      
 291          ⍝ Fill the DataTable:
 292           2010⌶dt aplArray
 293      
 294       :EndTrap
 295 
 296 
 297     ∇ AutoFitColumns range
 298       :Access Public
 299     ⍝ Adjust Width of Columns to the Widest Value.
 300     ⍝ Does not work well with Wrapped Text.
 301      
 302       (ParseRange range).AutofitColumns
 303 
 304 
 305     ∇ AutoFitRows range
 306       :Access Public
 307     ⍝ Adjust Height of Rows to the Highest Value.
 308     ⍝ Does not work well with Wrapped Text.
 309      
 310       (ParseRange range).AutofitRows
 311 
 312 
 313     ∇ r←ConvertA1toRC range;height;width;x;y
 314       :Access Public
 315     ⍝ Convert from Excel A1 notation to Row and Column Index notation (RC) (base 1).
 316     ⍝ 'B5'     → 5 2
 317     ⍝ 'D2:E10' → 2 4 10 5
 318      
 319       (y x height width)←∊XL.Excel.ActiveWorkbook.ActiveSheet.Range[⊂,range].GetRectangles.(Y X Height Width)
 320      
 321       :If 0 0≡height width
 322         ⍝ Single cell
 323           r←1+y,x
 324       :Else
 325         ⍝ Range
 326           r←1+y,x,(height+y),(width+x)
 327       :End
 328 
 329 
 330     ∇ r←ConvertRCtoA1 range;col;lastCol;lastRow;row
 331       :Access Public
 332     ⍝ Convert from Row and Column Index notation to Excel A1 notation
 333     ⍝ 5 2      → 'B5'
 334     ⍝ 2 4 10 5 → 'D2:E10'
 335      
 336       :If 2=⍴range  ⍝ Single cell
 337           (row col)←range
 338           r←XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col].AddressLocal
 339      
 340       :ElseIf 4=⍴range  ⍝ Range
 341           (row col lastRow lastCol)←range
 342           r←XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col;lastRow;lastCol].AddressLocal
 343       :End
 344 
 345 
 346     ∇ DeleteWorksheet sheet;item
 347       :Access Public
 348     ⍝ Delete a Worksheet from Active Workbook.
 349     ⍝ sheet = SheetName or Index (base 1) of the Worksheet
 350      
 351       :Select isString sheet
 352       :Case 1 ⍝ String
 353           :If (⊂,sheet)∊XL.Excel.ActiveWorkbook.(⌷Worksheets).Name
 354               XL.Excel.ActiveWorkbook.Worksheets[⊂,sheet].Remove
 355           :Else
 356               ⎕←'sfExcel.DeleteWorksheet Error: Worksheet Name ',sheet,' does not exist'
 357           :End
 358       :CaseList 0 ⍝ Numeric
 359           :If sheet≤XL.Excel.ActiveWorkbook.Worksheets.Count
 360               XL.Excel.ActiveWorkbook.Worksheets[sheet-1].Remove
 361           :Else
 362               ⎕←'sfExcel.DeleteWorksheet Error: Worksheet index ',sheet,' does not exist'
 363           :End
 364       :EndSelect
 365 
 366 
 367     ∇ Dispose
 368       :Access Public
 369     ⍝ Quit Excel and Dispose of the "XL" object.
 370      
 371       :Trap 0
 372           XL.Excel.Workbooks.Close
 373           XL.Dispose
 374           XL←⎕NULL
 375           ⎕EX'XL'
 376       :EndTrap
 377 
 378 
 379     ∇ apl←DTtoApl dt
 380       :Access Public
 381     ⍝ Convert a .Net DataTable to APL
 382      
 383       :If 9≠⎕NC'dt'
 384       :OrIf 'System.Data.DataTable'≢dt.GetType.ToString
 385           ⎕←'sfExcel.DTtoApl Error: The argument is not a DataTable Object !'
 386       :EndIf
 387      
 388       apl←2011⌶dt(dt.Columns.Count⍴0)  ⍝ ←Empty Cells will be returned as numeric 0
 389 ⍝     apl←2011⌶dt                      ⍝ ←Empty Cells will be returned as System.DBNull
 390 
 391 
 392     ∇ ds←ExportDataSet options;dt;tableName;tableNames
 393       :Access Public
 394      ⍝ Export the whole Workbook as a DataSet
 395      ⍝ Each Worksheets becomes a DataTable
 396      
 397      ⍝ None                    0 No datatable exports flags.
 398      ⍝ ColumnNames             1 Represents the ColumnNames datatable export flag.
 399      ⍝ ComputedFormulaValues   2 Represents the ComputedFormulaValues datatable export flag.
 400      ⍝ DetectColumnTypes       4 Indicates that XlsIO should try to detect column types.
 401      ⍝ DefaultStyleColumnTypes 8 When DetectColumnTypes is set and this flag is set too,it means that default column style must be used to detect style,if this flag is not set,but DetectColumnTypes is set,then first cell in the column will be used to detect column type.
 402      ⍝ PreserveOleDate         16 Indicates whether to preserve Ole date(double numbers)instead of date-time values.
 403      
 404      ⍝ Examples:
 405      ⍝ Option 4:     Detect type from the first row. Column names will be the default ie. Column1, Column2, etc.
 406      ⍝ Option 4+8:   Detect type from Column Style. Column names will be the default ie. Column1, Column2, etc.
 407      ⍝ Option 1+4+8: Detect type from Column Style and Column names from first row.
 408      ⍝ Add 2 to the above examples to get the computed values of formula.
 409      
 410       ds←⎕NEW DataSet(⊂'DataSet')
 411      
 412       tableNames←GetWorksheetsNames
 413      
 414       :For tableName :In tableNames
 415      
 416           SetActiveWorksheet tableName
 417           :If 0 0 0 0≢UsedRange
 418               dt←options ExportDataTable UsedRange
 419               ds.Tables.Add(dt)
 420           :Else
 421               ⍝ Do nothing. Worksheet is empty.
 422           :EndIf
 423      
 424       :EndFor
 425 
 426 
 427     ∇ dt←{options}ExportDataTable range
 428       :Access Public
 429      ⍝ Export the spreadsheet data as a .Net data table.
 430      
 431      ⍝ None                    0 No datatable exports flags.
 432      ⍝ ColumnNames             1 Represents the ColumnNames datatable export flag.
 433      ⍝ ComputedFormulaValues   2 Represents the ComputedFormulaValues datatable export flag.
 434      ⍝ DetectColumnTypes       4 Indicates that XlsIO should try to detect column types.
 435      ⍝ DefaultStyleColumnTypes 8 When DetectColumnTypes is set and this flag is set too,it means that default column style must be used to detect style,if this flag is not set,but DetectColumnTypes is set,then first cell in the column will be used to detect column type.
 436      ⍝ PreserveOleDate         16 Indicates whether to preserve Ole date(double numbers)instead of date-time values.
 437      
 438      ⍝ Examples:
 439      ⍝ Option 4:     Detect type from the first row. Column names will be the default ie. Column1, Column2, etc.
 440      ⍝ Option 4+8:   Detect type from Column Style. Column names will be the default ie. Column1, Column2, etc.
 441      ⍝ Option 1+4+8: Detect type from Column Style and Column names from first row.
 442      ⍝ Add 2 to the above examples to get the computed values of formula.
 443      
 444       :If 0=⎕NC'options'
 445           options←2+4 ⍝ Default.
 446       :End
 447      
 448       range←ParseRange range
 449       dt←XL.Excel.ActiveWorkbook.ActiveSheet.ExportDataTable(range options)
 450 
 451 
 452     ∇ FreezeRows noRows
 453       :Access Public
 454     ⍝ Freeze Rows from the Top of WorkSheet.
 455     ⍝ noRows = number of rows to freeze from top (base 1)
 456      
 457       XL.Excel.ActiveWorkbook.ActiveSheet.Range[1+noRows;1].FreezePanes
 458 
 459 
 460     ∇ r←GetActiveWorksheetName
 461       :Access Public
 462     ⍝ Get the Active Sheet in Active Workbook.
 463     ⍝ r = active sheet name
 464      
 465       r←XL.Excel.ActiveWorkbook.ActiveSheet.Name
 466 
 467 
 468     ∇ array←GetDisplayText range
 469       :Access Public
 470     ⍝ Gets the text that is displayed in the cell. This is a read-only property, which returns
 471     ⍝ a cell value that is displayed after the number format application.
 472     ⍝ array = Array same Size as Range
 473      
 474       range←ParseRange range
 475      
 476 ⍝     array←(¯2↑rangeRect range)⍴range.Cells.DisplayText
 477      
 478 ⍝     ↓↓↓ This is faster than line above for large range.
 479       array←⊃{⍵.Cells.DisplayText}¨range.Rows
 480 
 481 
 482     ∇ array←GetNumber range;dim;valueConverter
 483       :Access Public
 484     ⍝ Get data of Active WorkSheet. The data must be only numeric.
 485     ⍝ array = Array same Size as Range (of Number only)
 486      
 487       range←ParseRange range
 488       dim←({1+∊⍵.GetRectangles.(Height Width)}range)
 489      
 490       valueConverter←{
 491           ⍵.HasNumber:⍵.Number
 492           ⍵.IsBlank:0                                    ⍝ Default value when the cell is empty
 493           ⍵.HasFormulaNumberValue:⍵.FormulaNumberValue   ⍝ Added to return a number when formula
 494           ⍵.HasFormulaStringValue:0                      ⍝ Added to return a number when formula
 495           ⍵.Value2
 496       }
 497      
 498 ⍝     ↓↓↓ This line is working but too slow
 499 ⍝     array ← dim ⍴ ∊range.Cells.Number
 500      
 501 ⍝     ↓↓↓ This is faster than previous line and will not freeze the interpreter
 502       :If dim[1]≥dim[2]
 503         ⍝ More rows than columns. Resolve column wise.
 504 ⍝         array←⍉⊃{⍵.Cells.Number}¨range.Columns  ⍝ This is working but will bug on empty cell
 505           array←⍉⊃{valueConverter¨⍵.Cells}¨range.Columns
 506       :Else
 507         ⍝ More columns than rows. Resolve row wise.
 508 ⍝         array←⊃{⍵.Cells.Number}¨range.Rows      ⍝ This is working but will bug on empty cell
 509           array←⊃{valueConverter¨⍵.Cells}¨range.Rows
 510       :End
 511 
 512 
 513     ∇ array←GetNumber2 range;dt
 514       :Access Public
 515     ⍝ Get data of Active WorkSheet via a DataTable. The data must be only numeric.
 516     ⍝ array = Very Large Array of Number only Same Size as Range.
 517     ⍝ Empty cells are replaced by numeric 0 in DTtoApl
 518      
 519       dt←ExportDataTable range
 520       array←DTtoApl dt
 521 
 522 
 523     ∇ array←GetText range;col;dim;lastCol;lastRow;row;valueConverter
 524       :Access Public
 525     ⍝ Get data of Active WorkSheet. The data must be only characters.
 526     ⍝ array = Array same Size as Range (of Text only)
 527      
 528       range←ParseRange range
 529       dim←({1+∊⍵.GetRectangles.(Height Width)}range)
 530      
 531       valueConverter←{
 532           ⍵.HasString:⍵.Text
 533           ⍵.IsBlank:''                                   ⍝ Default value when the cell is empty
 534           ⍵.HasFormulaStringValue:⍵.FormulaString.Value  ⍝ Added to return text when formula
 535           ⍵.HasFormulaNumberValue:⍕⍵.FormulaValue        ⍝ Added to return text when formula
 536           ⍕⍵.Value2                                      ⍝ Added ⍕ to return text all the time 
 537       }
 538      
 539 ⍝     ↓↓↓ This line is working but too slow
 540 ⍝     array←dim⍴∊range.Cells.Text
 541      
 542 ⍝     ↓↓↓ This is faster than previous line and will not freeze the interpreter
 543       :If dim[1]≥dim[2]
 544         ⍝ More rows than columns. Resolve column wise.
 545 ⍝         array←⍉⊃{⍵.Cells.Text}¨range.Columns  ⍝ This is working but will bug on empty cell
 546           array←⍉⊃{valueConverter¨⍵.Cells}¨range.Columns
 547       :Else
 548         ⍝ More columns than rows. Resolve row wise.
 549 ⍝         array←⊃{⍵.Cells.Text}¨range.Rows      ⍝ This is working but will bug on empty cell
 550           array←⍉⊃{valueConverter¨⍵.Cells}¨range.Columns
 551       :End
 552 
 553 
 554     ∇ array←GetText2 range;dt
 555       :Access Public
 556     ⍝ Get data of Active WorkSheet via a DataTable. The data must be only character.
 557     ⍝ array = Very Large Array of Characters only Same Size as Range.
 558     ⍝ Empty cells are replaced by numeric 0 in DTtoApl
 559      
 560       dt←ExportDataTable range
 561       array←DTtoApl dt
 562 
 563 
 564     ∇ array←GetValue range;dim;valueConverter
 565       :Access Public
 566     ⍝ Get data of Active WorkSheet. The data can be numeric or text.
 567     ⍝ array = Array same Size as Range (Text or Number)
 568      
 569       valueConverter←{
 570           ⍵.HasNumber:⍵.Number
 571           ⍵.HasString:⍵.Text
 572           ⍵.HasFormulaNumberValue:⍵.FormulaNumberValue
 573           ⍵.HasFormulaStringValue:⍵.FormulaStringValue
 574           ⍵.IsBlank:⎕NULL              ⍝ You can use ⎕NULL, 0 or ⊂'' as returned value when cell is blank
 575           ⍵.HasDateTime:⍵.Number
 576           ⍵.HasBoolean:⍵.Number
 577           ⍵.HasRichText:⍵.RichText
 578           ⍵.Value2
 579       }
 580      
 581       range←ParseRange range
 582       dim←({1+∊⍵.GetRectangles.(Height Width)}range)
 583      
 584 ⍝     ↓↓↓ Syncfusion .Value2 is valid but does not work like Excel .Value2
 585 ⍝     array←(¯2↑rangeRect range)⍴range.Cells.Value2
 586      
 587 ⍝     ↓↓↓ This is valid, but will freeze the interpreter while executing
 588 ⍝     array ← dim ⍴ valueConverter¨range.Cells
 589      
 590 ⍝     ↓↓↓ This is faster than previous line and will not freeze the interpreter
 591       :If dim[1]≥dim[2]
 592         ⍝ More rows than columns. Resolve column wise.
 593           array←⍉⊃{valueConverter¨⍵.Cells}¨range.Columns
 594       :Else
 595         ⍝ More columns than rows. Resolve row wise.
 596           array←⊃{valueConverter¨⍵.Cells}¨range.Rows
 597       :End
 598      
 599 ⍝     Somehow 'range.Rows.Cells.HasNumber' is faster than 'range.Cells.HasNumber'
 600 
 601 
 602     ∇ r←GetWorksheetsNames
 603       :Access Public
 604     ⍝ Get All the Worksheets Names.
 605     ⍝ r = Worksheets Names
 606      
 607       r←XL.Excel.ActiveWorkbook.(⌷Worksheets).Name
 608 
 609 
 610     ∇ range ImportDataTable dt;col;keepHeader;preserveType;row
 611       :Access Public
 612     ⍝ Import a DataTable at [row;col] position in the Active Worksheet.
 613     ⍝ row col      = Row and Column (base 1) of the upper left corner of the DataTable
 614     ⍝ keepHeader   = The first row will be the columns names of the DataTable
 615     ⍝ preserveType = Preserve the Type of the DataTable
 616      
 617 ⍝     (row col)←range
 618      
 619     ⍝ ↓↓↓ Added in v1.3
 620       (row col keepHeader preserveType)←4↑range,0 1
 621      
 622       {}XL.Excel.ActiveWorkbook.ActiveSheet.ImportDataTable dt keepHeader row col preserveType  ⍝ DataTable, KeepHeader, Row, Col, PreserveType
 623 
 624 
 625     ∇ r←LastColumn
 626       :Access Public
 627     ⍝ Get the Last Column of a Worksheet.
 628     ⍝ r = last column (base 1)
 629      
 630       r←XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastColumn
 631 
 632 
 633     ∇ r←LastRow
 634       :Access Public
 635     ⍝ Get the Last Row of a Worksheet.
 636     ⍝ r = last row (base 1)
 637      
 638       r←XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastRow
 639 
 640 
 641     ∇ LoadFile fileName;sink
 642       :Access Public
 643     ⍝ Load an Excel Workbook file.
 644     ⍝ fileName = filename with full path and extension
 645      
 646       sink←XL.Excel.Workbooks.Open((⊂,fileName),ExcelOpenType.Automatic)
 647 
 648 
 649     ∇ LoadFromStream stream;MS;sink
 650       :Access Public
 651     ⍝ Load an Excel Workbook from a stream obtained by the method 'SaveAsStream'
 652      
 653       MS←⎕NEW MemoryStream(⊂⎕UCS stream)
 654       MS.Position←Convert.ToInt64 0
 655       sink←XL.Excel.Workbooks.Open(MS,ExcelOpenType.Automatic)
 656 
 657 
 658     ∇ Merge range
 659       :Access Public
 660     ⍝ Merge Text in Range.
 661      
 662       (ParseRange range).Merge
 663 
 664 
 665     ∇ ts←OADateToTs oaDate;date
 666       :Access Public
 667     ⍝ Convert OA Date to ⎕TS
 668     ⍝ oaDate = .Net OADate
 669     ⍝ ts = ⎕TS
 670     ⍝ Works with TsToOADate
 671      
 672       date←DateTime.FromOADate oaDate
 673       ts←date.(Year Month Day Hour Minute Second Millisecond)
 674 
 675 
 676     ∇ r←{array}ParseRange range;col;lastCol;lastRow;row
 677       :Access Public
 678     ⍝ Subroutine used to parse a range
 679     ⍝ range = Range in A1 notation (ex.: 'D5:F8' or 'B2')
 680     ⍝ range = Range with Row and Column Index (ex.: 'D5:F8' is 5 4 8 6)
 681     ⍝ range = Range as single positive number is the Column index base 1
 682     ⍝ range = Range as single negative number is the Row index base 1
 683     ⍝ array = optional, used internally.
 684      
 685       :If 0=isString range  ⍝ Is range a number ?
 686         ⍝ range is a number
 687           :If 1=⍴,range
 688               :If range>0
 689                 ⍝ Positive Number = Single Column as number.
 690                   :If range≤XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastColumn
 691                      ⍝ Pick an existing column.
 692 ⍝                     r←XL.Excel.ActiveWorkbook.ActiveSheet.Columns[range]   ⍝ Too Slow
 693                       lastRow←XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastRow
 694                       r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[1;range;lastRow;range]
 695                   :Else
 696                      ⍝ Define a new range outside the UsedRange.
 697                       row←1 ⋄ col←range
 698                       :If 0≠⎕NC'array'
 699                        ⍝ 'array' exist.
 700                           :If 2=↑⍴⍴array
 701                               lastRow←row+¯1+1⌷⍴array
 702                               lastCol←col+¯1+2⌷⍴array
 703                           :Else
 704                               lastRow←row+¯1+⍴,array
 705                               lastCol←col
 706                           :End
 707                       :Else
 708                         ⍝ 'array' does not exist (GetXXX) and outside of 'UsedRange'
 709                           lastRow←1⌈XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastRow
 710                           lastCol←col
 711                       :End
 712      
 713                       r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col;lastRow;lastCol]
 714                   :End
 715      
 716               :Else
 717                 ⍝ Negative Number = Single Row as number.
 718                   :If (|range)≤XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastRow
 719                     ⍝ Pick an existing row.
 720 ⍝                     r←XL.Excel.ActiveWorkbook.ActiveSheet.Rows[|range]  ⍝ Too Slow on large Worksheet
 721                       lastCol←XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastColumn
 722                       r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[|range;1;|range;lastCol]
 723                   :Else
 724                     ⍝ Define a new range.
 725                       row←|range ⋄ col←1
 726                       :If 0≠⎕NC'array'
 727                         ⍝ 'array' exist.
 728                           :If 2=↑⍴⍴array
 729                               lastRow←row+¯1+1⌷⍴array
 730                               lastCol←col+¯1+2⌷⍴array
 731                           :Else
 732                               lastRow←row
 733                               lastCol←col+¯1+⍴,array
 734                           :End
 735                       :Else
 736                         ⍝ 'array' does not exist (GetXXX) and outside of 'UsedRange'
 737                           lastRow←row
 738                           lastCol←1⌈XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange.LastColumn
 739                       :End
 740      
 741                       r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col;lastRow;lastCol]
 742                   :End
 743               :End
 744      
 745           :ElseIf 2=⍴range ⍝ RC notation: Single cell or Upper Left Corner of Array
 746               :If 0≠⎕NC'array'
 747                 ⍝ 'array' exist.
 748                   :If 1=⍴,array
 749                     ⍝ Single cell
 750                       (row col)←range
 751                       r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col]
 752      
 753                   :Else
 754                       (row col)←range
 755                       :If 2=↑⍴⍴array
 756                         ⍝ Two dimensional array
 757                           lastRow←row+¯1+1⌷⍴array
 758                           lastCol←col+¯1+2⌷⍴array
 759                       :Else
 760                         ⍝ Single row array
 761                           lastRow←row
 762                           lastCol←col+¯1+⍴,array
 763                       :End
 764      
 765                       r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col;lastRow;lastCol]
 766                   :End
 767      
 768      
 769               :Else
 770                ⍝ 'array' does not exist.
 771                   (row col)←range
 772                   r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col]
 773      
 774               :EndIf
 775      
 776           :ElseIf 4=⍴range  ⍝ RC notation: Range
 777               (row col lastRow lastCol)←range
 778               r←⍬⍴XL.Excel.ActiveWorkbook.ActiveSheet.Range[row;col;lastRow;lastCol]
 779           :EndIf
 780      
 781       :Else  ⍝ range is Text
 782         ⍝ A1 notation: range or single cell
 783      
 784           :If 0≠⎕NC'array'
 785               range←ConvertA1toRC range
 786               r←array ParseRange range
 787      
 788           :Else
 789               r←XL.Excel.ActiveWorkbook.ActiveSheet.Range[⊂,range]
 790      
 791           :End
 792       :End
 793 
 794 
 795     ∇ PrepareWindow;xaml;⎕USING
 796       :Access Private
 797      ⍝ Generic Window to display a SpreadsheetControl.
 798      
 799       xaml←'<sf:RibbonWindow'
 800       xaml,←'   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"'
 801       xaml,←'   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"'
 802       xaml,←'   xmlns:sf="http://schemas.syncfusion.com/wpf"'
 803       xaml,←'   Title="SpreadSheet Viewer"'
 804       xaml,←'   x:Name="window"'
 805       xaml,←'   sf:SkinStorage.VisualStyle="Office2010Blue"'
 806       xaml,←'   Width="800" Height="600">'
 807      
 808       xaml,←'   <Grid x:Name="LayoutRoot" >'
 809       xaml,←'       <Grid.RowDefinitions>'
 810       xaml,←'           <RowDefinition Height="Auto"/>'
 811       xaml,←'           <RowDefinition Height="*"/>'
 812       xaml,←'       </Grid.RowDefinitions>'
 813       xaml,←'   <sf:SpreadsheetRibbon x:Name="ribbon" DataContext="{Binding ElementName=spreadsheet}" sf:SkinStorage.VisualStyle="Office2010Blue"/>'
 814       xaml,←'   <sf:SpreadsheetControl x:Name="spreadsheet" FormulaBarVisibility="Visible" Grid.Row="1" sf:SkinStorage.VisualStyle="Office2010Blue"/>'
 815       xaml,←'   </Grid>'
 816       xaml,←'</sf:RibbonWindow>'
 817      
 818       ⎕USING←'Syncfusion.Windows.Tools.Controls,',sfDir,'Syncfusion.Tools.Wpf.dll'
 819       ⎕USING,←⊂'Syncfusion.Windows.Controls.Spreadsheet,',sfDir,'Syncfusion.Spreadsheet.Wpf.dll'
 820       ⎕USING,←⊂'Syncfusion.Windows.Shared,',sfDir,'Syncfusion.Shared.Wpf.dll'
 821      
 822       {}RibbonWindow SpreadsheetRibbon SpreadsheetControl SkinStorage
 823      
 824       ⎕USING,←⊂'System.Windows.Markup,WPF/PresentationFramework.dll'
 825       Win←XamlReader.Parse(⊂xaml)
 826      
 827       Win.ribbon←Win.FindName(⊂'ribbon')
 828       Win.spreadsheet←Win.FindName(⊂'spreadsheet')
 829       Win.window←Win.FindName(⊂'window')
 830 
 831 
 832     ∇ Print sheet;GC;gridModel;SV;Win;⎕USING
 833       :Access Public
 834      ⍝ Print the worksheet selected by the sheetIndex
 835      ⍝ sheet = SheetName or Index (base 1) of the Worksheet
 836      
 837       :Select isString sheet
 838       :Case 1 ⍝ String
 839           :If (⊂sheet)∊XL.Excel.ActiveWorkbook.(⌷Worksheets).Name
 840               sheet←(XL.Excel.ActiveWorkbook.(⌷Worksheets).Name)⍳(⊂sheet)
 841           :Else
 842               ⎕←'sfExcel.Print Error: Worksheet Name ',sheet,' does not exist'
 843           :End
 844       :CaseList 0 ⍝ Numeric
 845           :If sheet≤XL.Excel.ActiveWorkbook.Worksheets.Count
 846               ⍝ Do nothing. sheet is a valid sheet number.
 847           :Else
 848               ⎕←'sfExcel.Print Error: Worksheet index ',sheet,' does not exist'
 849           :End
 850       :EndSelect
 851      
 852       ⎕USING←'Syncfusion.Windows.Controls.Grid.Converter,',sfDir,'Syncfusion.Spreadsheet.Wpf.dll'
 853       gridModel←sheet⊃ExcelGridModelImportExtensions.ImportFromExcel(XL.Excel.ActiveWorkbook)
 854      
 855       ⎕USING←'Syncfusion.Windows.Controls.Grid,',sfDir,'Syncfusion.Grid.WPF.dll'
 856       GC←⎕NEW GridControl
 857       {}GC.Model←gridModel
 858      
 859      ⍝ ↓↓↓ Uncomment if you want to have a window before printing.
 860 ⍝     ⎕USING←'System.Windows.Controls,WPF/PresentationFramework.dll'
 861 ⍝     SV←⎕NEW ScrollViewer
 862 ⍝     SV.CanContentScroll←1
 863 ⍝     SV.HorizontalScrollBarVisibility←SV.HorizontalScrollBarVisibility.Auto
 864 ⍝     SV.VerticalScrollBarVisibility←SV.VerticalScrollBarVisibility.Auto
 865 ⍝     SV.Content←GC
 866 
 867 ⍝     ⎕USING←'System.Windows,WPF/PresentationFramework.dll'
 868 ⍝     Win←⎕NEW Window
 869 ⍝     Win.Title←'Spreadsheet Viewer'
 870 ⍝     Win.Content←SV
 871 ⍝     Win.Show
 872      
 873       ⎕USING←'Syncfusion.Windows.Controls.Grid,',sfDir,'Syncfusion.Grid.WPF.dll'
 874       GridPrintExtensions.Print GC
 875 
 876 
 877     ∇ r←RangeDimension range
 878       :Access Public
 879     ⍝ Get the dimension of a range (no of rows, no of columns).
 880      
 881     ⍝ ↓↓↓ Working but is Slower for large range
 882     ⍝ r←∊⍴¨(ParseRange range).(Rows Columns)
 883      
 884     ⍝ ↓↓↓ Does not work on empty range because of the .IsBlank test in 'rangeRect'
 885     ⍝ r←¯2↑rangeRect(ParseRange range)
 886      
 887       r←{1+∊⍵.GetRectangles.(Height Width)}(ParseRange range)
 888 
 889 
 890     ∇ {sheet}SaveAsCSV fileName
 891       :Access Public
 892     ⍝ Save a Sheet As fileName in CSV format.
 893     ⍝ fileName = filename with full path and extension (.csv)
 894     ⍝ sheet    = Sheet name or index (base 1)
 895     ⍝ Note: If sheet absent willl use the active sheet.
 896      
 897       :If 0=⎕NC'sheet'
 898         ⍝ sheet is absent used the Active one
 899           sheet←XL.Excel.ActiveWorkbook.ActiveSheet
 900      
 901       :ElseIf isString sheet
 902         ⍝ sheet is characters, use as sheet name
 903           sheet←XL.Excel.ActiveWorkbook.Worksheets[⊂,sheet]
 904      
 905       :Else
 906         ⍝ sheet is number, use as index base 1
 907           sheet←XL.Excel.ActiveWorkbook.Worksheets[sheet-1]
 908       :End
 909      
 910 ⍝      XL.Excel.ActiveWorkbook.Version←XL.Excel.ActiveWorkbook.Version.Excel97to2003
 911 ⍝      XL.Excel.ActiveWorkbook.SaveAs(fileName(,','))
 912       sheet.SaveAs(fileName(,','))
 913 
 914 
 915 
 916     ∇ {sheet}SaveAsHtml fileName;options;⎕USING
 917       :Access Public
 918     ⍝ Save the Current WorkSheet As fileName in .Html format.
 919     ⍝ fileName = filename with full path and extension (.Html)
 920     ⍝ sheet = Sheet name or index (base 1)
 921     ⍝ Note: If sheet absent willl use the active sheet.
 922      
 923       :If 0=⎕NC'sheet'
 924         ⍝ sheet is absent used the Active one
 925           sheet←XL.Excel.ActiveWorkbook.ActiveSheet
 926      
 927       :ElseIf isString sheet
 928         ⍝ sheet is characters, use as sheet name
 929           sheet←XL.Excel.ActiveWorkbook.Worksheets[⊂,sheet]
 930      
 931       :Else
 932         ⍝ sheet is number, use as index base 1
 933           sheet←XL.Excel.ActiveWorkbook.Worksheets[sheet-1]
 934       :End
 935      
 936       ⎕USING←'Syncfusion.XlsIO.Implementation,',sfDir,'Syncfusion.XlsIO.Base.dll'
 937       options←⎕NEW HtmlSaveOptions
 938       options.TextMode←HtmlSaveOptions.GetText.DisplayText
 939       sheet.SaveAsHtml(fileName options)
 940 
 941 
 942     ∇ {sheet}SaveAsPdf fileName;converter;pdfDoc;settings;⎕USING
 943       :Access Public
 944     ⍝ Save the Current WorkSheet As fileName in .Pdf format.
 945     ⍝ fileName = filename with full path and extension (.pdf)
 946     ⍝ sheet = Sheet name or index (base 1)
 947     ⍝ Note: If sheet absent willl use the active sheet.
 948      
 949       :If 0=⎕NC'sheet'
 950         ⍝ sheet is absent used the Active one
 951           sheet←XL.Excel.ActiveWorkbook.ActiveSheet
 952      
 953       :ElseIf isString sheet
 954         ⍝ sheet is characters, use as sheet name
 955           sheet←XL.Excel.ActiveWorkbook.Worksheets[⊂,sheet]
 956      
 957       :Else
 958         ⍝ sheet is number, use as index base 1
 959           sheet←XL.Excel.ActiveWorkbook.Worksheets[sheet-1]
 960       :End
 961      
 962      ⍝ Set the PageSetup here if required:
 963      ⍝ sheet.PageSetup.PrintArea
 964      
 965       ⎕USING←'Syncfusion.ExcelToPdfConverter,',sfDir,'Syncfusion.ExcelToPDFConverter.Base.dll'
 966      
 967      ⍝ Open the Excel document you want to convert
 968       converter←⎕NEW ExcelToPdfConverter(sheet)
 969      
 970      ⍝ Initialize the ExcelToPdfconverterSettings
 971       settings←⎕NEW ExcelToPdfConverterSettings
 972      
 973      ⍝ Initialize the PDF document
 974       ⎕USING←'Syncfusion.Pdf,',sfDir,'Syncfusion.Pdf.Base.dll'
 975       pdfDoc←⎕NEW PdfDocument
 976      
 977      ⍝ Set the Layout Options for the output Pdf page.
 978      ⍝ settings.LayoutOptions←settings.LayoutOptions.FitSheetOnOnePage
 979      
 980      ⍝ Assign the PDF document to the TemplateDocument property of ExcelToPdfConverterSettings
 981       settings.TemplateDocument←pdfDoc
 982       settings.DisplayGridLines←settings.DisplayGridLines.Invisible
 983      
 984      ⍝ Convert the Excel document to PDF document
 985       pdfDoc←converter.Convert(settings)
 986      
 987      ⍝ Save the PDF file
 988       pdfDoc.Save(⊂fileName)
 989 
 990 
 991     ∇ SaveAsXls fileName
 992       :Access Public
 993     ⍝ Save the Current WorkBook As fileName in .Xls format.
 994     ⍝ fileName = filename with full path and extension (.xls)
 995     ⍝ Note: .SaveAsXls& write the file to disk and do not hold the interpreter on large file.
 996     ⍝ Note: The .Xls format seems to be faster to load than the .Xlsx format on large file
 997     ⍝       but is slower to Save than the .Xlsx format.
 998      
 999       XL.Excel.ActiveWorkbook.Version←XL.Excel.ActiveWorkbook.Version.Excel97to2003
1000       XL.Excel.ActiveWorkbook.SaveAs(⊂,fileName)
1001 
1002 
1003     ∇ SaveAsXlsx fileName
1004       :Access Public
1005     ⍝ Save the Current WorkBook As fileName in .Xlsx format
1006     ⍝ fileName = filename with full path and extension (.xlsx)
1007     ⍝ Note: .SaveAsXlsx& write the file to disk and do not hold the interpreter on large file.
1008     ⍝ Note: The .Xlsx format seems to be faster to Save than the .Xls format on large file
1009     ⍝       but is slower to Load than the .Xls format.
1010      
1011       XL.Excel.ActiveWorkbook.Version←XL.Excel.ActiveWorkbook.Version.Excel2007
1012       XL.Excel.ActiveWorkbook.SaveAs(⊂,fileName)
1013 
1014 
1015     ∇ stream←SaveAsStream;MS
1016       :Access Public
1017     ⍝ Save the Current WorkBook As a Stream in .Xlsx format
1018      
1019       MS←⎕NEW MemoryStream
1020      
1021       XL.Excel.ActiveWorkbook.Version←XL.Excel.ActiveWorkbook.Version.Excel2007
1022       XL.Excel.ActiveWorkbook.SaveAs(MS)
1023       stream←⎕UCS MS.ToArray
1024      
1025       MS.Close ⋄ MS.Dispose ⋄ MS←⎕NULL
1026 
1027 
1028     ∇ SetActiveWorksheet sheet
1029       :Access Public
1030     ⍝ Activate specific Worksheet in active workbook.
1031     ⍝ sheet = Index of Sheet (Base 1) or name of Sheet (Text)
1032      
1033       :Select isString sheet
1034       :Case 1 ⍝ String
1035           :If (⊂sheet)∊XL.Excel.ActiveWorkbook.(⌷Worksheets).Name
1036               XL.Excel.ActiveWorkbook.Worksheets[⊂,sheet].Activate
1037           :Else
1038               ⎕←'sfExcel.SetActiveWorksheet: Worksheet Name ',sheet,' does not exist'
1039           :End
1040       :CaseList 0 ⍝ Numeric
1041           :If sheet≤XL.Excel.ActiveWorkbook.Worksheets.Count
1042               XL.Excel.ActiveWorkbook.Worksheets[sheet-1].Activate
1043           :Else
1044               ⎕←'sfExcel.SetActiveWorksheet: Worksheet index ',sheet,' does not exist'
1045           :End
1046       :EndSelect
1047 
1048 
1049     ∇ range SetBackgroundColor color;paletteIndex
1050       :Access Public
1051     ⍝ Set a Range Font Background Color.
1052     ⍝ fontColor = The color of the font
1053     ⍝ xl.XL.Color.⎕nl -2  enumerates the list of possible color
1054      
1055     ⍝ ↓↓↓ Will work only with the exact color's name of the palette
1056     ⍝ paletteIndex←⍎'ExcelKnownColors.',fontColor
1057      
1058       :If isString color
1059           paletteIndex←XL.Excel.ActiveWorkbook.SetColorOrGetNearest Color.FromName(⊂,color)
1060           (ParseRange range).CellStyle.FillBackground←paletteIndex
1061      
1062       :Else
1063           paletteIndex←XL.Excel.ActiveWorkbook.SetColorOrGetNearest Color.FromArgb 255,3↑color
1064           (ParseRange range).CellStyle.FillBackground←paletteIndex
1065      
1066       :End
1067 
1068 
1069     ∇ range SetBorderAround lineStyle
1070       :Access Public
1071      ⍝ Set the Border Around the specify range
1072      ⍝ lineStyle = Dash_dot  Dash_dot_dot  Dashed  Dotted  Double  Hair  Medium  Medium_dash_dot
1073      ⍝             Medium_dash_dot_dot  Medium_dashed  None  Slanted_dash_dot Thick Thin
1074      ⍝ xl.XL.ExcelLineStyle.⎕nl -2  enumarates the list of possible LineStyle
1075      
1076       (ParseRange range).BorderAround(⍎'XL.ExcelLineStyle.',lineStyle)
1077 
1078 
1079     ∇ range SetFontBold bit
1080       :Access Public
1081     ⍝ Set a Range Font in Bold.
1082     ⍝ bit = 1 or 0
1083      
1084       (ParseRange range).CellStyle.Font.Bold←bit
1085 
1086 
1087     ∇ range SetFontColor fontColor;paletteIndex
1088       :Access Public
1089     ⍝ Set a Range Font Color.
1090     ⍝ fontColor = The color of the font
1091      
1092     ⍝ ↓↓↓ Will work only with the exact color's name of the palette
1093     ⍝ paletteIndex←⍎'ExcelKnownColors.',fontColor
1094      
1095       :If isString fontColor
1096           paletteIndex←XL.Excel.ActiveWorkbook.SetColorOrGetNearest Color.FromName⊂fontColor
1097           (ParseRange range).CellStyle.Font.Color←paletteIndex
1098      
1099       :Else
1100           paletteIndex←XL.Excel.ActiveWorkbook.SetColorOrGetNearest Color.FromArgb 255,3↑fontColor
1101           (ParseRange range).CellStyle.Font.Color←paletteIndex
1102      
1103       :End
1104 
1105 
1106     ∇ range SetFontItalic bit
1107       :Access Public
1108     ⍝ Set a Range Font in Italic.
1109     ⍝ bit = 1 or 0
1110      
1111       (ParseRange range).CellStyle.Font.Italic←bit
1112 
1113 
1114     ∇ range SetFontName fontName
1115       :Access Public
1116     ⍝ Set a Range Font Name.
1117     ⍝ fontName = name of the font
1118      
1119       (ParseRange range).CellStyle.Font.FontName←fontName
1120 
1121 
1122     ∇ range SetFontSize fontSize
1123       :Access Public
1124     ⍝ Set a Range Font Size in Points.
1125     ⍝ size = Size of Font in Points
1126      
1127       (ParseRange range).CellStyle.Font.Size←fontSize
1128 
1129 
1130     ∇ range SetFormat format
1131       :Access Public
1132     ⍝ Set a Range Format.
1133     ⍝ format = Format (ex.: 'yy/m/d h:mm', '0.00')
1134      
1135       (ParseRange range).NumberFormat←(⊂,format)
1136 
1137 
1138     ∇ range SetHAlignment alignment
1139       :Access Public
1140     ⍝ Set Horizontal Alignment of Range.
1141     ⍝ alignment = Alignment (Center, CenterAcrossSelection, Distributed, Fill,General, Justify, Left, Right)
1142      
1143       alignment←⍎'ExcelHAlign.HAlign',alignment
1144      
1145       (ParseRange range).HorizontalAlignment←alignment
1146 
1147 
1148     ∇ range SetNumber array;col;dim;lastCol;lastRow;row
1149       :Access Public
1150     ⍝ Set data of Active WorkSheet. The data must be numeric.
1151     ⍝ array = Array same Size as Range (Number only)
1152     ⍝ Usage: For small array. See also SetNumber2 for large array.
1153      
1154       range←array ParseRange range
1155       dim←({1+∊⍵.GetRectangles.(Height Width)}range)
1156      
1157 ⍝     (array ParseRange range).Cells.Number←,array
1158      
1159 ⍝     ↓↓↓ This is faster than previous line and will not freeze the interpreter
1160       :If dim[1]≥dim[2]
1161         ⍝ More rows than columns. Resolve column wise.
1162           (↓⍉array){⍵.Cells.Number←⍺}¨range.Columns
1163      
1164       :Else
1165         ⍝ More columns than rows. Resolve row wise.
1166           (↓array){⍵.Cells.Number←⍺}¨range.Rows
1167      
1168       :End
1169 
1170 
1171     ∇ range SetNumber2 array;col;colNames;dt;row
1172       :Access Public
1173     ⍝ Set data of Active WorkSheet via a DataTable. The data must be numeric.
1174     ⍝ array = Very Large Array of Number only.
1175      
1176       range←ParseRange range
1177       (row col)←range.(Row Column)
1178      
1179     ⍝ If a Vector, set as a one row matrix:
1180       :If 1=⍴⍴array
1181           array←(1,⍴array)⍴array
1182       :EndIf
1183      
1184     ⍝ Generate the Column Names as 'C1' 'C2', etc.:
1185       colNames←'C',¨⍕¨⍳2⌷⍴array
1186      
1187     ⍝ Get an empty DataTable
1188       dt←⎕NEW DataTable
1189      
1190     ⍝ Set the Column's Types and Names of the DataTable:
1191       {}colNames{dt.Columns.Add ⍺ ⍵}¨(2⌷⍴array)⍴Double
1192      
1193     ⍝ Fill the DataTable:
1194       2010⌶dt array
1195      
1196     ⍝ Import the DataTable to the Spreadsheet
1197       (row col)ImportDataTable dt
1198 
1199 
1200     ∇ range SetText array;col;dim;lastCol;lastRow;row
1201       :Access Public
1202     ⍝ Set data of Active WorkSheet. The data must be Text only.
1203     ⍝ array = Array must be the same Dimension as Range (Text only)
1204      
1205       range←array ParseRange range
1206       dim←({1+∊⍵.GetRectangles.(Height Width)}range)
1207      
1208 ⍝     (array ParseRange range).Cells.Text←,array
1209      
1210 ⍝     ↓↓↓ This is faster than previous line and will not freeze the interpreter
1211       :If dim[1]≥dim[2]
1212         ⍝ More rows than columns. Resolve column wise.
1213           (↓⍉array){⍵.Cells.Text←⍺}¨range.Columns
1214      
1215       :Else
1216         ⍝ More columns than rows. Resolve row wise.
1217           (↓array){⍵.Cells.Text←⍺}¨range.Rows
1218      
1219       :End
1220 
1221 
1222     ∇ range SetText2 array;col;colNames;dt;row
1223       :Access Public
1224     ⍝ Set data of Active WorkSheet via a DataTable. The data must be characters.
1225     ⍝ array = Very Large Array of Characters only.
1226      
1227       range←ParseRange range
1228       (row col)←range.(Row Column)
1229      
1230     ⍝ If a Vector, set as a one row matrix:
1231       :If 1=⍴⍴array
1232           array←(1,⍴array)⍴array
1233       :EndIf
1234      
1235     ⍝ Generate the Column Names as 'C1' 'C2', etc.:
1236       colNames←'C',¨⍕¨⍳2⌷⍴array
1237      
1238     ⍝ Get an empty DataTable
1239       dt←⎕NEW DataTable
1240      
1241     ⍝ Set the Column's Types and Names of the DataTable:
1242       {}colNames{dt.Columns.Add ⍺ ⍵}¨(2⌷⍴array)⍴String
1243      
1244     ⍝ Fill the DataTable:
1245       2010⌶dt array
1246      
1247     ⍝ Import the DataTable to the Spreadsheet
1248       (row col)ImportDataTable dt
1249 
1250 
1251     ∇ range SetVAlignment alignment
1252       :Access Public
1253     ⍝ Set Vertical Alignment of Range.
1254     ⍝ alignment = Alignment (Bottom, Center, Distributed, Justify, Top)
1255      
1256       alignment←⍎'ExcelVAlign.VAlign',alignment
1257      
1258       (ParseRange range).VerticalAlignment←alignment
1259 
1260 
1261     ∇ range SetValue array;col;dim;lastCol;lastRow;row
1262       :Access Public
1263     ⍝ Set data of Active WorkSheet.
1264     ⍝ array = Array same Size as Range (Text or Number)
1265      
1266       range←array ParseRange range
1267       dim←({1+∊⍵.GetRectangles.(Height Width)}range)
1268      
1269 ⍝     (array ParseRange range).Cells.Value2←,array
1270      
1271 ⍝     ↓↓↓ This is faster than previous line and will not freeze the interpreter
1272       :If dim[1]≥dim[2]
1273         ⍝ More rows than columns. Resolve column wise.
1274           (↓⍉array){⍵.Cells.Value2←⍺}¨range.Columns
1275      
1276       :Else
1277         ⍝ More columns than rows. Resolve row wise.
1278           (↓array){⍵.Cells.Value2←⍺}¨range.Rows
1279      
1280       :End
1281 
1282 
1283     ∇ index SetWorksheetName sheetName
1284       :Access Public
1285     ⍝ Set the WorkSheet Name.
1286     ⍝ index =     Index of Worksheet (Base 1)
1287     ⍝ sheetName = Name of Worksheet
1288      
1289       XL.Excel.ActiveWorkbook.Worksheets[index-1].Name←(⊂,sheetName)
1290 
1291 
1292     ∇ Show
1293       :Access Public
1294     ⍝ Show the workbook in a window.
1295     ⍝ The changes made in the spreadsheet are not pass into the workspace.
1296     ⍝ This is a one-way, one-time interaction.
1297     ⍝ The method can only be call one time (don't know why).
1298      
1299     ⍝ Generic window to display the SpreadsheetControl
1300       PrepareWindow
1301      
1302     ⍝ Import the current Workbook into the SpreadsheetControl
1303       {}Win.spreadsheet.ImportFromExcel(XL.Excel.ActiveWorkbook)
1304      
1305     ⍝ Show the Spreadsheet
1306       Win.Show
1307 
1308 
1309     ∇ ShowExcelFile fileName
1310       :Access Public
1311     ⍝ To View only an Excel file.
1312      
1313     ⍝ Generic window to display the SpreadsheetControl
1314       PrepareWindow
1315      
1316     ⍝ Import the current Workbook into the SpreadsheetControl
1317       {}Win.spreadsheet.ImportFromExcel(⊂,fileName)
1318      
1319     ⍝ Show the Spreadsheet
1320       Win.Show
1321 
1322 
1323     ∇ r←TsToOADate ts
1324       :Access Public
1325      ⍝ OA Date from ⎕TS.
1326      ⍝ ts = ⎕TS
1327      ⍝ r = .Net OADate
1328      ⍝ Note: Works with OADateToTs
1329      
1330       r←(⎕NEW DateTime ts).ToOADate
1331 
1332 
1333     ∇ r←UsedRange
1334       :Access Public
1335     ⍝ Get the Range Used by the Active Worksheet.
1336     ⍝ r = Range in RC notation (ex.: 'B1:B12' is 1 2 12 2)
1337     ⍝ r = 0 0 0 0 if Worksheet is empty
1338      
1339       r←rangeRect XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange
1340 
1341 
1342     ∇ r←UsedRangeDimension;range
1343       :Access Public
1344     ⍝ Get the Dimension of the Used Range Used by the Active Worksheet.
1345      
1346       r←¯2↑rangeRect XL.Excel.ActiveWorkbook.ActiveSheet.UsedRange
1347 
1348 
1349     ∇ range WrapText bit
1350       :Access Public
1351     ⍝ Set if Text in Range is Wrapped.
1352     ⍝ bit = 1 or 0
1353      
1354       (ParseRange range).WrapText←bit
1355 
1356 
1357 :EndClass

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] (2015-01-27 14:26:37, 89.7 KB) [[attachment:XLDemo.png]]
  • [get | view] (2015-01-27 14:26:37, 33.9 KB) [[attachment:sfExcel.v1.0.txt]]
  • [get | view] (2015-01-27 14:26:37, 33.9 KB) [[attachment:sfExcel.v1.1.txt]]
  • [get | view] (2015-01-27 14:26:37, 33.9 KB) [[attachment:sfExcel.v1.2.txt]]
  • [get | view] (2015-05-11 21:16:32, 42.4 KB) [[attachment:sfExcel.v1.3.txt]]
  • [get | view] (2015-05-13 14:47:49, 44.3 KB) [[attachment:sfExcel.v1.4.txt]]
  • [get | view] (2015-05-15 17:25:56, 44.5 KB) [[attachment:sfExcel.v1.5.txt]]
  • [get | view] (2015-06-14 13:15:56, 51.5 KB) [[attachment:sfExcel.v1.6.txt]]
  • [get | view] (2015-09-23 11:44:39, 52.4 KB) [[attachment:sfExcel.v1.7.txt]]
  • [get | view] (2015-10-09 17:26:08, 52.6 KB) [[attachment:sfExcel.v1.8.txt]]
  • [get | view] (2017-08-26 22:17:32, 53.3 KB) [[attachment:sfExcel.v1.9.txt]]
  • [get | view] (2017-08-31 19:18:45, 53.8 KB) [[attachment:sfExcel.v2.0.txt]]
  • [get | view] (2018-05-05 12:03:24, 56.0 KB) [[attachment:sfExcel.v2.1.txt]]
 All files | Selected Files: delete move to page

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