Dear friends,
I am using B4XTable with inline editing , in my B4J app. For the same I need to display the row-wise sum of three columns in a fourth column. However I am unable to do so.
Without any explanation where the numbers in your table come from and without program code we cannot help you. If the numbers are read from a SQL database you could calculate the sum during the read in, or you read them out and add them up and store the result.
Apologies for not being very clear. The numbers in first three columns are entered manually. The fourth column is required to be the sum of the three columns ( row-wise) , just like the auto sum function in excel.
For example :for the first row, we input 6, 5, 4 in columns Q1(7), Q2,(7), Q3(6) respectively, then the cell in column Total(20) (in the same row) should be automatically calculated as the sum i.e; 15
I hope I am clear now.
Here is one way to do it. It works; there maybe others:
B4X:
Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
'Below code to total the first 3 cols and put in col four when you click col 4. It also updates the in memory table
If ColumnId = "TOTAL(20)" Then
Dim tot As Double
Dim m As Map=B4XTable1.GetRow(RowId)
For Each k As String In m.Keys
If k <> "TOTAL(20)" Then
tot=tot+ m.Get(k)
End If
Next
Dim c As B4XTableColumn = B4XTable1.GetColumn("TOTAL(20)")
Dim pnl As B4XView = c.CellsLayouts.Get(RowId)
Dim lbl As B4XView = pnl.GetView(0)
lbl.Text = tot
B4XTable1.sql1.ExecNonQuery2("UPDATE data SET c3 = ? WHERE rowid = ?", Array As Object(tot, RowId)) 'c3 is the 4th col
B4XTable1.Refresh
End If
End Sub
The code by Mahares works great for the first page of the table but I am getting error for the next page
CODE:
Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
'Below code to total the first 3 cols and put in col four when you click col 4. It also updates the in memory table
If ColumnId = "TOTAL(20)" Then
ie1.ExitEditMode
'ie1.CellClicked(ColumnId, RowId)
Dim tot As Double
Dim m As Map=B4XTable1.GetRow(RowId)
For Each k As String In m.Keys
If k <> "TOTAL(20)" And k<>"PRN" And k<>"ROLLNO" And k<>"NAME" Then
tot=tot+ m.Get(k)
End If
Next
Dim c As B4XTableColumn = B4XTable1.GetColumn("TOTAL(20)")
Dim pnl As B4XView = c.CellsLayouts.Get(RowId)
Dim lbl As B4XView = pnl.GetView(0)
lbl.Text = tot
B4XTable1.sql1.ExecNonQuery2("UPDATE data SET c6 = ? WHERE rowid = ?", Array As Object(tot, RowId)) 'c3 is the 4th col
B4XTable1.Refresh
Else
ie1.CellClicked(ColumnId, RowId)
End If
End Sub
ERROR LOG:
Waiting for debugger to connect...
Program started.
ok
Error occurred on line: 16 (UT1_MARKS)
java.lang.IndexOutOfBoundsException: Index: 11, Size: 11
at java.util.ArrayList.rangeCheck(ArrayList.java:659)
at java.util.ArrayList.get(ArrayList.java:435)
at anywheresoftware.b4a.objects.collections.List.Get(List.java:122)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:629)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:109)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:509)
at anywheresoftware.b4a.keywords.Common.CallSubNew3(Common.java:472)
at b4j.example.b4xtable$ResumableSub_CellClicked.resume(b4xtable.java:1726)
at b4j.example.b4xtable._cellclicked(b4xtable.java:1467)
at b4j.example.b4xtable._cell_mouseclicked(b4xtable.java:1457)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:629)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:109)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:96)
at anywheresoftware.b4j.objects.NodeWrapper$1.handle(NodeWrapper.java:109)
at anywheresoftware.b4j.objects.NodeWrapper$1.handle(NodeWrapper.java:1)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$ClickGenerator.postProcess(Scene.java:3473)
at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3401)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3769)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3488)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1765)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2497)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:397)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:434)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:411)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:433)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:941)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:185)
at java.lang.Thread.run(Thread.java:748)
That's precisely what I did! My question is that , even if the table is properly loaded , the parameter c.CellsLayouts does not reflect it.
Since I don't have any background of Java , I am unable to understand the cause.
That's precisely what I did! My question is that , even if the table is properly loaded , the parameter c.CellsLayouts does not reflect it.
Since I don't have any background of Java , I am unable to understand the cause.
The problem stemmed from the fact that when you go to a subsequent page, the index of the panel that holds the data is not the same as the rowid of the record you are totaling. The below code should now take care of that, tested and it works for all pages.
B4X:
Private MyList As List 'this line in globals
B4X:
Sub B4XTable1_CellClicked (ColumnId As String, RowId As Long)
'Below code to total the first 3 cols and put in col four when you click col 4. It also updates the in memory table
If ColumnId = "TOTAL(20)" Then
Dim tot As Double
Dim m As Map=B4XTable1.GetRow(RowId)
For Each k As String In m.Keys
If k <> "TOTAL(20)" Then
tot=tot+ m.Get(k)
End If
Next
MyList.Initialize
For i = 0 To B4XTable1.VisibleRowIds.Size - 1
Dim RId As Long = B4XTable1.VisibleRowIds.Get(i)
If RId > 0 And RId = RowId Then 'do not include -blank rows
MyList.Add(RId)
GetMyRow (RId, tot)
Exit
End If
Next
End If
End Sub
Sub GetMyRow (RowIndex As Int, t As Double)
Dim c As B4XTableColumn = B4XTable1.GetColumn("TOTAL(20)")
Dim pnl As B4XView = c.CellsLayouts.Get(MyList.IndexOf(RowIndex)+1) 'the +1 because of the header
Dim lbl As B4XView = pnl.GetView(0)
lbl.Text = t
B4XTable1.sql1.ExecNonQuery2("UPDATE data SET c3 = ? WHERE rowid = ?", Array As Object(t, RowIndex)) 'c3 is the 4th col
B4XTable1.Refresh
End Sub