Consulting

Results 1 to 13 of 13

Thread: Putting a mid function into a loop

  1. #1
    VBAX Newbie
    Joined
    May 2012
    Location
    Berlin
    Posts
    3
    Location

    Putting a mid function into a loop

    Hello there!

    I have recently started learning VBA in IT classes and I have an assignment to create a function that converts a 64-digit binary number into a hexadecimal number.

    This was my idea:
    -Create a sting that is defined by an input box
    -Check the length of the string and create an error report if it has less than 64 digits
    (And now comes the part that I'm having trouble with)
    -Use the mid function to split the binary number into 16 parts each containing four digits
    -Define a hexadecimal digit for each possible combination of the four digits
    The thing I'm having trouble with is putting it in a loop.
    The VBA editor tells me that the types are not compatible and selects the "For StrPart = Mid (BinZahl, 4, 4) To..."

    Here is my attempt.
    It would be great if some one could tell me what I am doing wrong and/or give me a hint on how to get it to work without having to type out each part of the binary individually.
    PS the German in the code is because I am living in Germany, but I don't think it should be too confusing

    Thanks in advance

    [VBA]Public Sub BinHexCalc()
    Dim BinZahl As String
    BinZahl = InputBox("Bitte geben Sie eine 64-stellige Binärzahl ein.")
    Dim HexZahl As String
    Dim iLen As Integer
    Dim strPart As String
    iLen = Len(BinZahl)
    If iLen < 64 Then
    MsgBox ("Ihre Zahl hat weniger, als 64 Stellen")
    End If

    For strPart = Mid(BinZahl, 4, 4) To Mid(BinZahl, 64, 4) Step -4

    If strPart = "0000" Then
    HexZahl = "0" + HexZahl
    End If

    If strPart = "0001" Then
    HexZahl = "1" + HexZahl
    End If

    If strPart = "0010" Then
    HexZahl = "2" + HexZahl
    End If

    If strPart = "0011" Then
    HexZahl = "3" + HexZahl
    End If

    If strPart = "0100" Then
    HexZahl = "4" + HexZahl
    End If

    If strPart = "0101" Then
    HexZahl = "5" + HexZahl
    End If

    If strPart = "0110" Then
    HexZahl = "6" + HexZahl
    End If

    If strPart = "0111" Then
    HexZahl = "7" + HexZahl
    End If

    If strPart = "1000" Then
    HexZahl = "8" + HexZahl
    End If

    If strPart = "1001" Then
    HexZahl = "9" + HexZahl
    End If

    If strPart = "1010" Then
    HexZahl = "A" + HexZahl
    End If

    If strPart = "1011" Then
    HexZahl = "B" + HexZahl
    End If

    If strPart = "1100" Then
    HexZahl = "C" + HexZahl
    End If

    If strPart = "1101" Then
    HexZahl = "D" + HexZahl
    End If

    If strPart = "1110" Then
    HexZahl = "E" + HexZahl
    End If

    If strPart = "1111" Then
    HexZahl = "F" + HexZahl
    End If

    Next strPart

    MsgBox HexZahl

    End Sub
    [/VBA]

  2. #2
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    What if someone passed string with values other that 0 or 1? Try this:

    [vba]Option Explicit
    Sub Demo()
    Dim strIn As String
    strIn = "1111000010100101"
    MsgBox ConvertBinaryToHex(strIn)
    End Sub
    Function ConvertBinaryToHex(strPassed As String) As String
    Dim lngLen As Long, i As Long
    Dim vHex As Variant
    lngLen = Len(strPassed)
    If lngLen < 64 Then
    ConvertyBinaryToHex = "Ihre Zahl hat weniger, als 64 Stellen"
    Exit Function
    End If
    For i = lngLen To 1 Step -1
    'Check the string for invalid characters
    Select Case Asc(Mid(strPassed, i, 1))
    Case 48, 49
    'Process valid input.
    If Mid(strPassed, i, 1) And 1 Then
    vHex = vHex + 2 ^ Abs(i - lngLen)
    End If
    Case Else
    vHex = ""
    ConvertBinaryToHex = "Invalid Input"
    Exit Function
    End Select
    Next i
    'Return vHex as String
    ConvertBinaryToHex = Hex(vHex)
    End Function
    [/vba]
    Greg

    Visit my website: http://gregmaxey.com

  3. #3
    VBAX Newbie
    Joined
    May 2012
    Location
    Berlin
    Posts
    3
    Location
    Hi Greg.

    Thanks for your quick reply.

    Looks like it would solve the problem, but I'm not allowed to copy entire codes off the internet or from other people.

    But I managed to find another solution (even if my code is a little longer than yours ).

    Thanks for the hint about the possibility of someone adding a digit other than 1 or 0

    Is there a way to tell the program to return to the original input box rather than ending it if that happens?

  4. #4
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    1. strPart is dimmed as a string, but you're trying to use it as loop index

    [VBA] For strPart = Mid(BinZahl, 4, 4) To Mid(BinZahl, 64, 4) Step -4[/VBA]

    2. You could use If ... ElseIf .... ElseIF ..... Endif instead of all the If/Then/Endif. After all, once you have a successful match, you don't need to check anymore. Look in Help for Select Case

    3. Always a good idea to use Option Explicit in your modules (see Help)

    4. I usually use a Do / Loop Until construct to handle re-getting bad input corrected.

    5. Examples of concepts for your own code

    [VBA]
    Option Explicit
    Public Sub BinHexCalc()
    Dim BinZahl As String
    Dim HexZahl As String
    Dim iLen As Long, iPart As Long
    Dim bGoodInput As Boolean

    bGoodInput = True

    Do
    BinZahl = InputBox("Bitte geben Sie eine 64-stellige Binärzahl ein.")

    iLen = Len(BinZahl)

    If iLen < 64 Then
    bGoodInput = False
    MsgBox ("Ihre Zahl hat weniger, als 64 Stellen")

    Else
    For iPart = 61 To 1 Step -4

    Select Case Mid(BinZahl, iPart, 4)
    Case "0000": HexZahl = "0" + HexZahl
    Case "0001": HexZahl = "1" + HexZahl
    Case "0010": HexZahl = "2" + HexZahl
    Case "0011": HexZahl = "3" + HexZahl
    Case "0100": HexZahl = "4" + HexZahl
    Case "0101": HexZahl = "5" + HexZahl
    Case "0110": HexZahl = "6" + HexZahl
    Case "0111": HexZahl = "7" + HexZahl

    Case "1000": HexZahl = "8" + HexZahl
    Case "1001": HexZahl = "9" + HexZahl
    Case "1010": HexZahl = "A" + HexZahl
    Case "1011": HexZahl = "B" + HexZahl
    Case "1100": HexZahl = "C" + HexZahl
    Case "1101": HexZahl = "D" + HexZahl
    Case "1110": HexZahl = "E" + HexZahl
    Case "1111": HexZahl = "F" + HexZahl
    Case Else
    bGoodInput = False
    End Select

    Next iPart

    If Not bGoodInput Then
    MsgBox "Bad input"
    Else
    MsgBox HexZahl
    End If

    End If

    Loop Until bGoodInput

    End Sub
    [/VBA]


    Paul

  5. #5
    VBAX Newbie
    Joined
    May 2012
    Location
    Berlin
    Posts
    3
    Location
    Wow, this forum definitely seems better than the German Office forum.
    Thanks for the replies.

  6. #6
    Microsoft Word MVP 2003-2009 VBAX Guru gmaxey's Avatar
    Joined
    Sep 2005
    Posts
    3,335
    Location
    If you can get two or more values from a function if you create a user defined type. Here you want to know a) Was the value passed valid and b)what is the string value of the converted input passed.

    [VBA]Option Explicit
    Type typConverter
    strOut As String
    bValid As Boolean
    End Type
    Sub Demo()
    Dim result As typConverter
    Dim strIn As String
    Do
    strIn = InputBox("Enter a binary string", "Input")
    result = ConvertBinaryToHex(strIn)
    MsgBox result.strOut
    Loop Until result.bValid = True
    End Sub
    Function ConvertBinaryToHex(strPassed As String) As typConverter
    Dim lngLen As Long, i As Long
    Dim vHex As Variant
    ConvertBinaryToHex.bValid = False
    lngLen = Len(strPassed)
    If lngLen < 64 Then
    ConvertBinaryToHex.strOut = "Ihre Zahl hat weniger, als 64 Stellen"
    Exit Function
    End If
    For i = lngLen To 1 Step -1
    'Check the string for invalid characters
    Select Case Asc(Mid(strPassed, i, 1))
    Case 48, 49
    'Process valid input.
    If Mid(strPassed, i, 1) And 1 Then
    vHex = vHex + 2 ^ Abs(i - lngLen)
    End If
    Case Else
    vHex = ""
    ConvertBinaryToHex.strOut = "Invalid Input"
    Exit Function
    End Select
    Next i
    'Return vHex as String
    ConvertBinaryToHex.strOut = Hex(vHex)
    ConvertBinaryToHex.bValid = True
    End Function

    [/VBA]
    Greg

    Visit my website: http://gregmaxey.com

  7. #7
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Another concept is the difference between ByVal and ByRef in VBA. Most parameters are passed ByRef, as a default. What does this mean?

    It means that, as an alternative to using a custom Type as a function return when needing multiple return values, you can also simply populate parameters within a function and reference them outside of a function. Although I like Greg's approach, there are times when it may not be the best approach. As an alternative, here is a demo of another way of using a function where you need multiple returns:
    [vba]
    Sub Demo
    Dim sParam1 As String
    Dim sParam2 As String
    Dim bReturn As Boolean

    sParam1 = "Before"
    sParam2 = "I change"
    'the variables as they first exist
    MsgBox sParam1 & " " & sParam2

    'but if we pass them ByRef to our function, and our function returns true...
    If fDemo(sParam1, sParam2) Then
    'then see how the messagebox is different... because the variables were returned "changed"
    MsgBox sParam1 & " " & sParam2
    End If
    End Sub
    'See the difference in the above subroutine if you insert "ByVal" before each of these parameter names
    'Function fDemo (ByVal sOneThing As String, ByVal sAnotherThing As String) As Boolean
    Function fDemo (sOneThing As String, sAnotherThing As String) As Boolean
    sOneThing = "Hello"
    sAnotherThing = "World"
    fDemo = True
    End Function
    [/vba]

  8. #8
    VBAX Sage
    Joined
    Apr 2007
    Location
    United States
    Posts
    8,724
    Location
    Greg / Frosty -- UDT's and ByRef/ByVal

    You're pushing the OP into the advanced course

    Paul

  9. #9
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    It's true. But I'm sure the course will cover it at some point, and then the OP will learn that UDTs mean "User Defined Types" and there will be more stuff to read up on in the help file.

    I appreciate that the OP requested hints rather than answers... so I was trying to cover the conceptual hints

    You put in the harder stuff... Do ... Loops with steps and Mid

    Personally, I would separate out the data validation from the data analysis. But there are so many ways to structure items, I make this comment not as a "this is better" but just as a different approach.

    As a bit of a brain teaser, I think I'd probably use the following function to determine whether to do any processing at all...
    I don't know if this kind of "Is" function exists elsewhere in the system, but it doesn't seem to exist in VBA in Word 2010.
    [vba]
    'pass in a value ByVal since we'll manipulate in the routine to determine whether it is a valid binary number
    'can pass in "0000 1110 11110110" or "01011101101"
    Public Function IsBinary(ByVal sExpression As String) As Boolean
    Dim bRet As Boolean
    Dim sChar As String
    Dim i As Integer

    'any errors, and we assume the passed string is not something which is binary
    On Error GoTo l_err

    'allow the passing in of blank spaces
    sExpression = Replace(sExpression, " ", "")
    'if not empty, and is numeric-- it might be binary
    If Len(sExpression) > 0 And IsNumeric(sExpression) Then
    'make sure the only characters in this string are 0s and 1s
    For i = 1 To Len(sExpression)
    sChar = Mid(sExpression, i, 1)
    Select Case sChar
    Case "0", "1"
    bRet = True
    Case Else
    bRet = False
    Exit For
    End Select
    Next
    End If

    l_exit:
    IsBinary = bRet
    Exit Function
    l_err:
    bRet = False
    Resume l_exit
    End Function
    [/vba] A couple concerns I would have with the input box method:
    1) empty spaces at the beginning or end
    2) typing 64 characters absolutely correctly

    So I would test for more than just 64 characters (you could easily have 63 chars and a space... and go through a whole bunch of processing before you find out you've got a bad input). The processing isn't a big deal time-wise, but it's a bit of a pain when stepping through code to analyze, so I would want to break apart whether I wanted to attempt to convert it to hexadecimal first).

  10. #10
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Two concepts in the above code which may be helpful...
    1) using the string manipulation function "Replace" to get rid of any spaces in the potential string. Similar to a Trim/LTrim/RTrim, this has the advantage of getting rid of any spaces which would cause a problem.
    2) Breaking apart multiple pieces of functionality, so that you can test those components without testing the whole system (i.e., this process requires 3 separate pieces: a) should you try to convert? (determine bad input) b) is it a valid length (determine valid good input) and c) the actual hexidecimal result.

    If you break these different pieces apart, you can give your end-user a better hint on why the function broke. i.e.,
    "Unable to process-- does not appear to be a binary string."
    "Unable to process-- must be 64 digits long."
    "Unable to process-- unanticipated error"

    Etc etc... the more you break a function apart, the easier it is to not just troubleshoot your own code, but to give valid error messages to the end-user.

  11. #11
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    This is a good assignment, because (to me) the hardest part about it is actually the easiest part -- conversion to hex. That's the part that VBA will do for you, with the "Hex" function. So the best "hint" would be to not spend so much of your coding time on that part (that is your extended Select Case or If...Else If...End if structure will you convert valid strings to a hex value by hand (i.e., "0000" becomes "0", etc))... but rather thinking about the various ways your InputBox methodology can be stymied by an end-user not putting in the right stuff, and how you can help your end user put in the right stuff.

    I don't want to say too much more, without giving it away...

    The rest of it is

  12. #12
    VBAX Master
    Joined
    Feb 2011
    Posts
    1,480
    Location
    Haha, I clearly posted an incomplete sentence... but it ends up looking like I'm teasing the OP.

    What I meant to say was...

    The rest of it is all logic, structure and data validation. The actual conversion of binary to hex is incidental to the real lesson. I like.

  13. #13
    VBAX Wizard
    Joined
    May 2004
    Posts
    6,713
    Location
    "logic, structure and data validation"

    ah yes, all part of that OVERT ruse...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •