Android Question Updating from old Table Class to Flex Table Class [SOLVED]

Tim Chapman

Active Member
Licensed User
Longtime User
I am trying to update my project to Flex Table class because I need functions it offers.
I have added a layout file in the Files folder and added it in the files manager.
When I open it in the designer and tell it to generate members, it seems to do nothing.
So I created a new project with nothing in it. Added the main.bal layout file and tried to generate members again. Same results.
As a result of this not working correctly, I am getting an error because
There is code regarding initializing the table in Activity_Create and at line 454.

Presently I am getting an error in the Table module but I am certain it is because I have not set it up correctly in the Main module.
I have also tried to follow what was done here (https://www.b4x.com/android/forum/threads/how-to-remove-a-row-on-a-table.112439/) in RedDogRework with no luck.
Project is attached.
What am I doing wrong here?
Thank you again for the help in advance!
 

Attachments

  • TimTodo.zip
    215.3 KB · Views: 41
Last edited:
Solution
Where ever you use a TempTodo = Starter.TodoList.Get() in a For / Next loop you must declare the TempTodo object.
I am not sure if the TempTodo.Initialize is always necessary.
I leave it up to you to make these modifications.
I think that this should solve your problem.
B4X:
    For j = 0 To Starter.TodoList.Size-1
        'Log("...")
        'Log("*TodoList counter = "&j)
        Private TempTodo As Todo
        TempTodo.Initialize
        TempTodo = Starter.TodoList.Get(j)

klaus

Expert
Licensed User
Longtime User
I had a look at your project.

Some questions:
1. You are adding the Table in the Designer, but then in the LoadTable routine you remove it and add a new one by code. Why ?
You should keep it and select the needed properties directly in the Designer.
2. You have 7 columns but you display only 2, why ?
3. I do not understand what you want to do in the Table1_CellClick event routine.
When pressing any button, the last lines are executed, do you really want to do this.
For me, the Cancel button should do nothing. And what do you want to do when the No button is clicked ?

Attached you find your project modified.

I have changed some lines to make it work on my computer.
These lines have this comment at the end: 'klaus
I commented the Tracker start.
I changed the the file dir to File.DirAssets
I commented the call to TableSave_Click.

I set the number of columns to 7 in the Designer.
I changed the code of the LoadTable routine.
I changed the column width to show all columns, the Table version allows horizontal scrolling.
 

Attachments

  • TimTodoKlaus.zip
    215.4 KB · Views: 50
Upvote 1

Tim Chapman

Active Member
Licensed User
Longtime User
1. You are adding the Table in the Designer, but then in the LoadTable routine you remove it and add a new one by code. Why ?
You should keep it and select the needed properties directly in the Designer.
I got that code from line 41 of the ExcelExample which I downloaded from here:
I was not using the designer. I thought it made sense to remove the table then initialize it again. My understanding may be incorrect, but I thought this would eliminate having one table over another and also might save memory. I may not have a correct understanding of this.
2. You have 7 columns but you display only 2, why ?
2 reasons:

1st is that the user doesn't need to see all the columns on the table but can see them with Table1_CellClick. Since the screen is small (and would not allow scrolling left and right) this allows the user to see the relevant information and tap to see the rest.

2nd is because I need all 7 columns in the table so that all the data is saved when I click TableSave_Click.
3. I do not understand what you want to do in the Table1_CellClick event routine.
When pressing any button, the last lines are executed, do you really want to do this.
For me, the Cancel button should do nothing. And what do you want to do when the No button is clicked ?
I don't understand what you mean by "the last lines are executed".
I have an If, Then, Else (line 302) which makes the code do nothing if No or Cancel are pressed. If I have done this incorrectly, please let me know. The table is currently redrawn and saved as I have it now, but that is an error and need to be included in the If, Then statement. When No is pressed or cancel, the table simply needs to be redrawn or left alone. I will have to figure that out. Thanks for pointing this out.

Table1_CellClick does two things:

1st is to show the information from all the columns(omits not column header if note is blank).

2nd is to allow the user to mark the Todo item complete. That Todo item is then changed in the TodoList (list of Type Todo). This is done in the LoadArray sub which only loads Todos from the spreadsheet that have a status of greater than 0 and less than 5 (line 142 of TimTodoKlaus). Done Todos have a status of 11 so the completed Todo will not be loaded.
Then the table is displayed again without the completed Todo in the LoadTable sub.
Then the table is saved to a new spreadsheet in TableSave_Click sub.
I have changed some lines to make it work on my computer.
These lines have this comment at the end: 'klaus
No problem. I will address those.
I commented the Tracker start.
No problem. I will uncomment it.
I changed the the file dir to File.DirAssets
No problem. I will put that back to how it was.
I use another program to download the TodoList to DirInternal then move it to Download.
The reason it is in another program (which will call this program when I figure out how to make that work) is because I could not get the FTP download to complete when I added that code to this. I think it was due to the resumable subs issue. I could not get it to work no matter how I tried. (Then to add to the fun, I think Cloudflare blocked it because I had downloaded it too many times. I don't have a Ray ID to give them to unblock it since I did not do it in a browser. I can download it from my phone but I do so sparingly to avoid being blocked.)
The reason I have to use Downloads is because I can see it with a file browser. Also later, I will be uploading it when it is changed.
I commented the call to TableSave_Click.
I assume that is because of the No or Cancel on the Msgbox2Async as mentioned above.
I set the number of columns to 7 in the Designer.
That is nice since I can now scroll left and right.
I changed the code of the LoadTable routine.
I see your changes. Looks good to me.
I changed the column width to show all columns, the Table version allows horizontal scrolling.
Again that is nice.
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
I have attached the FTP download code as well for reference but I can't get it to call the TimTodo program correctly. I will open a new thread for that if I can't figure it out.
 

Attachments

  • TimFTPTest.zip
    8.6 KB · Views: 37
Upvote 0

klaus

Expert
Licensed User
Longtime User
I would have written the end of the Table1_CellClick routine like this:

B4X:
         'This changes the file name for the active spreadsheet throughout the whole program:
        Starter.FileName = "todo list.xls"
   
        LoadTable
'        TableSave_Click    'klaus
    Else
    End If
'    'This changes the file name for the active spreadsheet throughout the whole program:
'    Starter.FileName = "todo list.xls"
'  
'    LoadTable
'    TableSave_Click    'klaus
End Sub

Moving the last lines into to If / Then.
If Cancel or No is clicked, leave the table as it is.

I use another program to download the TodoList to DirInternal then move it to Download.
Do not confuse DirInternal with DirAssets.
DirInternal is a folder specific to the application. and not seen from any other program.
DirAssets is the projects File folder.
 
Last edited:
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
I did what you said about moving the last line into the If / Then.
The table is left alone if no or cancel is clicked.

I have not confused the folders. I use the Download folder because it makes my testing much easier. I can see and access the files in Download with other apps.

Thank you again for all the help!
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
I will open a new thread if I have to, but I thought to continue here since it is on topic.
When there are todo items close to the user, the user is notified and allowed to select which todos to view.
Then the table is completely redrawn with new content in the CloseTodos sub.
It won't scroll left and right when this happens.
I have searched the forum and can't figure out how to fix this.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I did what you said about moving the last line into the If / Then.
The table is left alone if no or cancel is clicked.
What do you mean with 'is left alone' ?
The table content remains the same, so why do you want to refill it with exactly the same content ?
Or am I missing something ?
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
If the user exits the message dialog, the table will be unchanged.
If the user selects yes to the dialog then the Todo item status will be changed to 11 which means done.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Yes, but with the original code the table is emptied and filled again with the same content, not necessary.

I have noticed that the Table class you use in this project not the latest one.
I checked the file from the forum and it was not the latest one, it is version 3.33.
Please download the latest one from the Flexible Table thread.
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
Thanks for the tip. I have fixed filling the table with the same content again.
I have downloaded the latest. Thanks for catching that.
I see that I need to watch the threads for the classes I am using so that I will be notified when they are updated.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
When I update a thread I send a post in this thread that it was updated.
Which I have just done for the Flexible Table class.

With the latest version, you can set the SingleLine property to False, instead in the code like I did.
You may also unselect the MultiSelection property.
You could also change this in the TableSave_Click routine. The HeaderNames are public in a List.
You do not need to get the label and its content.
B4X:
    'add the headers to the sheet
'    For Each lbl As Label In table1.Header
    For i = 0 To table1.NumberOfColumns - 1
        Private cell As WritableCell
'        cell.InitializeText(col, 0, lbl.Text)
        cell.InitializeText(col, 0, table1.HeaderNames.Get(i))
        cell.SetCellFormat(cellFormat)
        sheet1.AddCell(cell)
        sheet1.SetColumnWidth(col, 15)
        col = col + 1
    Next
 
Upvote 0

JudyWilson

New Member
I had a look at your project.

Some questions:
1. You are adding the Table in the Designer, but then in the LoadTable routine you remove it and add a new one by code. Why ?
You should keep it and select the needed properties directly in the Designer.
2. You have 7 columns but you display only 2, why ?
3. I do not understand what you want to do in the Table1_CellClick event routine.
When pressing any button, the last lines are executed, do you really want to do this.
For me, the Cancel button should do nothing. And what do you want to do when the No button is clicked ?

Attached you find your project modified.

I have changed some lines to make it work on my computer.
These lines have this comment at the end: 'klaus
I commented the Tracker start.
I changed the the file dir to File.DirAssets
I commented the call to TableSave_Click.
If you want to find free games and applications on mobile platforms, you can refer to the Techongame website, which is safe so you can feel secure in the experience.

I set the number of columns to 7 in the Designer.
I changed the code of the LoadTable routine.
I changed the column width to show all columns, the Table version allows horizontal scrolling.
I don't understand I watched it and everything was fine. There were no errors at all
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
Thanks for the updates.
I did as you said for singleline and multiselect. Both are not set in the designer and not the code.
Frankly I still prefer everything in the code instead of the designer. I had trouble with setting the row height because I was trying to set it in code when it is in the designer. I am learning to look in the designer because I have never used it before.

I like the change you suggested for SaveTable_Click. This way I don't have to change the Table Class each time I update it. I was having to make the Header Panel public. Now I don't have to do that.

The biggest problem I am having is that I have to call LoadArrays every time I want to fill the table. It was this way before I updated to Flex Table.
I put the TodoList list in the Starter module because it is supposed to never lose the values if it is there. But it does. Same if I put it in Process_Globals in the Main module. The entire list disappears and I have no idea why. So, I just made it so the LoadTable sub always calls the LoadArrays sub before filling the table.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
It looks strange to me that the TodoList disappears when it is declared in the Starter module or in Process_Globals ?
In the LoadArray routine you say that you load only part of the content.
Does this content change when the user runs the program or does it remain the same until he leaves the program ?
If the content does not change, I would load the list in Activity_Create, and for me this should work.
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
The content of the TodoList list is not changed.
When a user marks a todo item as done, a new spreadsheet is saved.
It will copied over the original one and the TodoList is loaded again from scratch. I have not implemented this little change in my code yet to do that.

However I changed the code to load the arrays once in Activity_Create as you suggested. The array is blank after the table is loaded the first time.
When I try to make a new table from part of the information in the TodoList list, it is blank or just the last item in the TodoList is loaded.
What is weird is that if I check the TodoList.size, it still shows the normal size.

Note that I have my request permissions in the FirstTime If / Then statement to ask for permissions before loading the TodoList from the spreadsheet since the spreadsheet resides in the Download folder.

I sure would like to not have to load the TodoList from the spreadsheet each time I change the table because it makes the code slow.
I get a message on my phone saying the app is not responding and asks me to wait or close the app.

B4A Code:
Sub Process_Globals
    Log("********Process_Globals sub start")
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Type Todo(ID As Short, Name As String, Status As Byte, Context As String, Category As Byte, Priority As Int, Note As String)
    Public Contexts(40,7) As String
    Public LastContext As Byte
    Public ExitFlag As Byte
    Public Close As Boolean
    Public NotificationAllowed As Boolean = True
    Public MenuBuilt As Boolean = False
    
    Public rp As RuntimePermissions
    Public myMap As Map
    Public WhichTodosToShow As String = "All" 'This will set the value only at the beginning of the program.
    Public TodoList As List
    Public Dir As String
    Public FileName As String
End Sub

Sub Globals
    Log("Globals sub start")
    'These global variables will be redeclared each time the activity is created.
    Public table1 As Table
    Private Statuses(12,2) As String
    Private Categories(40,2) As String
    Private HeaderRow(7) As String
    Private n As Notification = CreateNotification("Tap to Proceed.") 'This immediately calls the CreateNotification sub.
    Public Table1Header(7) As String
'    Private lblPleaseWait As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Log("Activity_Create sub started FIRST TIME")
    Activity.LoadLayout("Main")
    
    'AddMenuItems must be at the beginning of Activity_Create or they won't show
    Activity.AddMenuItem("Show Close Todos", "ShowCloseTodos")
    Activity.AddMenuItem("Leave Here", "LeaveHere")
    'Activity.AddMenuItem("Load Table", "LoadTable")
    Activity.AddMenuItem("Save Table", "TableSave")
    Activity.AddMenuItem("Allow Context Notification", "AllowContextNotification")
    Activity.AddMenuItem("Clear Context Notification", "ClearContextNotification")
    Activity.AddMenuItem("Exit Program", "ExitProgram")

    If FirstTime Then
        myMap.Initialize
        'Get access to downloads
        rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
        Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
        Log("Finished getting permission")
        If Result = False Then
            Log("No external permissions")
            Return
        End If
    
        Dir  = File.Combine(File.DirRootExternal,"Download")
        FileName = "todo list.xls"
        
        LoadArrays
    
    End If
End Sub

Sub Activity_Resume
    Log("Activity_Resume sub start")
    'Any call to Sleep() or Wait For will cause a return to the parent sub.
    Wait For (CheckAndRequestNotificationPermission) Complete (HasPermission As Boolean)
    Log("Check and Requestion Notification Permission should be complete")
    If HasPermission = False Then
        Log("no permission")
        ToastMessageShow("no permission", True)
        Return
    End If
    
    'Get access to fine location
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result Then
        StartService(Tracker)    'klaus
    Else
        ToastMessageShow("No permission...", True)
    End If
    
    'Get access to downloads
    rp.CheckAndRequest(rp.PERMISSION_WRITE_EXTERNAL_STORAGE)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    Log("Finished getting permission")
    If Result = False Then
        Log("No external permissions")
        Return
    End If
    
    'Log("WhichTodosToShow = "&WhichTodosToShow)
    Log("Calling LoadTable from Activity_Resume")
    LoadTable
End Sub
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
I just discovered that I can't remove a completed item from the TodoList. In order to do that, I would have to be able to change one item in the list, reload the table and then save the table.
I can't reload the table without reloading the TodoList from the spreadsheet first which loses the changes I made by marking the todo complete.
 
Last edited:
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
It is attached here:
 
Upvote 0
Top