Skip to content

Commit eec20ad

Browse files
committed
added method overload for LookupUniqueColumnName + feature ApplyFirstRowContentToColumnNames
1 parent ba50a36 commit eec20ad

5 files changed

Lines changed: 90 additions & 9 deletions

File tree

CompuMaster.Data.Controls/CompuMaster.Data.Controls.vbproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<OutputType>Library</OutputType>
55
<AssemblyName>CompuMaster.Data.Controls</AssemblyName>
66
<TargetFrameworks>net48;net6.0-windows</TargetFrameworks>
7-
<Version>3.0.2024.0522</Version>
7+
<Version>3.0.2024.0523</Version>
88
<Authors>Jochen Wezel</Authors>
99
<Company>CompuMaster GmbH</Company>
1010
<Copyright>2010-2024 CompuMaster GmbH</Copyright>

CompuMaster.Data/CompuMaster.Data.vbproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<PropertyGroup>
44
<RootNamespace></RootNamespace>
55
<TargetFrameworks>netstandard2.0;netcoreapp3.1;net6.0;net48;net461</TargetFrameworks>
6-
<Version>3.0.2024.0522</Version>
6+
<Version>3.0.2024.0523</Version>
77
<Authors>Jochen Wezel</Authors>
88
<Company>CompuMaster GmbH</Company>
99
<Copyright>2010-2024 CompuMaster GmbH</Copyright>

CompuMaster.Data/DataTables.vb

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1587,7 +1587,7 @@ Namespace CompuMaster.Data
15871587
''' </summary>
15881588
''' <param name="dataTable">The data table which shall get a new data column</param>
15891589
''' <param name="suggestedColumnName">A column name suggestion</param>
1590-
''' <returns>The suggested column name as it is or modified column name to be unique</returns>
1590+
''' <returns>The suggested column name as it is or modified column name to be unique (case-insensitive)</returns>
15911591
''' <remarks>
15921592
''' </remarks>
15931593
Public Shared Function LookupUniqueColumnName(ByVal dataTable As DataTable, ByVal suggestedColumnName As String) As String
@@ -1599,14 +1599,24 @@ Namespace CompuMaster.Data
15991599
''' </summary>
16001600
''' <param name="dataTable">The data table which shall get a new data column</param>
16011601
''' <param name="suggestedColumnName">A column name suggestion</param>
1602-
''' <returns>The suggested column name as it is or modified column name to be unique</returns>
1602+
''' <returns>The suggested column name as it is or modified column name to be unique (case-insensitive)</returns>
16031603
''' <remarks>
16041604
''' </remarks>
16051605
<Obsolete("Use the correct method name without typing error"), ComponentModel.EditorBrowsable(ComponentModel.EditorBrowsableState.Never)>
16061606
Public Shared Function LookupUnqiueColumnName(ByVal dataTable As DataTable, ByVal suggestedColumnName As String) As String
16071607
Return CompuMaster.Data.DataTablesTools.LookupUniqueColumnName(dataTable, suggestedColumnName)
16081608
End Function
16091609

