Android Question How do you put several If statements into a for loop?

BTNorthrup

Member
Licensed User
Longtime User
Hello! I have a finance app I'm working on. Currently, everything works just fine. However, I would like to put these statements into a for loop if possible:

B4X:
        If IsNumber(Payment1.Text) = False OR Payment1.Text < 0 Then
            Msgbox("Please use only positive numbers and up to one decimal.","Error!")
        Else
        If IsNumber(Payment2.Text) = False OR Payment2.Text < 0 Then
            Msgbox("Please use only positive numbers and up to one decimal.","Error!")
        Else
        If IsNumber(Payment3.Text) = False OR Payment3.Text < 0 Then
            Msgbox("Please use only positive numbers and up to one decimal.","Error!")
        Else

There are going to be 120 of these labels total (Called Payment1 - Payment120). I wouldn't have any problems just using tons of repetitive code, but there has to be a simpler way. All of them are going to be put into a vertical scrollview if that makes any difference to how the for loop would work. Thank you!
 

klaus

Expert
Licensed User
Longtime User
You should use an array dimed in Globals like:
Dim Payment(120) As EditText
Then you can use a loop and access each EditText with its Index.
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Put these 120 edits in a list and iterate through this list.

Please note the code is a quick&dirty hack based on CLV-Tutorial

B4X:
Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Private clv As CustomListView
    Private editsList As List
    Private btncheck As Button
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("main")
    editsList.Initialize
    For i = 1 To 120
        clv.Add(CreateListItem(i, "Item #" & i, clv.AsView.Width, 50dip), 50dip, "Item #" & i)
    Next
    Log("editsMap has "&editsList.Size&" entries")

End Sub
Sub CreateListItem(index As Int,Text As String, Width As Int, Height As Int) As Panel
    Dim p As Panel
    p.Initialize("")
    p.Color = Colors.Black
    Dim b As Button
    b.Initialize("button") 'all buttons click events will be handled with Sub Button_Click
    b.Tag = index
    b.Text = Text
    Dim edt As EditText
    edt.Initialize("edit")
    edt.Text = index
    edt.Tag = "#"&index
    editsList.Add(edt)
    p.AddView(edt, 10dip, 2dip, 150dip, Height - 4dip) 'view #1
    p.AddView(b, 160dip, 2dip, 100dip, Height - 4dip) 'view #2
    Return p
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub clv_ItemClick (Index As Int, Value As Object)
  
End Sub

Sub button_Click
    Dim b As Button = Sender
    Log("Button "&b.Tag&" clicked...")
End Sub
Sub btncheck_Click
    For i = 0 To editsList.Size-1
        Dim Payment As EditText = editsList.Get(i)
        If IsNumber(Payment.Text) = False OR Payment.Text < 0 Then
            Log("Edit # "&Payment.Tag&":Please use only positive numbers and up to one decimal.")
        End If
    Next
End Sub
 

Attachments

  • 120editsTest.zip
    10 KB · Views: 68
Last edited:
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
An array would work just fine, but something like this would probably benefit more with a list. Then you can iterate through the items with
For Each Payment As typePayment In PaymentList
...process payment here
Next
 
Upvote 0

mc73

Well-Known Member
Licensed User
Longtime User
From what I see in your code, perhaps I would use IME in order to filter each editText view, setting just numbers and dot accepted and then checking user's response in the corresponding IME sub. Have a look here.
 
Upvote 0

James Chamblin

Active Member
Licensed User
Longtime User
For i = 0 To editsList.Size-1
Dim Payment As EditText = editsList.Get(i)
If IsNumber(Payment.Text) = False OR Payment.Text < 0 Then
Log("Edit # "&Payment.Tag&":please use only positive numbers and up to one decimal.")
End If
Next
It may be best to add an Exit in there to stop processing when an error is detected.
B4X:
    For Each Payment As EditText In editsList 'loops through each Payment in the list
        If IsNumber(Payment.Text) = False OR Payment.Text < 0 Then 'Checks if valid
            Log("Edit # "&Payment.Tag&":Please use only positive numbers and up to one decimal.")
            Exit 'abort loop when an error is detected
        End If
    Next
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
From what I see in your code, perhaps I would use IME in order to filter each editText view, setting just numbers and dot accepted and then checking user's response in the corresponding IME sub. Have a look here.

I agree. You should use InputType.

Also, if for example the type of validation was different, you could execute it in the event FocusChanged of EditTexts or create an event ItemFocusChanged, thinking that each Item is a panel that contains some views, validating the entire Item (uhm, I hope this is clear enough).
 
Last edited:
Upvote 0

BTNorthrup

Member
Licensed User
Longtime User
Awesome! I used klaus' idea to reference each index. Works perfectly! And thank you for the suggestions guys, that's very helpful. You answered my next question, which had to do with InputType. :) If something with the array has some sort of issue later on, I'll try out the List instead.
 
Last edited:
Upvote 0
Top