B4A Library [Class] Flexible Table

This thread will be used by Erel, Melamoud and myself to discuss / post new releases of the Table class.

The table class is a flexible UI component that enable scrollable table like UI, with sortable columns, multiselect rows etc

the table is very efficient, maintaining labels only for visible rows

old thread with details : http://www.b4x.com/forum/additional...view-supports-tables-any-size.html#post110901

The class depend on following libraries:
- StringUtils (standard)
- SQL (standard)
- JavaObject (standard)
- ScrollView2D (additional)

List of major features.
1. scrollable table UI
2. sortable columns
3. select a row, cell or multi select rows
4. callback for selection / click a cell / row
5. callback for long click action
6. read / write to CSV file

Current version --> 3.33 Custom View
Current version --> 1.44 Class

Other complementary routines:

Load data with the Remote Database Connector.


EDIT: LucaMs has written a routine to fill a table with a Remote Database Connector query result see post 182.
The routine hasn't been added into the Class for the reasons explained in post 183.
A sample program can be found HERE.

Code:
B4X:
'load data from a RDC Request
'Result = DBResult object got from a RDC request
'AutomaticWidths  True > set the column widths automaticaly
'Written by LucasMs
Public Sub LoadRDCResult(Result As DBResult, AutomaticWidths As Boolean)
    cAutomaticWidths = AutomaticWidths
    NumberOfColumns = Result.Columns.Size
    innerClearAll(NumberOfColumns)

    Dim Headers(NumberOfColumns) As String
    Dim ColumnWidths(NumberOfColumns) As Int
    Dim HeaderWidths(NumberOfColumns) As Int
    Dim DataWidths(NumberOfColumns) As Int
    Dim col, row As Int
    Dim str As String
    For col = 0 To NumberOfColumns - 1
        Headers(col) = Result.Columns.GetKeyAt(col)
        If AutomaticWidths = False Then
            ColumnWidths(col) = 130dip
            HeaderWidths(col) = 130dip
            DataWidths(col) = 130dip
        Else
            HeaderWidths(col) = cvs.MeasureStringWidth(Headers(col), Typeface.DEFAULT, cTextSize) + 8dip + cLineWidth
            DataWidths(col) = 0

            Dim FieldValue As Object
            For row = 0 To Result.Rows.Size - 1
                Dim Record() As Object = Result.Rows.Get(row)
                FieldValue = Record(col)
                If GetType(FieldValue) = "java.lang.String" Then
                    DataWidths(col) = Max(DataWidths(col), cvs.MeasureStringWidth(str, Typeface.DEFAULT, cTextSize) + 8dip + cLineWidth)
                End If
            Next
            ColumnWidths(col) = Max(HeaderWidths(col), DataWidths(col))
        End If
    Next
    SetHeader(Headers)
    SetColumnsWidths(ColumnWidths)

    For Each Record() As Object In Result.Rows
        Dim R(NumberOfColumns) As String
        Dim FieldV As String
        For col = 0 To NumberOfColumns - 1
            FieldV = Record(col)
            R(col) = FieldV
        Next
        AddRow(R)
    Next
End Sub

This is another routine updated by cimperia in post #392 using a Map for the columns and a List for the rows.
B4X:
'load data from a RDC Request
'A RDC request returns a DBResult object, therefore this method
'could be called as is:
'LoadRDCResult(DBResult.Columns, DBResult.Rows, True)
'AutomaticWidths  True > set the column widths automaticaly
'Written by LucasMs
Public Sub LoadRDCResult(Columns As Map, Rows As List, AutomaticWidths As Boolean)
  cAutomaticWidths = AutomaticWidths
  NumberOfColumns = Columns.Size
  innerClearAll(NumberOfColumns)

  Dim Headers(NumberOfColumns) As String
  Dim ColumnWidths(NumberOfColumns) As Int
  Dim HeaderWidths(NumberOfColumns) As Int
  Dim DataWidths(NumberOfColumns) As Int
  Dim col, row As Int
  Dim str As String
  For col = 0 To NumberOfColumns - 1
    Headers(col) = Columns.GetKeyAt(col)
    If AutomaticWidths = False Then
      ColumnWidths(col) = 130dip
      HeaderWidths(col) = 130dip
      DataWidths(col) = 130dip
    Else
      HeaderWidths(col) = cvs.MeasureStringWidth(Headers(col), Typeface.DEFAULT, cTextSize) + 8dip + cLineWidth
      DataWidths(col) = 0

      Dim FieldValue As Object
      For row = 0 To Rows.Size - 1
        Dim Record() As Object = Rows.Get(row)
        FieldValue = Record(col)
       If GetType(FieldValue) = "java.lang.String" Then
         DataWidths(col) = Max(DataWidths(col), cvs.MeasureStringWidth(str, Typeface.DEFAULT, cTextSize) + 8dip + cLineWidth)
       End If
      Next
      ColumnWidths(col) = Max(HeaderWidths(col), DataWidths(col))
    End If
  Next
  SetHeader(Headers)
  SetColumnsWidths(ColumnWidths)

  For Each Record() As Object In Rows
    Dim R(NumberOfColumns) As String
    Dim FieldV As String
    For col = 0 To NumberOfColumns - 1
      FieldV = Record(col)
      R(col) = FieldV
    Next
    AddRow(R)
  Next
