B4J Question Compare two lsist based on a list specified value

NewB4JUser

Member
Licensed User
Hi, i have two lists, and i want to cross reference them. The first only has 15 values and i want to take each value and lookup if it exists in the other lists that has 500 values and if it does i would like to cause a checkbox on a form to beocme ticked.

Have tried this but keeps crashing and can't see why?

Any ideas please?

My code:

Sub CheckForMatchingValues
Dim SearchList As List
Dim DataList As List

' Initialize lists
SearchList .Initialize
DataList.Initialize

' Test data
SearchList.AddAll(Array As Int("2", "33", "C19"))
DataList.AddAll(Array As int("2", "7", "489", "78", "33", "0", "1"))

' Uncheck checkbox first
RationalDataMapping.Checked = False

' Loop through List1
For Each item In SearchList
If DataList.IndexOf(item) > -1 Then
RationalDataMapping.Checked = True
Exit ' Stop if a match is found
End If
Next
End Sub
 

Daestrum

Expert
Licensed User
Longtime User
Not going to work
B4X:
SearchList.AddAll(Array As Int("2", "33", "C19"))
C19 is not an Int

change to
B4X:
SearchList.AddAll(Array("2", "33", "C19"))
 
Upvote 0

NewB4JUser

Member
Licensed User
I am trying to search from one list which has 15 values against another list that has 200 values, when a value is found i want to go to another form and highlight the label background on another form, but i keep getting errors, do i need to set focus.

this is the code:
Dim LookVal() As String = Array (Clbl1.Text, Clbl2.Text, Clbl15.Text, Clbl7.Text, Clbl9.Text, Clbl12.Text, Clbl14.Text, Clbl15.Text, Clbl17.Text, Clbl18.Text, Clbl20.Text, Clbl22.Text, Clbl24.Text, Clbl25.Text)

Dim FVal() = Array(ExeptionList)

Dim X As Int = 0



ExeptionList.Initialize
Vlist.Initialize

For i = 0 To 14

Do Until i = 0 To 200


If LookVal(X) = FVal(I) Then
Log("Found number" & X & "in panel")
clbl(X).color = 0xFF46FF00
End If


I = I + 1

Loop

X = X + 1
Next
 
Upvote 0

NewB4JUser

Member
Licensed User
Great thanks emexes. I actually do only have unique values, so there should and will never be an duplicates, so will take a look at the mapping fuction. Are lists limted to capacity limitations, i.e only maximum of 500 values?

I do want to cross reference eventually a imported spreadsheet with over 10,000 values. again each unique to a row, that will be searched, but duplicates integeres willl exists in other rows, but guess that is fine, as each row acts as list as such. Would Mapping be the best for this or i was reading abour listviews?

I'll see how mapping works will try now and no doubt i'll need help with it.

Thanks
 
Upvote 0

NewB4JUser

Member
Licensed User
Hi, this is my code, but still cant get it to work, am i mssing something simple:

For i = 0 To 15


Do Until Y = 60

If LookFor.GetValueAt(X) = SearchValue.GetValueAt(Y) Then

Log("Found a match" & SearchValue.GetValueAt(Y))

Else

Y = Y + 1
Log("Not Found " & SearchValue)
End If



Loop


X = X + 1


Next

Results:

Not Found (MyMap) {1=, 2=2, 3=, 4=4, 5=, 6=6, 7=, 8=, 9=9, 10=, 11=11, 12=, 13=, 14=14, 15=, 16=16, 17=, 18=, 19=19, 20=20, 21=21, 22=22, 23=23, 24=24, 25=25, 26=26, 27=27, 28=29, 29=, 30=30, 31=, 32=, 33=, 34=, 35=, 36=, 37=37, 38=, 39=, 40=, 41=41, 42=, 43=43, 44=, 45=45, 46=, 47=, 48=, 49=49, 50=, 51=, 52=52, 53=, 54=54, 55=55, 56=, 57=57, 58=, 59=, 60=60, 61=61, 62=, 63=63, 64=64, 65=65, 66=, 67=, 68=, 69=, 70=, 71=, 72=72, 73=, 74=74, 75=, 76}
Not Found (MyMap) {1=, 2=2, 3=, 4=4, 5=, 6=6, 7=, 8=, 9=9, 10=, 11=11, 12=, 13=, 14=14, 15=, 16=16, 17=, 18=, 19=19, 20=20, 21=21, 22=22, 23=23, 24=24, 25=25, 26=26, 27=27, 28=29, 29=, 30=30, 31=, 32=, 33=, 34=, 35=, 36=, 37=37, 38=, 39=, 40=, 41=41, 42=, 43=43, 44=, 45=45, 46=, 47=, 48=, 49=49, 50=, 51=, 52=52, 53=, 54=54, 55=55, 56=, 57=57, 58=, 59=, 60=60, 61=61, 62=, 63=63, 64=64, 65=65, 66=, 67=, 68=, 69=, 70=, 71=, 72=72, 73=, 74=74, 75=, 76}

