Android Tutorial Converting VB6 to B4A

Discussion in 'Tutorials & Examples' started by nfordbscndrd, May 24, 2011.

  1. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    Below is a table listing features of Visual Basic 6 and their equivalents in B4A.

    If you find errors or wish to add other features, post a reply here to have your input integrated into the table (which will be updated as needed).

    This file is primarily for reference when converting Visual Basic 6 source code to B4A.
      VB6                  B4A
      ===                  ===
    controls            Views  (buttonedittextlabel, etc.)
    In the VB6 code window, the top left drop-down list contains all
    controls you have placed in the current form and the right list
    contains all the events 
    for each control.  The equivalent in B4A can
    be found by clicking on Designer - Tools - Generate Members. Once
    you have created Subs 
    in the program coding window, the tab "Modules"
    on the right side will 
    list each of the Subs.
    In B4A, you start by typing "Sub [viewName]" followed by a space and
    follow the prompts, pressing Enter after 
    each selection until B4A
    ends with 
    "EventName" highlighted. This is where you would type in
    the name of the 
    editBox = 
    string      editBox.Text = string
    In VB6, you can leave ".Text" off the names of controls when assigning
    to them, but this is not allowed in B4A.

    Dim Array(n)        Dim Array(n+1)
    While "n" is the last index number in VB6, it indicates the number
    array elements when used in B4A. For example, to Dim an array
    0-32 elements in VB6, you would say Dim A(32), while to convert
    to B4A, you need to change it to Dim A(33), yet index #33 is
    never used (doing so would cause an out-of-range error).
    ReDim Preserve      Use a 
    Array()       Dim Array(n+1) -- to clear an array, just Dim it again.
    Dim a Int: Dim b as Boolean]
    If Not b Then...    If Not(b) Then...
    If b Then...        same
    If b = True Then    same
    If a Then...        If a > 0 Then...
                           B4A does 
    not treat any non-zero value as True like VB6.
    a = a + b           
    If b = True Then a = a - 1
    's value cannot be used in a math function in B4A.
    Global Const x=1    B4A does not have a Global Const function.
    In Sub Globals, you can say   Dim x as Int: x = 1
                           but x 
    is not a constant (it's value can be changed).

    If-ThenSelect Case:
    Do [Until/While]    same
    Loop [Until/While]  Loop  [Until/While not allowed.]
    For - Next          same
    For i... - Next i   The loop variable (i) is not allowed with Next.
    Exit Do/For         Exit
    If - Then - Else    same, except VB's ElseIf is "Else If" in B4A; ditto EndIf
       ---              Continue [Skips to Next in For-Next loop]
    For i = 1 to 6        For i = 1 to 6
    If i <> 4 Then        If i = 4 Then Continue
        ...code...          ...code...
    End If                ...
    Next                  Next
    Select Case [expr]  Select [value]

    L1.BackColor =      L1.Color = 
    L1.ForeColor =      L1.TextColor = 

    Calling a 
    SubName x, y        SubName(x, y)
    Sub SubName()       Sub SubName() As Int/String/etc. -- a Global variable cannot be
                           a parameter, so say that 
    "player" is a Global variable, you
                           cannot say: PlayCard(player). Instead you have 
    to say:
                           i=player: PlayCard(i)
    Function FName()    
    Sub FName() As [var.type]
    As [var.type]       In B4A, any Sub can be used like a Function by adding a
    type such as
    Sub CheckX(x As Int) As Boolean
                                 ...optional code...
    If x = [desired value] Then Return True
                                 ...optional code...
    End Sub
    If no Return is given, then zero/False/"" is returned, but
                           the IDE will give a warning, so it 
    is better to Return 0/False/"".
                           The calling code does 
    not have to reference the returned
                           value, so that 
    while "If CheckX(x) = True..." is valid,
    is just "CheckX(x)"
    Exit Sub            Return
    Exit Function       Return [value]

    DoEvents            same, except that Erel says:
    "Calling DoEvents in a loop consumes a lot of resources and
                        it doesn't allow the system to process all waiting messages
                        properly." This was in response to my pointing out that while
                        in a Do Loop with DoEvents in it, WebView could not be loaded
    or if loaded, would not process a hyperlink click. And Agraham
    "Looping is bad practice on mobile devices. The CPU will
                        be constantly executing code and using battery power as the
                        code will never get back 
    to the OS idle loop where the hardware
    power saving measures are invoked."
    Format()            NumberFormat & NumberFormat2 [see documentation]
    InputList(Items as List, Title, CheckedItem as Int) as Int
    list multiple       Shows list of choices with radio buttons. Returns index.
    for which       CheckedItem is the default.
    the user enters a   
    InputMultiList(Items as List, Title) As List
    to choose.       User can select multiple items via checkboxes.
    list with the indexes of boxes checked.
    MsgBox "text"       MsgBox("text""title")
    MsgBox()          MsgBox2(Message, Title, Positive, Cancel, Negative, Icon) as Int
                            Displays three buttons with text 
    to display for buttons
                               (Positive, Cancel, Negative)
    is displayed near the title and is specified like:
    LoadBitmap(File.DirAssets, "[filename].gif")
    ToastMessageShow(text, b) [where b=True for long duration]
    is a Sub from Pfriemler which acts like InputBox:
    Sub InputBox(Prompt As String, Title As String, Default As String, Hint As StringAs String
    Dim Id As InputDialog
    Id.Hint = Hint
    Id.Input = Default
        ret = 
    Id.Show(Prompt, Title, "OK""","Abbrechen"Null)
    If ret = -1 Then Return Id.Input Else Return ""
    End Sub

    Rnd is < 1          Rnd(minmaxis integer >= min to < max
    Rnd(-#)             RndSeed(#) - causes Rnd to generate the same random number series
    for the same # entered.
    Not needed in B4A to randomize Rnd.
    Round(n)            same, or Round2(n, x) where x=number of decimal places

    i = Val(
    string)     If IsNumber(stringThen i = string Else i = 0 --
                        An attempt 
    to use i=string "throws an exception" if the string is
    not numbers, even if the string starts with numbers. For example,
                        t = 
                        i = Val(t) sets i=
    10 but causes an error in B4A.
                        i = t.SubString2(
    02) = 10
    control.SetFocus    view.RequestFocus
    n / 
    0 : error       n / 0 = 2147483647 -- B4A does not "throw an exception" for
                           division by 
    0, but it does return 2147483647 no matter
                           what the value of 
    "n" is.
    x = 
    Shell("...")    See "Intent". This is not a complete replacement, but allows
                           code such 
    as the following from the B4A forum (by Erel):
    Dim pi As PhoneIntents
    StartActivity (pi.OpenBrowser("[URL]file:///sdcard/yourfile.html[/URL]"))
    t = 
    Timer           t = DateTime.Now ' Ticks are number of milliseconds since 1-1-70

    In VB6, TabIndex can be set to control the order in which controls get focus
    Tab is pressed. According to Erel, in B4A:
    "Android handles the sequence according to their position. You can set
        EditText.ForceDone = True in all your EditTexts. Then catch the
    event and explicitly set the focus to the next
    view (with EditText.RequestFocus)."

    Label Transparency:
    Properties - Back Style        Designer - Drawable - Alpha

    ""                  Quote = Chr$(34)
    CRLF = Chr$(10)
    vbCrLf              none

    String "Members":
    VB6 uses a character position pointer starting with 
    B4A uses a character Index pointer starting with 
            VB6                        B4A
    "abcde"11) = "a" = letter array index 0 -- "a" = "abcde".CharAt(0)
    "abcde"21) = "b" = letter array index 1
    "abcde"31) = "c" = letter array index 2
    "abcde"41) = "d" = letter array index 3
    "abcde"51) = "e" = letter array index 4
         VB6                               B4A
         ===                               ===
    Mid$(text, n, 
    1)                    text.CharAt(n-1)
    Mid$(text, n)                       text.SubString(n-
    Mid$(text, n, x) [x=length wanted]  text.SubString2(n-
    1, n+x-1) [n+x-1=end position]
    Mid$(text, n, x) = text2            text = text.SubString2(
    0, n-2) & _
    0, x-1) & _
    1 + z)  where...
                                                 z = 
    Min(x, text2.length)
    Left$(text, n)  [n=num.of chars.]   text.SubString2(
    0, n)
    Right$(text, n)                     text.SubString(text.Length - n + 
    If a$ = b$...                       If a.CompareTo(b)...
    If Right$(text, n) = text2...       If text.EndsWith(text2)...
    If Left$(text, n) = text2...        If text.StartsWith(text2)...
    If Lcase$(text) = Lcase$(text2)...  If text.EqualsIgnoreCase(text2)...
    Following are some subs from NeoTechni which take the place of VB6
    string functions:
    Sub Left(Text As String, Length As Long)As String
    If length>text.Length Then length=text.Length
    Return text.SubString2(0, length)
    End Sub
    Sub Right(Text As String, Length As Long) As String
    If length>text.Length Then length=text.Length
    Return text.SubString(text.Length-length)
    End Sub
    Sub Mid(Text As String, Start As Int, Length As Int) As String
    Return text.SubString2(start-1,start+length-1)
    End Sub
    Sub Split(Text As String, Delimiter As StringAs String()
    Return Regex.Split(delimter,text)
    End Sub

    x = Len(text)                       x = text.Length
    text = Replace(text, str, str2)     text.Replace(str, str2)
    Lcase(text)                         text.ToLowerCase
    Ucase(text)                         text.ToUpperCase
    Trim(text)                          text.Trim
      (no LTrim 
    or RTrim in B4A)
    string)                 text.IndexOf(string)
    Instr(int, text, 
    string)            text.IndexOf2(string, int)
                                           Returns -
    1 if not found.
                                           Returns char. index, 
    not position.
                                           Starts search at 
    InStrRev(text, str, start, 
    case)    text.LastIndexOf(string)
      Searches from 
    end of string,      text.LastIndexOf(string, start)
        optionally from 
    "start".           Cannot specify case sensitivity.
    case = 0 = case-sensitive
    case = 0 = case-insensitive
                                        A boolean 
    form of IndexOf is -
    If text.Contains(string) = True Then...
    If Lcase$(x) = Lcase$(y)...         If x.EqualsIgnoreCase(y)...
    text = Left$(text, n) & s &         text.Insert(n, s)
              Right$(Text, y)
    Asc(s) [where s = a character]      same

    Error Trapping:
    Sub SomeSub
       On [Local] Error GoTo ErrorTrap
          ...some code...
       On Error GoTo 
    0 [optional end to error trapping]
       ...optional additional code...
    Exit Sub [to avoid executing ErrorTrap code]
       ...optional code 
    for error correction...
       Resume [optional: 
    "Resume Next" or "Resume [line label]".
    End Sub
    Sub SomeSub
          ...some code...
    Catch [only executes if error above]
    Log(LastException) [optional]
          ...optional code 
    for error correction...
    End Try
       ...optional additional code...
    End Sub
    WIth B4A, 
    if you get an error caught in the middle of a large subroutine, you can
    NOT make a correction and resume within the code you were executing. Only the code
    in "Catch" gets executed, plus any code following "End Try".
    Try-Catch in place of GoTo:
    Try-Catch can be used as a substitute for GoTo [line labelfor forward, but not
    backward, jumps. It cannot be used 
    to replace GoSub, for which B4A has no equivalent.
    Start the code with 
    "Try" and replace the [line label] with "Catch".
    "GoTo [line label]" with code which will create an exception, which causes
    a jump 
    to "Catch", such as OpenInput("bad path""bad filename").

    "Immediate Window" vs "Logs" Tab
    Comments, variable values, etc., can be displayed 
    in VB6's Immediate
    Window by entering into the code "Debug.Print ...".
    In the B4A environment, the Logs tab on the right side of the IDE is a
    to show the values of variables, etc., while the code is running.
    Both VB6 
    and (now) B4A allow single-stepping through the code while it
    is running and viewing the values of variables. VB6 also allows changing
    the value of variables, changing the code, jumping 
    to other lines from
    the current line, etc. Because B4A runs on a PC 
    while the app runs on
    a separate device, B4A 
    is currently unable to duplicate all of these
    VB6 debug features.
    Last edited: Aug 11, 2013
  2. Erel

    Erel Administrator Staff Member Licensed User

    Thank you very much.
    mjnadev and LiuDong like this.
  3. SoyEli

    SoyEli Active Member Licensed User

    VB6 to B4A

    Thank You:)
    Thank You:)
    Thank You:sign0087:

    Verry Helpful

    PLEASE more more more :)
  4. NeoTechni

    NeoTechni Well-Known Member Licensed User

    The redim preserve (a very advantageous feature of VB) equivalent is to switch to a list

    Vbnewline in VB is CRLF in B4A

    ---              Continue [Skips to Next in For-Next loop]
    For i = 1 to 6        For i = 1 to 6
    If i = 4 Then         If i = 4 Then Continue
        ...code...          ...code...
    End If                ...
    Next                  Next
    Those dont appear to be equivalent.
    Shouldn't "If i = 4 Then Continue" skip that iteration, where the VB side only runs on 4?

    InputBox($)         InputList(Items as List, Title, CheckedItem as Int) as Int
    list of choices with radio buttons. Returns index.
    is the default.
    InputMultiList(Items as List, Title) As List
                            Usere can 
    select multiple items via checkboxes.
    list with the indexes of boxes checked.
    Those definitely aren't equivalent. Inputbox is to input a string, not a multiple choice question
    I think I had to use the dialog library to get an inputbox equivalent
    Last edited: May 25, 2011
  5. Pfriemler

    Pfriemler Member Licensed User

    You're right. A way to skip an iteration in VB6 is to change the loop variable. "If i=4 then i=5" (pay attention to the right stepping in the for-Statement) is equivalent to "Continue" in B4A. As this looks a bit ungly in VB6, it is an advantage to B4A.

    I got me a little substition using the DIALOG library. Unfortunatly, there's no way to overload the SUB, so you have to pass all Parameters in B4A.

    Sub InputBox(Prompt As String, Title As String, Default As String, Hint As StringAs String
    Dim Id As InputDialog
    Id.Hint = Hint
    Id.Input = Default
       ret = 
    Id.Show(Prompt, Title, "OK""","Abbrechen"Null)
    If ret = -1 Then Return Id.Input Else Return ""
    End Sub
    Maybe there's a way to adapt the Button Labels ...
  6. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    I'll add that tip. Thanks.

    Both vbCrLf and vbNewLine are Chr$(13) & Chr$(10).
    CRLF in B4A, which acts like VB6's vbCr, is just Chr$(10):

    That was a brain fart. The VB6 code should be:
    "If i <> 4 Then"

    I believe that I was thinking more of the button options in MsgBox rather than InputBox.

    OTOH, I've used InputBox for multiple choice many times in VB6 programs.

    response = InputBox("The WordID-POS entered has these Type-Of entries:" & _
                        vbCr & EntryList$ & vbCr & _ 
    "Enter the ID# of the entry to use or press Enter" & vbCr & _
    "to use the original entry ID# you entered:",,Default$)
    which might look something like this when the program runs:
    The WordID-POS entered has these Type-Of entries:
    09300 type-of entry 0
    10020 type-of entry 1
    10734 type-of entry 2
    Enter the 
    ID# of the entry to use or press Enter
    to use the original entry ID# you entered:
    In B4A, I would convert this to:
    response = InputList(EntryList [as List], "Enter the ID# to use...",  1)
    where instead of entering the number, the user could click a radio button.

    However, this doesn't really answer the question of how to replace InputBox with something similar in B4A for getting string input (rather than making simple choices), and due to a combination of lack of sleep and still being a noobie, it's not coming to me right now. Can someone help me out with that? If not, I'll research it later.
  7. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    I meant to say "If i <> 4 Then". Changing that to "If i = 4 Then Continue" in B4A is actually an optional change because the If-Then from VB6 works fine and IMO is easier to follow, though that may be because I'm not as accustomed yet to "Continue".

    Thanks. If nobody has a more direct equivalent, I'll change the table to reference your message.
  8. Pfriemler

    Pfriemler Member Licensed User

    I agree - I only tried to find a VB6 equivalent code for B4A's "Continue". In fact, no one should change the loop in this way. If-then is definitly better.

    I think it would be a great idea to have a more or less complete VB6/eVB-to-B4A translation help (I think that embeddedVisualBasic, which I used for a long time, is quite similar to VB6) in the new WIKI. Your Table is a very good base for it.

    My version of InputBox is quite enough for a quick&dirty programming during the test period of a program. In fact, such dialog is not really what Android progs normally looks like (AFAIK).

    And with the other post of you: Regarding InputBox as a editable radio button input: I also have a code which couples a radio button choice with a last option to enter a new text, which just pops the inputbox. Works fine. Next stage is to integrate a EditText view and a radio choice to the panel in DIALOG's CustomDialog(2).
  9. NeoTechni

    NeoTechni Well-Known Member Licensed User

    I've been rewriting subs since I'm used to the VB way


    Sub Left(Text As String, Length As Long)As String 
    If length>text.Length Then length=text.Length 
    Return text.SubString2(0, length)
    End Sub

    Sub Right(Text As String, Length As Long) As String
    If length>text.Length Then length=text.Length 
    Return text.SubString(text.Length-length)
    End Sub

    Sub Mid(Text As String, Start As Int, Length As Int) As String 
    Return text.SubString2(start-1,start+length-1)
    End Sub

    Sub Split(Text As String, Delimiter As StringAs String()
    Return Regex.Split(delimter,text)
    End Sub
  10. Lordshiva1948

    Lordshiva1948 Member Licensed User


    Thank you very much:sign0098:
  11. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    Updated file (in the original post), mainly for a couple of new functions in B4A 1.6: String.Contains, String.LastIndexOf(2), and RndSeed.
    Last edited: Jul 22, 2011
  12. Kim Rowden

    Kim Rowden Member Licensed User

    Errors in VB6 conversion table

    I see lots of discussion about "If-then" and chr$(13) in the VB6 conversion chart... which is good...

    but the errors don't seem to have been removed from the chart. Any reason why?

    As Erel pointed out in another post: the equivalent of VB6's vbCRLF is simply CRLF in B4A. And if you want to define it yourself it should be:
    myCRLF = chr(10)
    ...NOT the chr$(13) as posted many times elsewhere.

  13. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    Thanks. I've just uploaded the latest file to the original post.
  14. Kim Rowden

    Kim Rowden Member Licensed User

    Thanks... and sorry for coming back again on this but perhaps the CR/LF portion of the chart for "Constants" should simply read:

    vbCRLF CRLF = Chr(10) this is probably the real conversion required (the vbCR is typically not used).

    NOTE: there should NOT be a '$' in the chr() function in B4A usage.

    It took me a couple of iterations before I realised the chart was incorrect... ;)

  15. nfordbscndrd

    nfordbscndrd Well-Known Member Licensed User

    Since CRLF is a constant, the line you are referring to was just meant to indicate that CRLF in B4A is equivalent to CHR$(10) in VB6.

    Actually, though Erel has said that CRLF is just a Chr$(10) (or Chr(10) or whatever), the whole thing is kind of confusing because some programs in Windows, such as Notepad, treat a linefeed character as both a line feed and carriage return while others do not and just show a symbol for the ASCII-10 in the middle of the line.

    Logically, since CHR$(10) is just a line feed:
    "This is the first line." & CHR$(10) & "This is the 2nd line."
    should appear as

    This is the first line.
    is the second line.
    Meanwhile, if instead of CHR$(10) it was CHR$(13) (carriage return), then the cursor (or printer) should simply return to the start of the first line and overwrite it with the second line. Since neither of these results are desirable, some software fudges and treats a CHR$(10) and CHR$(13) & CHR$(10) the same.
    Last edited: Aug 13, 2011
  16. Kim Rowden

    Kim Rowden Member Licensed User

    Yes - I would agree it can be a little confusing at times...

    I simply take the approach that in VB a vbCRLF will get me the CR and the LF needed to do the carriage return and line feed to get to the begining of a new line (in, say, a message box) - while in Unix-land I only need the "\n", hence:

    chr$(13) & chr$(10), or vbCRLF, in VB map to chr(10), or CRLF, in B4A

  17. agraham

    agraham Expert Licensed User

    Linefeed as a new line indicator is standard for Unix and so Linux on which Android is based. Carriage return and linefeed is standard for MSDOS and so Windows. Pehaps the difference arose because DOS (and I!) started on Teletype machines that needed a CR to return the print head and a LF to advance the paper. Maybe the Unix guys could afford better line-at-a-time drum or belt printers that had no need for a CR. :)
    David S likes this.
  18. Hubert Brandel

    Hubert Brandel Active Member Licensed User


    I have just red about chr(13) and Android (Linux), I have to work with and build to CSV files from and for Win32 systems.
    Does this mean, that I can't use WriteLine() from the textwriter and have to
    write( cTextLine1+chr(13)+chr(10) )
    write( cTextLine2+chr(13)+chr(10) ) ?

    Does the "\" from Windowsdirectorys have to be "/" ?
  19. Hubert Brandel

    Hubert Brandel Active Member Licensed User

    I found that the syntax of Basic4ppc is very different from Basic4Android, this is strange too ;-)
  20. varayut

    varayut Member Licensed User

    Great ! That's very useful for me. Thank you and please do more.