End Sub


Load data from a MSMariaDB database.

Another routine for loading data from a MSMariaDB database can be found in post#727.
Thanks to @Magma.

Updates:
EDIT: 2024.01.13 Version 3.33
Changed possible values for DataType
TEXT and NUMBER become T, R and I
Amended problem with column colors
Amended problems with SetHeaderColors and SetHeaderTextColors

Version 3.32
Amended Header and HeaderFirst problem in SaveCSVFromTable
Moved If (lblStatusline... from AddRow to ShowRow

Version 3.31
Added SingleLine property for the Designer
Added StatusLineHeight as a property
Added FastScrollLabelMaxChars as a property

EDIT: 2021.06.28 Version 3.30
Added a check for none numeric values for numeric sorting.

EDIT: 2021.06.28 Version 3.29
Amended problem with column colors
Version 3.28
Added NumberOfColumns in the code
Added TopRowIndex method
Version 3.27
Amended MultiSelect EDIT: 2020.09.02 Version 3.26
Amended problem with sort with remove accents
Amended problem with SetRowColorN
Added SetCellAlignmentColN method
Added SetHeaderAlignmentColN method

EDIT: 2020.08.05 Version 3.24
Amended problem with JumpToRowAndSelect not being selected.
Amended error when setting RowHeight before the table initialized

EDIT: 2020.06.19 Version 3.22
Amended error in the insertRowAt routine.

EDIT: 2020.05.25 Version 3.21
Amended bug with TextSize in fixed columns

EDIT: 2020.05.16 Version 3.20
Added fast scroll feature
Version 3.19
Improved automatic width calculation and hidden columns
Version 3.18
Added a check in RemoveRowColorN to ensure that Row is not out of bounds
Added ShowRow event
Amended automatic width calculations
Amended hidden column width problem

EDIT: 2020.04.21 Version 3.17
Amended HeaderHight problem with fixed columns

EDIT: 2020.04.21 Version 3.16
Amended two errors.

EDIT: 2020.04.14 Version 3.14
Added the methods below
- LoadSQLiteDB4(SQLite As SQL, Query As String, AutomaticWidths As Boolean)
loads SQLite data with data type checking
- LoadSQLiteDB5(SQLite As SQL, Query As String, Values() As String, AutomaticWidths As Boolean).
loads SQLite data with data type checking , similar to LoadSQLiteDB4 but for parametrized queries.
- GetColumnDataTypes As String(), returns an Array with the data type for each column.
- GetColumnDataType(Column As Int) As String, returns the data type of the fiven column.
Added the InnerTotalWidth property, read only.
Added multiple first fiexed columns
Added line colors

EDIT: 2020.03.10 Version 3.10
Amended bug reported HERE

EDIT: 2020.03.06 Version 3.09
Amended bug reported HERE.

EDIT: 2020.02.29 Version 3.08
Amended SetHeaderTypefaces method problem reprted HERE.
Added HeaderTypeface property.

EDIT: 2020.01.08 Version 3.07
Amended bug ShowStatisLine = False property bug.
Added MultiSelect property to Designer properties.
You need to open and close the Designer when you use the new version the first time to make the MultiSelect property active.

EDIT: 2019.12.28 Version 3.06
Amened some bugs

EDIT: 2019.12.25 Version 3.05
Added FirstColumnFixed property which allows to fix the first column.
Attention: You need to open and close the Designer to make the new property active.

EDIT: 2019.11.15 Version 3.04
- Added SelectedRowTextColor and SlectedCellTextColor properties
- Added ZeroSelections property, True > when a selected row is pressed it will be unselected False > it remains selected.

EDIT: 2019.11.12 Version 3.03
- Changed JumpToRowAndSelect(Row As Int, Col As Int) to JumpToRowAndSelect(Col As Int, Row As Int)
- Changed LoadSQLiteDB2 signature. Replaced the possible values from "T", "I", "R" to "TEXT", "NUMBER" for coherence with SetColumnDataTypes.
- Added internal sorting bitmaps, avoids loading the image files into the Files folder.
- Added two new properties: SortBitmapWidth and SortBitmapColor.
- Added SetCustomSortingBitmaps method, which allows to use custom bitmaps instead of the internal ones.
Attention: You need to open and close the Designer to make the new properties active.
Attention: You need to invert the parameters in JumpToRowAndSelect.

EDIT: 2019.07.04 Version 3.02
Amended error reported in post #887

EDIT: 2019.06.26 Version 3.01
Amended SingleLine property setting in the code

EDIT: 2019.04.05 Version 3.00
Amended SetColumnColors and SetTextColors
Removed Reflection library dependency

EDIT: 2018.04.11 Version 2.29
Version 2.27
set the two variables sortedCol and sortingDir to Public instaed of Private
added RemoveAccent routine for sorting with accented characters
Version 2.28
Added SetHeaderTypeFaces
Added SortRemoveAccents property
Version 2.29
Added SaveTableToCSV2 with a user defined separator character

EDIT: 2018.04.11 Version 2.26
added LoadSQLiteDB3 method using SQLExec2 instead of SQLExec
The query can include question marks which will be replaced with the values in the array.

EDIT: 2018.03.27 Version 2.25
amended minor errors
added UpdateCell method

EDIT: 2017.11.19 Version 2.22
improved JumpToRowAndSelect scrolls horizontally to the selected column
improved setHeaderHeight
added padding for status bar Label

EDIT: 2017.06.27 Version 2.19
Replaced DoEvents by Sleep(0)
Asked HERE

EDIT: 2017.06.27 Version 2.19
Replaced DoEvents by Sleep(0)
Asked HERE

EDIT: 2017.05.16 Version 2.18
Amended error reported HERE.

EDIT: 2017.03.09 Version 2.17
Amended error reported HERE.

EDIT: 2017.03.09 Version 2.15
Amended error reported here, Event signatures
#Event: CellClick(col As Int, row As Int)
#Event: CellLongClick(col As Int, row As Int)

EDIT: 2016.12.05 Version 2.14
Added NumberOfColumns and NumberOfRows as Public variables.
Amended error reported here.

EDIT: 2016.12.05 Version 2.13
Amended error reported here.
Added NumberOfColumns as a property for the Designer.

EDIT: 2016.07.30 Version 2.10
Amended error with TextAlignment and HeaderTextAlignment reported in post #606

EDIT: 2016.03.15 Version 2.00
Added CustomView support.
This version can be compiled into a library.
Changes between the previous versions and version 2.00
For a Table added in the Designer, this is new
No need to initialize nor add it onto a parent view
'For a Table added in the Designer, this is new
'No need to initialize nor add it onto a parent view

For a Table added in the code:
The Initialize routine has been splittend into two routines.
New:
Initialize (CallBack As Object, EventName As String)
InitializeTable (vNumberOfColumns As Int, cellAlignement As Int, showStatusL As Boolean)

'Example:
Table1.Initialize(Me, "Table1")
Table1.InitializeTable(5, Gravity.CENTER_HORIZONTAL, True)


Old:
Initialize(CallBack As Object, EventName As String, vNumberOfColumns As Int, cellAlignement As Int, showStatusL As Boolean)
Example:
Table1.Initialize(Me, "Table1", 5, Gravity.CENTER_HORIZONTAL, True)

EDIT: 2015.04.29 Version 1.43
As the modifications in LoadSQLiteDB don't work in all cases I went back.
LoadSQLiteDB as in version 1.40
Added LoadSQLiteDB2 where the column data types must be given.

EDIT: 2015.04.26 Version 1.42
Changed he LoadSQLiteDB routine, version 1.41 didn't work as expected.
The final solution was suggested by cimperia HERE.

EDIT: 2015.04.16 Version 1.41
Changed the LoadSQLiteDB routine according to the error reported in the SQL issue thread
and the SQLite Cursor GetString versus GetDouble thread.
The problem appears with numbers bigger than 999999.
I left version 1.40 in case of problems.
I tested it with a few databases, but I am not sure if it works in all cases.

EDIT: 2015.03.05
Amended bugs reported in posts #383 and #386
Added SetAutomaticWidths routine

EDIT: 2015.02.19
Amended the problem alignment reported in post # 378

EDIT: 2015.02.13
Amended the problem of rows not shown reported in post # 371

EDIT: 2015.01.09
Added header aligments

EDIT: 2014.08.14
Added HeaderHeight property
Amended RowColor problem reported in post #260

EDIT: 2014.08.10
Added SortColumn property asked in post #266
Added UseColumnColors ColumnColors and HeaderColors propeties

EDIT: 2014.05.10 Added RowHeight as a property

Screenshot:

1589638570453.png
 

Attachments

  • TableV1_44.zip
    44.8 KB · Views: 1,980
  • 1589638550715.png
    1589638550715.png
    31.8 KB · Views: 1,406
  • TestFastScroll.zip
    50.6 KB · Views: 1,291
  • Table.bas
    136.3 KB · Views: 96
  • TableV3_33.zip
    106.4 KB · Views: 142
Last edited:

Eric McDonald

Member
Licensed User
With the amount of pages there are on this thread, I have no idea if this has been asked yet but,

is there a way to select a row then select it again to be able to deselect it (pretty much just removing the color of the selected row)?

Also, is there a way to change the color of the selected row?
 

klaus

Expert
Licensed User
Longtime User
is there a way to select a row then select it again to be able to deselect it
Directly no, but you can use a workaround:
Define a Global variable SelectedRow = -1 As Int
And use the CellClick event like this:
B4X:
Sub Table2_CellClick(col As Int, row As Int)
    If SelectedRow >= 0 And SelectedRow = row Then
        Table2.clearSelection 'this removes the selection and removes the selected row color
        SelectedRow = -1
    Else
        SelectedRow = row
    End If
End Sub

Also, is there a way to change the color of the selected row?
Yes, you have the SelectedRowColor and SelectedCellColor properties which can be defined in the Designer or in the code.

I have seen that there are no SelectedRowTextColor and SelectedCellTextColor properties.
I will add these today and I will also add a property, ZeroSelections, allowing to have no selection.
 

klaus

Expert
Licensed User
Longtime User
The Table class has been updated to version 3.04.
- Added SelectedRowTextColor and SlectedCellTextColor properties
- Added ZeroSelections property, True > when a selected row is pressed it will be unselected False > it remains selected.
 
Last edited:

AnandGupta

Expert
Licensed User
Longtime User
Sorry, I was sure that I did it, but after your post I saw that I removed the previous version without uploading the new version!?
Thanks got it, but updates text is still due, I think.

2019-11-16_154546.png

Regards,

Anand
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Sorry, I was sure that I did it, but after your post I saw that I removed the previous version without uploading the new version!?

Just had a look at the latest version and noticed it still uses the old selection sort.
I found this to be quite slow and changed it with the SortType method on a list.
This is indeed a lot faster and I posted about this and I think you were going to look into it
and maybe incorporate it. This is a long time ago. How is the situation regarding this?

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This is the relevant code as I have it now, may have changed since that thread.

B4X:
Public Sub SortTableNum(col As Int, bAscending As Boolean)

    Dim i As Long
    Dim lUB As Long
    Dim DataSorted As List
    Dim strColumnDataType As String

    GetVisibleRows (SV.VerticalScrollPosition)


    'strColumnDataTypes is set in LoadSQLDB4
    '---------------------------------------
    strColumnDataType = strColumnDataTypes(col)

    lUB = Data.Size - 1

    DataSorted.Initialize

    If bMap Then
        If col = 0 Then
            If strColumnDataType = "I" Then
                If iAlteredRowColour <> -1 Then
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairLong(i, CInt(SortResultMap.GetKeyAt(i)), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairLong(i, CInt(SortResultMap.GetKeyAt(i)), False))
                    Next
                End If
                DataSorted.SortType("lLong", bAscending)    '<< this will do the sort
            Else
                If iAlteredRowColour <> -1 Then
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairDouble(i, SortResultMap.GetKeyAt(i), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairDouble(i, SortResultMap.GetKeyAt(i), False))
                    Next
                End If
                'this will take a bit less than half of the total time of SortTableNum
                '---------------------------------------------------------------------
                DataSorted.SortType("dDouble", bAscending)    '<< this will do the sort
            End If
        Else    'If col = 0
            If strColumnDataType = "I" Then
                If iAlteredRowColour <> -1 Then
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairLong(i, CInt(SortResultMap.GetValueAt(i)), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairLong(i, CInt(SortResultMap.GetValueAt(i)), False))
                    Next
                End If
                DataSorted.SortType("lLong", bAscending)    '<< this will do the sort
            Else
                If iAlteredRowColour <> -1 Then
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairDouble(i, SortResultMap.GetValueAt(i), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To lUB
                        DataSorted.Add (setSortPairDouble(i, SortResultMap.GetValueAt(i), False))
                    Next
                End If
                'this will take a bit less than half of the total time of SortTableNum
                '---------------------------------------------------------------------
                DataSorted.SortType("dDouble", bAscending)    '<< this will do the sort
            End If
        End If    'If col = 0
    Else
        If strColumnDataType = "I" Then
            If iAlteredRowColour <> -1 Then
                For i = 0 To lUB
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairLong(i, SortResultSet.GetInt2(col), arrAlteredRowColour(i)))
                Next
            Else
                For i = 0 To lUB
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairLong(i, SortResultSet.GetInt2(col), False))
                Next
            End If
            DataSorted.SortType("lLong", bAscending)    '<< this will do the sort
        Else
            If iAlteredRowColour <> -1 Then
                For i = 0 To lUB
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairDouble(i, SortResultSet.GetDouble2(col), arrAlteredRowColour(i)))
                Next
            Else
                For i = 0 To lUB
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairDouble(i, SortResultSet.GetDouble2(col), False))
                Next
            End If
            'this will take a bit less than half of the total time of SortTableNum
            '---------------------------------------------------------------------
            DataSorted.SortType("dDouble", bAscending)    '<< this will do the sort
        End If
    End If

    SelectedRows.Clear

    debug_counter = 0

    If strColumnDataType = "I" Then
        If iAlteredRowColour <> -1 Then
            For i = 0 To lUB
                Dim tL As SortLong = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tL.IDX))
                SetRowColour(i, tL.bColouredRow, False)
            Next
        Else
            For i = 0 To lUB
                Dim tL As SortLong = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tL.IDX))
            Next
        End If
    Else
        If iAlteredRowColour <> -1 Then
            'will be column type real - "R"
            For i = 0 To lUB
                Dim tD As SortDouble = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tD.IDX))
                SetRowColour(i, tD.bColouredRow, False)
            Next
        Else
            'will be column type real - "R"
            For i = 0 To lUB
                Dim tD As SortDouble = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tD.IDX))
            Next
        End If
    End If

    RefreshTable