All i want is to find the first value in my LookFor map (1: clbl1, 2: clcbl2, 3: clbl3) - text values

and then if it conatins in my second map SearchIn (1: label1, 2: label2, 3: label3) co-ordinates in each label

If 1: clbl.text = label3.text then
checkbox = true

but cant seem to get it to work, and changed the code........still new to this, but can you advise please?
 
Upvote 0

emexes

Expert
Licensed User
Longtime User
I had to format the code to see more easily what it is doing.

The highlighted lines are the ones that probably need attention.

B4X:
Dim LookVal() As String = Array (Clbl1.Text, Clbl2.Text, Clbl15.Text, Clbl7.Text, Clbl9.Text, Clbl12.Text, Clbl14.Text, Clbl15.Text, Clbl17.Text, Clbl18.Text, Clbl20.Text, Clbl22.Text, Clbl24.Text, Clbl25.Text)

Dim FVal() = Array(ExeptionList)

Dim X As Int = 0

ExeptionList.Initialize
Vlist.Initialize

For i = 0 To 14
    Do Until i = 0 To 200
        If LookVal(X) = FVal(I) Then
            Log("Found number" & X & "in panel")
            clbl(X).color = 0xFF46FF00
        End If
        I = I + 1
    Loop

    X = X + 1
Next
 
Last edited:
Upvote 0

NewB4JUser

Member
Licensed User
Sorry disregard that data.

Ultimatley i am looking to search two maps one with 15 values in it, these are unique numbers from 1- 15 and all i want is to search the second map and if the value is found then cause a tickbox to tick. But i cant get my head around these maps.
 
Upvote 0

Peter Meares

Member
Licensed User
Longtime User
I would have used lists and done it like this. No limit to list sizes. I use this type of search on several 100,000 items quite often.

B4X:
Sub Process_Globals
    Dim SearchList As List
    Dim DataList As List
End Sub

Sub AppStart (Args() As String)
    
    ' Initialize lists
    SearchList .Initialize
    DataList.Initialize

    ' Test data
    ' These are strings
    SearchList.AddAll(Array As String("2", "33", "C19"))
    DataList.AddAll(Array As String("2", "7", "489", "78", "33", "0", "1"))
    
    For Each strItem As String In DataList
        If Search(SearchList, strItem) = True Then
            Log($"Found ${strItem} in the list"$)
        Else
            Log($"Not Found ${strItem} in the list"$)
        End If
    Next
    
End Sub

Private Sub Search(Haystack As List, Needle As String) As Boolean
    
    For Each xstr As String In Haystack
        If xstr = Needle Then
            Return True
        End If
    Next

Return False
    
End Sub
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
I have written a full example (needs JavaObject library) Layout has 1 button (Button1) and two ListViews (ListView1 and ListView2)
(After I wrote it I realised its a bit advanced, but none the less you should be able to understand it)
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    Private Button1 As B4XView
    Private ListView1 As ListView
    Private ListView2 As ListView
    Dim search As List = Array("2", "33", "C19")
    Dim DataList As List = Array("2", "7", "489", "78", "33", "0", "1")
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    'build the lists and put into listviews
    For Each item In search
        listview1Add(item)
    Next
    For Each item In DataList
        ListView2.Items.Add(item)
    Next
End Sub

