Function CInches

Hi i was using this code in MS Excel and was working fine but i need to use it in a small application i'm making in Ms visual studio 2005, if any one can help thanx.

'\ This function converts a string like 5'-6 1/4" to a decimal number
'\ of inches that can be used in calculation.
Function CInches(Text_string_containing_values_for____Feet_Inches)

'\ These values are used to examine the input string, one character at a time
Dim vVal As String '\ shorter name for input string
Dim i As Integer '\ counter to step through each character in input string
Dim vChar As Variant '\ temporary storage of each input string character

'\ These variables hold the values we discover for feet, inches and the
'\ numerator and denominator of the fractional inches
Dim iFt As Integer '\ used to store number of feet
Dim iIn As Integer '\ number of inches
Dim iNumerator As Integer '\ numerator of fractional inches
Dim iDenominator As Integer '\ denominator of fractional inches

'\ In the process of discovering values for feet and inches, these variable
'\ are used to accumulate and hold numeric values
Dim iTemp As Integer '\ Used to build a number as each digit is read

'\ We want to ignore spaces, except for the very important space between
'\ the number of inches and the numerator of the fractional inches
'\ This variable is true if the last character processed was a space
Dim bLastCharWasSpace As Boolean

'\ First we assign input string to variable with shorter name
vVal = Text_string_containing_values_for____Feet_Inches

'\ If input string is numeric, then we don't want to convert it
If IsNumeric(vVal) Then
CInches = vVal
Exit Function
End If

'\ Now we step through each character in input string from left to right
iTemp = 0
bLastCharWasSpace = False
For i = 1 To Len(vVal)
vChar = Mid(vVal, i, 1)

'\ If character is a number, then we combine it with numbers before it
'\ to get a number that we can assign to feet, inches, numerator or denominator
If IsNumeric(vChar) Then

'\ If this is a number and the last character was a space then
'\ chances are, the number in iTemp is inches and we need to
'\ start over building the numerator of fractional inches
If bLastCharWasSpace = True And iIn = 0 Then
iIn = iTemp
iTemp = 0
End If

'\ As we read number from left to right, we multiply value of previous
'\ number (if any) by 10 and add this number
If iTemp = 0 Then
iTemp = vChar
Else
iTemp = iTemp * 10
iTemp = iTemp + vChar
End If

'\ The number we've been buiding must be feet
ElseIf vChar = "'" Or vChar = "f" Then
iFt = iTemp
iTemp = 0

'\ The number we've been bulding must be the numerator of fraction
ElseIf vChar = "/" Then
iNumerator = iTemp
iTemp = 0