End Sub

Public Sub SortTable(col As Int, bAscending As Boolean)

    Dim i As Long
    Dim lUB As Long
    Dim DataSorted As List

    GetVisibleRows (SV.VerticalScrollPosition)

    lUB = Data.Size - 1

    If bMap Then
        If col = 0 Then
            DataSorted.Initialize
            If arrDateColumns(col) = True Then
                If iAlteredRowColour <> -1 Then
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairLong(i, CLng(SortResultMap.GetKeyAt(i)), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairLong(i, CLng(SortResultMap.GetKeyAt(i)), False))
                    Next
                End If
                DataSorted.SortType("lLong", bAscending)
            Else    'If arrDateColumns(col) = True
                If iAlteredRowColour <> -1 Then
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairString(i, ClearStringNull(SortResultMap.GetKeyAt(i), ""), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairString(i, ClearStringNull(SortResultMap.GetKeyAt(i), ""), False))
                    Next
                End If
                DataSorted.SortType("strString", bAscending)
            End If    'If arrDateColumns(col) = True
        Else    'If col = 0
            DataSorted.Initialize
            If arrDateColumns(col) = True Then
                If iAlteredRowColour <> -1 Then
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairLong(i, CLng(SortResultMap.GetValueAt(i)), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairLong(i, CLng(SortResultMap.GetValueAt(i)), False))
                    Next
                End If
                DataSorted.SortType("lLong", bAscending)
            Else    'If arrDateColumns(col) = True
                If iAlteredRowColour <> -1 Then
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairString(i, ClearStringNull(SortResultMap.GetValueAt(i), ""), arrAlteredRowColour(i)))
                    Next
                Else
                    For i = 0 To SortResultMap.Size - 1
                        DataSorted.Add (setSortPairString(i, ClearStringNull(SortResultMap.GetValueAt(i), ""), False))
                    Next
                End If
                DataSorted.SortType("strString", bAscending)
            End If    'If arrDateColumns(col) = True

        End If    'If col = 0
    Else    'If bMap
        DataSorted.Initialize
        If arrDateColumns(col) = True Then
            If iAlteredRowColour <> -1 Then
                For i = 0 To SortResultSet.RowCount - 1
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairLong(i, SortResultSet.GetLong2(col), arrAlteredRowColour(i)))
                Next
            Else
                For i = 0 To SortResultSet.RowCount - 1
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairLong(i, SortResultSet.GetLong2(col), False))
                Next
            End If
            DataSorted.SortType("lLong", bAscending)
        Else
            If iAlteredRowColour <> -1 Then
                For i = 0 To SortResultSet.RowCount - 1
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairString(i, ClearStringNull(SortResultSet.GetString2(col), ""), arrAlteredRowColour(i)))
                    'General.RunLog("SortTable, setSortPairString, arrAlteredRowColour(" & i & "): " & arrAlteredRowColour(i))
                Next
            Else
                For i = 0 To SortResultSet.RowCount - 1
                    SortResultSet.Position = i
                    DataSorted.Add (setSortPairString(i, ClearStringNull(SortResultSet.GetString2(col), ""), False))
                Next
            End If
            DataSorted.SortType("strString", bAscending)
        End If
    End If    'If bMap

    SelectedRows.Clear
    debug_counter = 0

    If arrDateColumns(col) = True Then
        If iAlteredRowColour <> -1 Then
            For i = 0 To lUB
                Dim tL As SortLong = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tL.IDX))
                SetRowColour(i, tL.bColouredRow, False)
            Next
        Else
            For i = 0 To lUB
                Dim tL As SortLong = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tL.IDX))
            Next
        End If
    Else    'If arrDateColumns(col) = True
        If iAlteredRowColour <> -1 Then
            For i = 0 To lUB
                Dim tDS As SortString = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tDS.IDX))
                SetRowColour(i, tDS.bColouredRow, False)
            Next
        Else
            For i = 0 To lUB
                Dim tDS As SortString = DataSorted.Get(i)
                'DataTemp is populated in LoadSQLDB4 or LoadSQLiteDBFromMap,
                'so keep using the same original Data list with different sorts
                '--------------------------------------------------------------
                Data.Set(i, DataTemp.Get(tDS.IDX))
            Next
        End If
    End If    'If arrDateColumns(col) = True

    RefreshTable