Sub Button1_Click
    'search for the items
    For Each item In ListView1.Items
        'funky line explanation
        'get the checkbox in the item and set if item.label.text is in listview2 using contains (of arraylist) it returns True or False
        item.as(Pane).GetNode(0).As(CheckBox).Checked = ListView2.Items.As(JavaObject).RunMethod("contains",Array(item.As(Pane).GetNode(1).As(Label).text))
    Next
End Sub

Sub listview1Add(str As String)
    'helper to add the pane.checkbox.label to listview items
    Dim p As Pane
    p.Initialize("P")
    Dim chk As CheckBox
    chk.Initialize("CHK")
    Dim lab As Label
    lab.Initialize("LAB")
    lab.Text = str
    p.AddNode(chk,10,0,20,20)
    p.AddNode(lab,40,0,60,20)
    ListView1.Items.Add(p)
End Sub

When you click the button the checkbox(s) will be set if the value is in listview2
 
Upvote 0

NewB4JUser

Member
Licensed User
I have written a full example (needs JavaObject library) Layout has 1 button (Button1) and two ListViews (ListView1 and ListView2)
(After I wrote it I realised its a bit advanced, but none the less you should be able to understand it)
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    Private Button1 As B4XView
    Private ListView1 As ListView
    Private ListView2 As ListView
    Dim search As List = Array("2", "33", "C19")
    Dim DataList As List = Array("2", "7", "489", "78", "33", "0", "1")
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    'build the lists and put into listviews
    For Each item In search
        listview1Add(item)
    Next
    For Each item In DataList
        ListView2.Items.Add(item)
    Next
End Sub

Sub Button1_Click
    'search for the items
    For Each item In ListView1.Items
        'funky line explanation
        'get the checkbox in the item and set if item.label.text is in listview2 using contains (of arraylist) it returns True or False
        item.as(Pane).GetNode(0).As(CheckBox).Checked = ListView2.Items.As(JavaObject).RunMethod("contains",Array(item.As(Pane).GetNode(1).As(Label).text))
    Next
End Sub

Sub listview1Add(str As String)
    'helper to add the pane.checkbox.label to listview items
    Dim p As Pane
    p.Initialize("P")
    Dim chk As CheckBox
    chk.Initialize("CHK")
    Dim lab As Label
    lab.Initialize("LAB")
    lab.Text = str
    p.AddNode(chk,10,0,20,20)
    p.AddNode(lab,40,0,60,20)
    ListView1.Items.Add(p)
End Sub

When you click the button the checkbox(s) will be set if the value is in listview2
Thank you. The form that houses the check box is loaded from the main form on a button click, and i w
I would have used lists and done it like this. No limit to list sizes. I use this type of search on several 100,000 items quite often.

B4X:
Sub Process_Globals
    Dim SearchList As List
    Dim DataList As List
End Sub

Sub AppStart (Args() As String)
  
    ' Initialize lists
    SearchList .Initialize
    DataList.Initialize

    ' Test data
    ' These are strings
    SearchList.AddAll(Array As String("2", "33", "C19"))
    DataList.AddAll(Array As String("2", "7", "489", "78", "33", "0", "1"))
  
    For Each strItem As String In DataList
        If Search(SearchList, strItem) = True Then
            Log($"Found ${strItem} in the list"$)
        Else
            Log($"Not Found ${strItem} in the list"$)
        End If
    Next
  
End Sub

Private Sub Search(Haystack As List, Needle As String) As Boolean
  
    For Each xstr As String In Haystack
        If xstr = Needle Then
            Return True
        End If
    Next

Return False
  
End Sub
Thanks Peter, this worked great after changing the names to match my list names. However, this procedure runs before a form is loaded and the relevant strings are popuated before the form is loaded, and so the checkboxes do not become true, is there a quick way of resolving this?
 
Upvote 0

NewB4JUser

Member
Licensed User
I have written a full example (needs JavaObject library) Layout has 1 button (Button1) and two ListViews (ListView1 and ListView2)
(After I wrote it I realised its a bit advanced, but none the less you should be able to understand it)
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    Private Button1 As B4XView
    Private ListView1 As ListView
    Private ListView2 As ListView
    Dim search As List = Array("2", "33", "C19")
    Dim DataList As List = Array("2", "7", "489", "78", "33", "0", "1")
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    'build the lists and put into listviews
    For Each item In search
        listview1Add(item)
    Next
    For Each item In DataList
        ListView2.Items.Add(item)
    Next