'\ The number we've been building must be inches or
'\ the denominator of the fraction, so we check to see if
'\ there is a numerator
ElseIf vChar = """" Or vChar = "i" Then
If iNumerator > 0 Then
iDenominator = iTemp
iTemp = 0
'\ If no numerator, then the number must be inches
ElseIf iIn = 0 Then
iIn = iTemp
iTemp = 0
End If
End If

'\ Now we set our indicator so that when we process the next
'\ character, we will know if the last character was a space
If vChar = " " Then
bLastCharWasSpace = True
Else
bLastCharWasSpace = False
End If
Next i

'\ To avoid dividing by zero if there was no numerator for fraction,
'\ we set denominator to 1
If iNumerator = 0 And iDenominator = 0 Then iDenominator = 1

'\ Finally, we calculate number of decimal inches and return value
CInches = (iFt * 12) + iIn + (iNumerator / iDenominator)
End Function


'\ This function converts a decimal number of inches to a text string like 5'-6 1/2"
Function CFeet(Decimal_Inches, Optional Enter_16_32_64_Etc__To_Round_Inches_To__Fraction_Of_Inch)
'\ These variables are used to convert the decimal inches to the number
'\ of fractional units. For example 6" would convert to 96 16ths
Dim iNumUnits As Long '\ converted value = 96 in example
Dim iUnit As Double '\ unit used to convert = 1/16 in example

'\ These varibles are used to hold calculated values that will become
'\ part of the text string
Dim iFeet As Integer
Dim iInches As Integer
Dim dFraction As Double
Dim sFtSymbol As String

'\ These variables are used to assign shorter names to input values
Dim vVal As Variant
Dim vDenominator As Variant

'\ First we assign shorter names
vVal = Decimal_Inches
vDenominator = Enter_16_32_64_Etc__To_Round_Inches_To__Fraction_Of_Inch

'\ If no denominator value was supplied, we will round to 1/9999 of inch
If IsMissing(vDenominator) Then
iUnit = 1 / 9999
Else
iUnit = 1 / vDenominator
End If

'\ Now we calculate the number of fractional units in the input value
'\ Example 6 inches = 96 16ths
iNumUnits = (vVal / iUnit)

'\ We prepare each part of text string
iFeet = Fix(iNumUnits / (12 / iUnit))
iInches = Fix((iNumUnits Mod (12 / iUnit)) * iUnit)
dFraction = (iNumUnits Mod (1 / iUnit)) * iUnit
If iFeet <> 0 Then sFtSymbol = "'-"

'\ Finally we format and return text string

CFeet = Application.Text(iFeet, "##") & sFtSymbol & Application.Text(iInches + dFraction, "# ##/##\""")

End Function




Answer this question

Function CInches

  • ruben_ruvalcaba_camba

    Thank you all but non of them seem to work when you start to multiply, you see with your code's try to multiply this 5'-0 1/2" x 600'-0 1/16"

    Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged

    If Not IsNumeric(TextBox2.Text) Then

    MessageBox.Show("Only Numeric Values On The Length Box", "My Application", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)

    LengthTextBox.Clear()

    ElseIf TextBox9.Text = "" Then

    Sq_FeetTextBox.Text = TextBox2.Text

    ElseIf LengthTextBox.Text = "" Then

    Sq_FeetTextBox.Text = TextBox9.Text

    Else

    TextBox2.Text = CInches(LengthTextBox.Text)

    Sq_FeetTextBox.Text = TextBox9.Text * TextBox2.Text / 12 / 12

    End If

    End Sub



  • CRames

    Lukan,

    I'm sorry, I read your post too fast and missed the fact that the second function is supposed to change the decimal value back into a string.

    To do this, you'll need two functions; one does the actual conversion and the other is used to get the Greatest Common Factor of the remainder of the number so that your final fraction can be reduced to lowest terms:

    Here's the function to do the conversion:

    Public Function GetStringFromInches(ByVal dec As Decimal)

    Dim sF As String = String.Empty
    Dim sI As String = String.Empty
    Dim sN As String = String.Empty

    If Decimal.Divide(dec, 12) > 1 Then

    Dim dF As Decimal

    dF = Decimal.Truncate(Decimal.Divide(dec, 12))
    sF = dF.ToString
    dec -=
    Decimal.Multiply(dF, 12)

    End If

    If Decimal.Truncate(dec) > 0 Then

    sI = Decimal.Truncate(dec)
    dec -=
    Decimal.Truncate(dec)

    End If

    If Not dec = 0 Then

    Dim digits As Integer
    digits = dec.ToString.Substring(2).Length
    digits = 10 ^ digits
    dec =
    Decimal.Multiply(dec, digits)

    Dim gcf As Integer = GetGCF(dec, digits)
    dec =
    Decimal.Divide(dec, gcf)
    digits =
    Decimal.Divide(digits, gcf)

    sN = String.Format("{0}/{1}", CInt(dec), digits)

    End If

    Dim rtn As New System.Text.StringBuilder

    If sF.Length > 0 Then

    rtn.Append(sF)
    rtn.Append(
    "'")

    End If

    If sI.Length > 0 Then

    If sF.Length > 0 Then

    rtn.Append("-")

    End If

    rtn.Append(sI)

    End If

    If sN.Length > 0 Then

    If sI.Length > 0 Then

    rtn.Append(" ")

    Else

    If sF.Length > 0 Then

    rtn.Append("-")

    End If

    End If

    rtn.Append(sN)

    rtn.Append(ControlChars.Quote)

    Else

    If sI.Length > 0 Then

    rtn.Append(ControlChars.Quote)

    End If

    End If

    Return rtn.ToString

    End Function

    And here's the helper function that the one above uses to get the GCF:

    Public Function GetGCF(ByVal int1, ByVal int2) As Integer

    Dim max1 As Integer = Math.Max(int1, int2)
    Dim first, second As Integer

    For i As Integer = -max1 To max1

    Dim a As Decimal = int1 / i
    Dim b As Decimal = Math.Floor(a)
    Dim c As Decimal = a - b

    If c = 0 Then

    first = 1

    Else

    first = 0

    End If

    a = int2 / i
    b = Math.Floor(a)
    c = a - b

    If c = 0 Then

    second = 1

    Else

    second = 0

    End If

    If first = 1 And second = 1 Then

    Return Math.Abs(i)

    End If

    Next

    End Function

    Hope that helps.  I haven't tested a lot of different values but this should work across the board (or at least give you a good starting point!)



  • Martin Dietz

    i did try that and it does not seem to work any other ideas

  • Yoni Gibbs

    Oh, BTW, to do the actual calculation, like multipling 5'-0 1/2" x 600'-0 1/16", use something similar to the following:

    Dim text1 As String = String.Format("5'-0 1/2{0}", ControlChars.Quote)

    Dim text2 As String = String.Format("600'-0 1/16{0}", ControlChars.Quote)

    Dim dAns As Decimal

    Dim sAns As String

    dAns = Decimal.Multiply(GetInchesFromString(text1), GetInchesFromString(text2))

    sAns = GetStringFromInches(dAns)



  • jkline

    You might tell him HOW it fails and what "doesn't work" means.



  • Alan Hebert

    One more thing... If you always want the inches to display, even if the value is 0, modify the string building portion of the fuction to the following:

    Dim rtn As New System.Text.StringBuilder

    If sF.Length > 0 Then

    rtn.Append(sF)
    rtn.Append(
    "'")
    rtn.Append(
    "-")

    End If

    If sI.Length > 0 Then

    rtn.Append(sI)

    Else

    rtn.Append("0")

    End If

    If sN.Length > 0 Then

    rtn.Append(" ")
    rtn.Append(sN)
    rtn.Append(ControlChars.Quote)

    Else

    rtn.Append(ControlChars.Quote)

    End If

    Return rtn.ToString



  • Whatfly

    Not to sound picky, but the method you're using seems to be a bit of overkill.... Try something a little simpler like this:

    Const STRMEASUREMENT As String = "5'6.25"
    Dim FEET As Integer
    Dim INCHES As Double
    Dim X As Integer
    For X = 1 To Len(STRMEASUREMENT)
      If Mid(STRMEASUREMENT, X, 1) = "'" Then
        FEET = Val(Strings.Left(STRMEASUREMENT, _
         (X - 1)))
        INCHES = Val(Mid(STRMEASUREMENT, (X + 1)))
        Exit For
      End If
    Next
    MsgBox(FEET & " feet and " & INCHES & " inches")

     

    Hope this helps you out! :-)



  • mneedham

    Thank you very much rkimble you are are a very smart person God bless. i will try it and let you know waht hapens ok thank's again.

  • tculler

    That's because my input string format is:

    Feet (') Inches (as Double)

    So "5'-6 1/4" as you put it is entered like this "5'6.25"

    If it's just 6 inches, simply go "0'6"

    All I'm saying is that doing the crazy formatting is overkill, however, with slight modification, my code would expand to meet his requirements.



  • Ruprect8696

    You're quite welcome Lukan.  I hope it works out for you.

    I did find an error though that you'll need to correct...  Due to experimentation, I left in an If-Then condition that souldn't be there.  In the code:

    If Decimal.Remainder(digits, dec) = 0 Then

    Dim gcf As Integer = GetGCF(dec, digits)
    dec =
    Decimal.Divide(dec, gcf)
    digits =
    Decimal.Divide(digits, gcf)

    End If

    Remove the If Decimal.Remainder(digits, dec) = 0 Then statement.  It doesn't belong there and will prevent many fractions from factoring down.

    Sorry about that!

    This is one of those slap-together POCs that is actaully very useful to me so I'm compiling it into a project to keep.  It was during this process that I discovered my mistake.

    Hope the error hasn't cost you too much time!



  • KeWin

    I'm not sure just how varied your input strings get, but the following function should get you started:

    Public Function GetInchesFromString(ByVal str As String)

    Dim rtnI As Decimal

    If IsNumeric(str.Replace(ControlChars.Quote, "").Trim) Then

    Return CDec(str.Replace(ControlChars.Quote, "").Trim)

    End If

    Dim findChar As Integer
    findChar = str.IndexOf("'")

    If findChar > -1 Then

    Dim feet As String
    feet = str.Substring(0, findChar)

    If IsNumeric(feet) Then

    rtnI = feet * 12

    End If

    str = str.Substring(findChar + 1)
    If str.Length = 0 Then Return rtnI

    End If

    If str.StartsWith("-") Then

    str = str.Substring(1)

    End If

    Dim vals() As String
    vals = str.Split(" ")
    rtnI +=
    CInt(vals(0).Replace(ControlChars.Quote, ""))

    If vals.Length = 1 Then

    Return rtnI

    End If

    vals = vals(1).Replace(ControlChars.Quote, "").Split("/")
    rtnI +=
    CDec(vals(0)) / CDec(vals(1))
    Return rtnI

    End Function

    To get the value in feet, just divide the result of the function by 12.



  • Julien Gourdet SOPRA

    CumQuaT, your code returns -1 for the string 5'-6 1/4".  It also does not handle values like 6"...

    (I should note that I stuck your code in the following function:)

    Public Function GetInchesFromString(ByVal str As String)

    Dim strmeasurement As String = str
    Dim FEET As Integer
    Dim INCHES As Double
    Dim X As Integer

    For X = 1 To Len(STRMEASUREMENT)

    If Mid(STRMEASUREMENT, X, 1) = "'" Then

    FEET = Val(Strings.Left(STRMEASUREMENT, _
    (X - 1)))
    INCHES = Val(Mid(STRMEASUREMENT, (X + 1)))

    End If

    Next

    Return (FEET * 12) + INCHES

    End Function



  • Steini

    I have so this so far and the only thing giving me a problem seems to be the bottom part of the code were it says in red just like here (Application.Text)

    '\ This function converts a string like 5'-6 1/4" to a decimal number

    '\ of inches that can be used in calculation.

    Function CInches(ByVal Text_string_containing_values_for____Feet_Inches)

    '\ These values are used to examine the input string, one character at a time

    Dim vVal As String '\ shorter name for input string

    Dim i As Integer '\ counter to step through each character in input string

    Dim vChar As Object '\ temporary storage of each input string character

    '\ These variables hold the values we discover for feet, inches and the

    '\ numerator and denominator of the fractional inches

    Dim iFt As Integer '\ used to store number of feet

    Dim iIn As Integer '\ number of inches

    Dim iNumerator As Integer '\ numerator of fractional inches

    Dim iDenominator As Integer '\ denominator of fractional inches

    '\ In the process of discovering values for feet and inches, these variable

    '\ are used to accumulate and hold numeric values

    Dim iTemp As Integer '\ Used to build a number as each digit is read

    '\ We want to ignore spaces, except for the very important space between

    '\ the number of inches and the numerator of the fractional inches

    '\ This variable is true if the last character processed was a space

    Dim bLastCharWasSpace As Boolean

    '\ First we assign input string to variable with shorter name

    vVal = Text_string_containing_values_for____Feet_Inches

    '\ If input string is numeric, then we don't want to convert it

    If IsNumeric(vVal) Then

    CInches = vVal

    Exit Function

    End If

    '\ Now we step through each character in input string from left to right

    iTemp = 0

    bLastCharWasSpace = False

    For i = 1 To Len(vVal)

    vChar = Mid(vVal, i, 1)

    '\ If character is a number, then we combine it with numbers before it

    '\ to get a number that we can assign to feet, inches, numerator or denominator

    If IsNumeric(vChar) Then

    '\ If this is a number and the last character was a space then

    '\ chances are, the number in iTemp is inches and we need to

    '\ start over building the numerator of fractional inches

    If bLastCharWasSpace = True And iIn = 0 Then

    iIn = iTemp

    iTemp = 0

    End If

    '\ As we read number from left to right, we multiply value of previous

    '\ number (if any) by 10 and add this number

    If iTemp = 0 Then

    iTemp = vChar

    Else

    iTemp = iTemp * 10

    iTemp = iTemp + vChar

    End If

    '\ The number we've been buiding must be feet

    ElseIf vChar = "'" Or vChar = "f" Then

    iFt = iTemp

    iTemp = 0

    '\ The number we've been bulding must be the numerator of fraction

    ElseIf vChar = "/" Then

    iNumerator = iTemp

    iTemp = 0

    '\ The number we've been building must be inches or

    '\ the denominator of the fraction, so we check to see if

    '\ there is a numerator

    ElseIf vChar = """" Or vChar = "i" Then

    If iNumerator > 0 Then

    iDenominator = iTemp

    iTemp = 0

    '\ If no numerator, then the number must be inches

    ElseIf iIn = 0 Then

    iIn = iTemp

    iTemp = 0

    End If

    End If

    '\ Now we set our indicator so that when we process the next

    '\ character, we will know if the last character was a space

    If vChar = " " Then

    bLastCharWasSpace = True

    Else

    bLastCharWasSpace = False

    End If

    Next i

    '\ To avoid dividing by zero if there was no numerator for fraction,

    '\ we set denominator to 1

    If iNumerator = 0 And iDenominator = 0 Then iDenominator = 1

    '\ Finally, we calculate number of decimal inches and return value

    CInches = (iFt * 12) + iIn + (iNumerator / iDenominator)

    End Function

    ' \ This function converts a decimal number of inches to a text string like 5'-6 1/2"

    Function CFeet(ByVal Decimal_Inches, ByVal Enter_16_32_64_Etc__To_Round_Inches_To__Fraction_Of_Inch)

    ' \ These variables are used to convert the decimal inches to the number

    ' Warning!!! Optional parameters not supported

    ' \ of fractional units. For example 6" would convert to 96 16ths

    Dim iNumUnits As Long

    ' \ converted value = 96 in example

    Dim iUnit As Double

    ' \ unit used to convert = 1/16 in example

    ' \ These varibles are used to hold calculated values that will become

    ' \ part of the text string

    Dim iFeet As Integer

    Dim iInches As Integer

    Dim dFraction As Double

    Dim sFtSymbol As String

    ' \ These variables are used to assign shorter names to input values

    Dim vVal As Object

    Dim vDenominator As Object

    ' \ First we assign shorter names

    vVal = Decimal_Inches

    vDenominator = Enter_16_32_64_Etc__To_Round_Inches_To__Fraction_Of_Inch

    ' \ If no denominator value was supplied, we will round to 1/9999 of inch

    If IsNothing(vDenominator) Then

    iUnit = (1 / 9999)

    Else

    iUnit = (1 / vDenominator)

    End If

    ' \ Now we calculate the number of fractional units in the input value

    ' \ Example 6 inches = 96 16ths

    iNumUnits = (vVal / iUnit)

    iFeet = Fix((iNumUnits / (12 / iUnit)))

    iInches = Fix(((iNumUnits Mod (12 / iUnit)) _

    * iUnit))

    dFraction = ((iNumUnits Mod (1 / iUnit)) _

    * iUnit)

    If (iFeet <> 0) Then

    sFtSymbol = "\'-"

    End If

    ' '\ Finally we format and return text string

    Return (Application.Text(iFeet, "##") & (sFtSymbol & Application.Text((iInches + dFraction), "# ##/##\\\""")))

    End Function



  • Artur I.

    I think your problem with Application.Text is the fact that you should be using the Format statement. Give that a go :-)


  • Function CInches