End Sub

Sub setSortPairString(lIDX As Long, strValue As String, bColouredRow As Boolean) As SortString

    Dim tSS As SortString

    tSS.Initialize
    tSS.IDX = lIDX
    tSS.strString = strValue
    tSS.bColouredRow = bColouredRow
    Return tSS

End Sub

Sub setSortPairLong(lIDX As Long, lValue As Long, bColouredRow As Boolean) As SortLong

    Dim tL As SortLong

    tL.Initialize
    tL.IDX = lIDX
    tL.lLong = lValue
    tL.bColouredRow = bColouredRow
    Return tL

End Sub

Sub setSortPairDouble(lIDX As Long, dValue As Double, bColouredRow As Boolean) As SortDouble

    Dim tD As SortDouble

    tD.Initialize
    tD.IDX = lIDX
    tD.dDouble = dValue
    tD.bColouredRow = bColouredRow
    Return tD

End Sub

Public Sub SetSortCursor(oRS As ResultSet)
    bMap = False
    SortResultSet = oRS
End Sub

Public Sub SetSortMap(oMap As Map)
    bMap = True
    SortResultMap = oMap
End Sub

Sub Class_Globals

    Public bMap As Boolean
    Public SortResultSet As ResultSet
    Public SortResultMap As Map

    Type SortString(IDX As Long, _
                     strString As String, _
                     bColouredRow As Boolean)
    Type SortLong(IDX As Long, _
                   lLong As Long, _
                   bColouredRow As Boolean)
    Type SortDouble(IDX As Long, _
                     dDouble As Double, _
                     bColouredRow As Boolean)
                     bColouredRow As Boolean)

    Private DataTemp As List