1610+
''' <summary>
1611+
''' Lookup a new unique column name for a data table
1612+
''' </summary>
1613+
''' <param name="columnNames">The column names of a data table</param>
1614+
''' <param name="suggestedColumnName">A column name suggestion</param>
1615+
''' <returns>The suggested column name as it is or modified column name to be unique (case-insensitive)</returns>
1616+
Public Shared Function LookupUniqueColumnName(columnNames As String(), ByVal suggestedColumnName As String) As String
1617+
Return CompuMaster.Data.DataTablesTools.LookupUniqueColumnName(columnNames, suggestedColumnName, "")
1618+
End Function
1619+
16101620
''' <summary>
16111621
''' Return a string with all columns and rows as an html table
16121622
''' </summary>
@@ -5004,6 +5014,34 @@ Namespace CompuMaster.Data
50045014
Return Result
50055015
End Function
50065016

5017+
''' <summary>
5018+
''' Apply column names based on first row content (and remove first row)
5019+
''' </summary>
5020+
''' <param name="table"></param>
5021+
Public Shared Sub ApplyFirstRowContentToColumnNames(table As DataTable)
5022+
Dim FirstRow As DataRow = table.Rows(0)
5023+
Dim ColumnNames As New List(Of String)
5024+
5025+
'Find unique column names from first row
5026+
For ColIndex As Integer = 0 To table.Columns.Count - 1
5027+
Dim NewColumnName As String = Utils.NoDBNull(FirstRow(ColIndex), "").ToString()
5028+
If ColumnNames.Contains(NewColumnName) = False Then
5029+
ColumnNames.Add(NewColumnName)
5030+
Else
5031+
ColumnNames.Add(DataTables.LookupUniqueColumnName(ColumnNames.ToArray, NewColumnName))
5032+
End If
5033+
Next
5034+
If ColumnNames.Count <> table.Columns.Count Then Throw New InvalidOperationException("Internal error: Column count mismatch")
5035+
5036+
'Assign new column names
5037+
For ColIndex As Integer = 0 To table.Columns.Count - 1
5038+
table.Columns(ColIndex).ColumnName = ColumnNames(ColIndex)
5039+
Next
5040+
5041+
'Remove first row
5042+
table.Rows.RemoveAt(0)
5043+
End Sub
5044+
50075045
End Class
50085046

50095047
End Namespace

CompuMaster.Data/DataTablesTools.vb

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1474,13 +1474,28 @@ Namespace CompuMaster.Data
14741474
''' <param name="suggestedColumnName">A column name suggestion</param>
14751475
''' <returns>The suggested column name as it is or modified column name to be unique</returns>
14761476
Friend Shared Function LookupUniqueColumnName(ByVal dataTable As DataTable, ByVal suggestedColumnName As String) As String
1477+
Dim ColumnNames As New List(Of String)
1478+
For MyCounter As Integer = 0 To dataTable.Columns.Count - 1
1479+
ColumnNames.Add(dataTable.Columns(MyCounter).ColumnName)
1480+
Next
1481+
Return LookupUniqueColumnName(ColumnNames.ToArray, suggestedColumnName)
1482+
End Function
1483+
1484+
''' <summary>
1485+
''' Lookup a new unique column name for a data table
1486+
''' </summary>
1487+
''' <param name="columnNames">The column names of a data table</param>
1488+
''' <param name="suggestedColumnName">A column name suggestion</param>
1489+
''' <returns>The suggested column name as it is or modified column name to be unique (case-insensitive)</returns>
1490+
Friend Shared Function LookupUniqueColumnName(columnNames As String(), ByVal suggestedColumnName As String, Optional prefixForSuggestedColumnNames As String = "ClientTable_") As String
14771491

14781492
Dim ColumnNameAlreadyExistant As Boolean = False
1479-
For MyCounter As Integer = 0 To dataTable.Columns.Count - 1
1493+
For MyCounter As Integer = 0 To columnNames.Length - 1
14801494
#Disable Warning CA1309 ' Ordinalzeichenfolgenvergleich verwenden
1481-
If String.Compare(suggestedColumnName, dataTable.Columns(MyCounter).ColumnName, True, Threading.Thread.CurrentThread.CurrentCulture) = 0 Then
1495+
If String.Compare(suggestedColumnName, columnNames(MyCounter), True, Threading.Thread.CurrentThread.CurrentCulture) = 0 Then
14821496
#Enable Warning CA1309 ' Ordinalzeichenfolgenvergleich verwenden
14831497
ColumnNameAlreadyExistant = True
1498+
Exit For
14841499
End If
14851500
Next
14861501

@@ -1489,7 +1504,7 @@ Namespace CompuMaster.Data
14891504
Return suggestedColumnName
14901505
Else
14911506
'Add prefix "ClientTable_" or add/increase a counter at the end
1492-
If suggestedColumnName.StartsWith("ClientTable_", StringComparison.Ordinal) Then
1507+
If suggestedColumnName.StartsWith(prefixForSuggestedColumnNames, StringComparison.Ordinal) Then
14931508
'Find the position range of an already existing counter at the end of the string - if there is a number
14941509
Dim NumberPositionIndex As Integer = -1
14951510
For NumberPartCounter As Integer = suggestedColumnName.Length - 1 To 0 Step -1
@@ -1515,10 +1530,10 @@ Namespace CompuMaster.Data
15151530
End If
15161531
Else
15171532
'Add new prefix
1518-
suggestedColumnName = "ClientTable_" & suggestedColumnName
1533+
suggestedColumnName = prefixForSuggestedColumnNames & suggestedColumnName
15191534
End If
15201535
'Revalidate uniqueness by running recursively
1521-
suggestedColumnName = LookupUniqueColumnName(dataTable, suggestedColumnName)
1536+
suggestedColumnName = LookupUniqueColumnName(columnNames, suggestedColumnName, prefixForSuggestedColumnNames)
15221537
End If
15231538

15241539
Return suggestedColumnName

CompuMaster.Test.Tools.Data/DataTablesTest.vb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ Namespace CompuMaster.Test.Data
6868
Return dt
6969
End Function
7070

71+
Private Function TestTable2WithDisabledFirstRowContentAsColumnName() As DataTable
72+
Dim file As String = AssemblyTestEnvironment.TestFileAbsolutePath(System.IO.Path.Combine("testfiles", "Q&A.xlsx"))
73+
Dim dt As DataTable = CompuMaster.Data.XlsEpplus.ReadDataTableFromXlsFile(file, False) ', "Rund um das NT")
74+
Return dt
75+
End Function
76+
7177
Private Function TestTable2WithInvariantCultureInColumnNames() As DataTable
7278
Dim Result = TestTable2()
7379
For MyCounter As Integer = Result.Columns("Erläuterung").Ordinal + 1 To Result.Columns.Count - 1
@@ -1337,6 +1343,14 @@ Namespace CompuMaster.Test.Data
13371343
Assert.IsFalse(dt.Columns.Contains(uname))
13381344
End Sub
13391345

1346+
<Test> Public Sub LookupUniqueColumnName2()
1347+
Dim DuplicatedColumnNames15 = New String() {"Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column", "Column"}
1348+
Dim ColumnsSimplyNumbered15 = New String() {"Column1", "Column2", "Column3", "Column4", "Column5", "Column6", "Column7", "Column8", "Column9", "Column10", "Column11", "Column12", "Column13", "Column14", "Column15"}
1349+
Assert.AreEqual("Column1", CompuMaster.Data.DataTables.LookupUniqueColumnName(DuplicatedColumnNames15, "Column"))
1350+
Assert.AreEqual("Column1", CompuMaster.Data.DataTables.LookupUniqueColumnName(DuplicatedColumnNames15, "Column1"))
1351+
Assert.AreEqual("Column16", CompuMaster.Data.DataTables.LookupUniqueColumnName(ColumnsSimplyNumbered15, "Column1"))
1352+
End Sub
1353+
13401354
<Test()> Public Sub CloneTableAndReArrangeDataColumns()
13411355
Dim dt As New DataTable
13421356
Dim dt2 As DataTable
@@ -2796,6 +2810,20 @@ Namespace CompuMaster.Test.Data
27962810
Return Result
27972811
End Function
27982812

2813+
<Test> Public Sub ApplyFirstRowContentToColumnNames()
2814+
Dim FullDataTable As DataTable
2815+
2816+
FullDataTable = Me.TestTable2WithDisabledFirstRowContentAsColumnName
2817+
Assert.AreEqual(New String() {"Column1", "Column2", "Column3", "Column4", "Column5", "Column6", "Column7", "Column8", "Column9", "Column10", "Column11", "Column12", "Column13", "Column14", "Column15"}, CompuMaster.Data.DataTables.AllColumnNames(FullDataTable))
2818+
CompuMaster.Data.DataTables.ApplyFirstRowContentToColumnNames(FullDataTable)
2819+
Assert.AreEqual(New String() {"Frage", "Antwort A", "Antwort B", "Antwort C", "Antwort D", "Rubrik", "Richtige Antwort", "Erläuterung", "100", "200", "500", "1000", "5000", "10000", "20000"}, CompuMaster.Data.DataTables.AllColumnNames(FullDataTable))
2820+
2821+
FullDataTable = Me.TestTable2WithDisabledFirstRowContentAsColumnName
2822+
FullDataTable.Rows(0)(1) = "Frage"
2823+
CompuMaster.Data.DataTables.ApplyFirstRowContentToColumnNames(FullDataTable)
2824+
Assert.AreEqual(New String() {"Frage", "Frage1", "Antwort B", "Antwort C", "Antwort D", "Rubrik", "Richtige Antwort", "Erläuterung", "100", "200", "500", "1000", "5000", "10000", "20000"}, CompuMaster.Data.DataTables.AllColumnNames(FullDataTable))
2825+
End Sub
2826+
27992827
End Class
28002828
#Enable Warning CA1822 ' Member als statisch markieren
28012829

0 commit comments

Comments
 (0)