End Sub

Sub Button1_Click
    'search for the items
    For Each item In ListView1.Items
        'funky line explanation
        'get the checkbox in the item and set if item.label.text is in listview2 using contains (of arraylist) it returns True or False
        item.as(Pane).GetNode(0).As(CheckBox).Checked = ListView2.Items.As(JavaObject).RunMethod("contains",Array(item.As(Pane).GetNode(1).As(Label).text))
    Next
End Sub

Sub listview1Add(str As String)
    'helper to add the pane.checkbox.label to listview items
    Dim p As Pane
    p.Initialize("P")
    Dim chk As CheckBox
    chk.Initialize("CHK")
    Dim lab As Label
    lab.Initialize("LAB")
    lab.Text = str
    p.AddNode(chk,10,0,20,20)
    p.AddNode(lab,40,0,60,20)
    ListView1.Items.Add(p)
End Sub

When you click the button the checkbox(s) will be set if the value is in listview2
Thanks you for this. Really appreciate it.
 
Upvote 0

NewB4JUser

Member
Licensed User
I have written a full example (needs JavaObject library) Layout has 1 button (Button1) and two ListViews (ListView1 and ListView2)
(After I wrote it I realised its a bit advanced, but none the less you should be able to understand it)
B4X:
Sub Process_Globals
    Private fx As JFX
    Private MainForm As Form
    Private xui As XUI
    Private Button1 As B4XView
    Private ListView1 As ListView
    Private ListView2 As ListView
    Dim search As List = Array("2", "33", "C19")
    Dim DataList As List = Array("2", "7", "489", "78", "33", "0", "1")
End Sub

Sub AppStart (Form1 As Form, Args() As String)
    MainForm = Form1
    MainForm.RootPane.LoadLayout("Layout1")
    MainForm.Show
    'build the lists and put into listviews
    For Each item In search
        listview1Add(item)
    Next
    For Each item In DataList
        ListView2.Items.Add(item)
    Next
End Sub

Sub Button1_Click
    'search for the items
    For Each item In ListView1.Items
        'funky line explanation
        'get the checkbox in the item and set if item.label.text is in listview2 using contains (of arraylist) it returns True or False
        item.as(Pane).GetNode(0).As(CheckBox).Checked = ListView2.Items.As(JavaObject).RunMethod("contains",Array(item.As(Pane).GetNode(1).As(Label).text))
    Next
End Sub

Sub listview1Add(str As String)
    'helper to add the pane.checkbox.label to listview items
    Dim p As Pane
    p.Initialize("P")
    Dim chk As CheckBox
    chk.Initialize("CHK")
    Dim lab As Label
    lab.Initialize("LAB")
    lab.Text = str
    p.AddNode(chk,10,0,20,20)
    p.AddNode(lab,40,0,60,20)
    ListView1.Items.Add(p)
End Sub

When you click the button the checkbox(s) will be set if the value is in listview2
Hey I used this code and all works fine. only now i am getting the following errors and not sure how to solve it.

main.initializeProcessGlobals (java line: 3350)
java.lang.RuntimeException: java.lang.RuntimeException: Object should first be initialized (B4XView).
at b4j.example.main.initializeProcessGlobals(main.java:3350)
at b4j.example.main.start(main.java:34)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:847)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:484)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:457)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:456)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
at java.base/java.lang.Thread.run(Thread.java:1589)
Caused by: java.lang.RuntimeException: Object should first be initialized (B4XView).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:49)
at anywheresoftware.b4a.objects.B4XViewWrapper.getNodeObject(B4XViewWrapper.java:123)
at anywheresoftware.b4a.objects.B4XViewWrapper.getColor(B4XViewWrapper.java:604)
at b4j.example.main._process_globals(main.java:4154)
at b4j.example.main.initializeProcessGlobals(main.java:3345)
... 10 more

how would I identify the error as cant see code at that number line?
 
Upvote 0
Top