Public Sub LoadSQLiteDB(RS1 As ResultSet, _
                         AutomaticWidths As Boolean, _
                         ColumnNames() As String, _
                         ColumnDataTypes() As String, _
                         MaxColumnWidths() As Int, _
                         ColWidths() As Int)
    
    'towards the end of LoadSQLiteDB
    SetSortCursor (RS1)
    DataTemp.Initialize
    For i = 0 To lRows - 1
        DataTemp.Add (Data.Get(i))
    Next

Will see if I can find that thread now.

RBS
 

Eric McDonald

Member
Licensed User
Not sure if this has been asked yet but I haven't been able to find it anywhere on this forums or google.

But is there a way to take a table and save it as a CSV file then be able to take a different table and save it into the same CSV file under the existing rows?

I appreciate any help.
 

klaus

Expert
Licensed User
Longtime User
Yes!
There are two methods:
SaveTableToCSV(Dir As String, Filename As String)
SaveTableToCSV2(Dir As String, Filename As String, SeparatorChar As String)

You could have found it on your own.
In the IDE, type the name of the Table object and a dot, like in the example Table1.
1577725166517.png

The inline help shows all the methods and properties for the Table object.
 

Eric McDonald

Member
Licensed User
I have tried that method but what I am trying to do is explained with the comments in the code below
B4X:
    If File.Exists(File.DirRootExternal,"CSV_Test.csv") = True Then
        'Take the data from the existing CSV file and store it somewhere
        'Add that data to a new CSV file
        'The below row will take that saved data from the old CSV file and take the data
        'from the new table and add it to a new CSV file
        register.SaveTableToCSV(File.DirRootExternal,"CSV_Test.csv")
    Else
        register.SaveTableToCSV(File.DirRootExternal,"CSV_Test.csv")
    End If

