@@ -39,6 +39,13 @@ Namespace CompuMaster.Data
3939 Me .AssignRowData(rows, columnFormatting)
4040 End Sub
4141
42+ Public Sub New (headers As System.Collections.Generic.List( Of TextRow), rows As System.Collections.Generic.List( Of TextRow))
43+ If headers Is Nothing Then Throw New ArgumentNullException( NameOf (headers))
44+ If rows Is Nothing Then Throw New ArgumentNullException( NameOf (rows))
45+ Me .Headers = headers
46+ Me .Rows = rows
47+ End Sub
48+
4249 'Public Sub New(table As DataTable, columnFormatting As DataTables.DataColumnToString)
4350 ' Me.New(table, CType(Nothing, String), columnFormatting)
4451 'End Sub
@@ -156,17 +163,171 @@ Namespace CompuMaster.Data
156163 ' Rows.Add(New TextRow(Cells))
157164 'End Sub
158165
159-
160- Public Sub New (headers As System.Collections.Generic.List( Of TextRow), rows As System.Collections.Generic.List( Of TextRow))
161- If headers Is Nothing Then Throw New ArgumentNullException( NameOf (headers))
162- If rows Is Nothing Then Throw New ArgumentNullException( NameOf (rows))
163- Me .Headers = headers
164- Me .Rows = rows
165- End Sub
166-
166+ ''' <summary>
167+ ''' Captions of the table (can be multiple rows)
168+ ''' </summary>
169+ ''' <returns></returns>
167170 Public Property Headers As System.Collections.Generic.List( Of TextRow)
171+
172+ ''' <summary>
173+ ''' Rows of the table
174+ ''' </summary>
175+ ''' <returns></returns>
168176 Public Property Rows As System.Collections.Generic.List( Of TextRow)
169177
178+ ''' <summary>
179+ ''' Maximum number of columns in the table (including headers and rows)
180+ ''' </summary>
181+ ''' <returns></returns>
182+ Public Function ColumnCount() As Integer
183+ Dim MaxColumns As Integer = 0
184+ For MyCounter As Integer = 0 To Me .Headers.Count - 1
185+ MaxColumns = System.Math.Max(MaxColumns, Me .Headers(MyCounter).Cells.Count)
186+ Next
187+ For MyCounter As Integer = 0 To Me .Rows.Count - 1
188+ MaxColumns = System.Math.Max(MaxColumns, Me .Rows(MyCounter).Cells.Count)
189+ Next
190+ Return MaxColumns
191+ End Function
192+
193+ ''' <summary>
194+ ''' Convert TextTable to classic DataTable
195+ ''' </summary>
196+ ''' <returns></returns>
197+ Public Function ToDataTable() As DataTable
198+ 'Collect column names from all header rows (if multiple header rows exist, combine their texts with line breaks)
199+ Dim ColumnNames As New System.Collections.Generic.List( Of String )
200+ For RowCounter As Integer = 0 To Me .Headers.Count - 1
201+ For ColCounter As Integer = 0 To Me .Headers(RowCounter).Cells.Count - 1
202+ If ColumnNames.Count <= ColCounter Then
203+ 'Add new column
204+ ColumnNames.Add( Me .Headers(RowCounter).Cells(ColCounter).Text)
205+ Else
206+ 'Column already exists -> extend column name if required
207+ Dim ExistingColumnName As String = ColumnNames(ColCounter)
208+ If ExistingColumnName <> Nothing Then
209+ ColumnNames(ColCounter) = ExistingColumnName & System.Environment.NewLine & Me .Headers(RowCounter).Cells(ColCounter).Text
210+ Else
211+ ColumnNames(ColCounter) = Me .Headers(RowCounter).Cells(ColCounter).Text
212+ End If
213+ End If
214+ Next
215+ Next
216+
217+ 'Create DataTable with all columns
218+ Dim Result As New DataTable
219+ For ColCounter As Integer = 0 To ColumnNames.Count - 1
220+ Dim UniqueColumnName As String = DataTables.LookupUniqueColumnName(Result, ColumnNames(ColCounter))
221+ Result.Columns.Add(UniqueColumnName, GetType ( String ))
222+ Next
223+
224+ 'Add all rows
225+ For RowCounter As Integer = 0 To Me .Rows.Count - 1
226+ Dim NewRow As DataRow = Result.NewRow
227+ For ColCounter As Integer = 0 To Me .Rows(RowCounter).Count - 1
228+ If Me .Rows(RowCounter).Cells(ColCounter).Text <> Nothing Then
229+ NewRow(ColCounter) = Me .Rows(RowCounter).Cells(ColCounter).Text
230+ End If
231+ Next
232+ Result.Rows.Add(NewRow)
233+ Next
234+ Return Result
235+ End Function
236+
237+ Private Shared Function OutputOptions(rowNumbering As Boolean ) As CompuMaster.Data.ConvertToPlainTextTableOptions
238+ Dim Result = CompuMaster.Data.ConvertToPlainTextTableOptions.SimpleLayout
239+ Result.MinimumColumnWidth = 2
240+ Result.MaximumColumnWidth = 65535
241+ Result.RowNumbering = rowNumbering
242+ Return Result
243+ End Function
244+
245+ Public Function ToPlainTextTable() As String
246+ Return CompuMaster.Data.DataTables.ConvertToPlainTextTableFixedColumnWidths( Me .ToDataTable, OutputOptions( False ))
247+ End Function
248+
249+ Public Function ToPlainTextTable(rowNumbering As Boolean ) As String
250+ Return CompuMaster.Data.DataTables.ConvertToPlainTextTableFixedColumnWidths( Me .ToDataTable, OutputOptions(rowNumbering))
251+ End Function
252+
253+ ''' <summary>
254+ ''' Convert to plain text table with Excel-like column names (A, B, ..., Z, AA, AB, ..., AZ, BA, BB, ...) and row numbers (1-based)
255+ ''' </summary>
256+ ''' <returns></returns>
257+ Public Function ToPlainTextExcelTable() As String
258+ Return CompuMaster.Data.DataTables.ConvertToPlainTextTableFixedColumnWidths( Me .ToExcelStyleTextTable.ToDataTable, OutputOptions( False ))
259+ End Function
260+
261+ ''' <summary>
262+ ''' Convert to TextTable with Excel-like column names (A, B, ..., Z, AA, AB, ..., AZ, BA, BB, ...) and row numbers (1-based)
263+ ''' </summary>
264+ ''' <returns></returns>
265+ Public Function ToExcelStyleTextTable() As TextTable
266+ 'Prepare new header row with column letters
267+ Dim NewHeaderRows As New System.Collections.Generic.List( Of TextRow)
268+ With Nothing
269+ 'Setup column names in letters
270+ Dim NewHeaderCells As New TextRow
271+ Dim MaxColumns As Integer = Me .ColumnCount()
272+ For MyCounter As Integer = 0 To MaxColumns - 1
273+ NewHeaderCells.Cells.Add( New TextCell(ExcelColumnName(MyCounter)))
274+ Next
275+ NewHeaderRows.Add(NewHeaderCells)
276+ End With
277+
278+ 'Prepare new table data
279+ Dim NewDataRows As New System.Collections.Generic.List( Of TextRow)
280+ For RowCounter As Integer = 0 To Me .Headers.Count - 1 'Add all existing header rows as regular data rows
281+ NewDataRows.Add( Me .Headers(RowCounter).Clone)
282+ Next
283+ For RowCounter As Integer = 0 To Me .Rows.Count - 1 'Add all existing data rows
284+ NewDataRows.Add( Me .Rows(RowCounter).Clone)
285+ Next
286+
287+ 'Create new table
288+ Dim Result As TextTable = New TextTable()
289+ Result.Headers = NewHeaderRows
290+ Result.Rows = NewDataRows
291+
292+ 'Setup row numbers 1-based
293+ Result.ApplyRowNumbering()
294+
295+ Return Result
296+ End Function
297+
298+ ''' <summary>
299+ ''' Calculate Excel-like column name (A, B, ..., Z, AA, AB, ..., AZ, BA, BB, ...) for given 0-based column index
300+ ''' </summary>
301+ ''' <param name="columnIndex"></param>
302+ ''' <returns></returns>
303+ Friend Shared ReadOnly Property ExcelColumnName(columnIndex As Integer ) As String
304+ Get
305+ If columnIndex < 0 Then Throw New ArgumentOutOfRangeException( NameOf (columnIndex), "Must be a positive value" )
306+ Dim x As Integer = columnIndex + 1
307+ If x >= 1 AndAlso x <= 26 Then
308+ Return Char .ConvertFromUtf32(x + 64 )
309+ Else
310+ Return ExcelColumnName( CType (((x - x Mod 26 ) / 26 ) - 1 , Integer )) & Char .ConvertFromUtf32((x Mod 26 ) + 64 )
311+ End If
312+ End Get
313+ End Property
314+
315+ ''' <summary>
316+ ''' Creates a copy of the current table
317+ ''' </summary>
318+ ''' <returns></returns>
319+ Public Function Clone() As TextTable
320+ Dim NewHeaders As New System.Collections.Generic.List( Of TextRow)
321+ For MyCounter As Integer = 0 To Me .Headers.Count - 1
322+ NewHeaders.Add( Me .Headers(MyCounter).Clone)
323+ Next
324+ Dim NewRows As New System.Collections.Generic.List( Of TextRow)
325+ For MyCounter As Integer = 0 To Me .Rows.Count - 1
326+ NewRows.Add( Me .Rows(MyCounter).Clone)
327+ Next
328+ Return New TextTable(NewHeaders, NewRows)
329+ End Function
330+
170331 ''' <summary>
171332 ''' Text representation of table
172333 ''' </summary>
0 commit comments