Just trying to find something that will do what I'm trying to do in my code, not necessarily go the route of checking if the file already exists.
 

klaus

Expert
Licensed User
Longtime User
Sorry, I hadn't read your post deeply enough.
It is not possible, in the current version, to append the table content to an existing *.csv file.
The SaveTableToCSV routines are based on the StringUtils library which doesn't allow to append data.
To append data you need to write your own routine.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User

Eric McDonald

Member
Licensed User
Is there a relatively possible way to be able to take the values (As Strings) from the table and have that text be auto-filled into an existing Edit Text?
I.e. An edit selected feature when a button is pressed, an existing edit text control will be filled with the specified value from the table.

Going along with this feature to actually make it work, is there a way to check if a certain row is selected using Register_CellClick as a way to take the values from that specific row?
 

klaus

Expert
Licensed User
Longtime User
You can use the Table_CellClick(col As Int, row As Int) event which returns the selected row and column.
You have the Value = Table.GetValue(col, row) method which returns the value of the cell with the given row and column index.
You can define two variables to save the row and col values and or save the content with the method above.

You have Table.SelectedRows, the list of the selected row indexes without the selected column indexes.
Table.SelectedRows.Size returns the number of selected rows. If you set Table.MultiSelect = True you can select several rows.
Table.SelectedRows.Get(0) returns the index of the first selected row and Table.SelectedRows.Get(1) the next one and so on.
 
Top