Form not sorting numerically correct (1 Viewer)

specialk1116

New member
Local time
Today, 13:41
Joined
May 15, 2013
Messages
5
I have a form that lists evidence items 1, 2, 3, ect....

The form is listing them 1, 10, 11, 12, 13, 2, 3, 4, 5...

I have tried right clicking the evidence item # field and doing a sort a to z, and it is still listing them the wrong way.
 

pbaldy

Wino Moderator
Staff member
Local time
Today, 13:41
Joined
Aug 30, 2003
Messages
36,127
It sounds like your field is text, or a function has been used to cause it to be seen as text. First option is changing the data type of the field.
 

specialk1116

New member
Local time
Today, 13:41
Joined
May 15, 2013
Messages
5
I need it to be a text field because we sometimes have evidence items that need to be listed as 1A.

Is there any other suggestions.

Thank you so much for your help again. You helped me yesterday.
 

apr pillai

AWF VIP
Local time
Tomorrow, 02:11
Joined
Jan 20, 2005
Messages
735
The data is treated as text in sorting. Check the field data type on the Table, if it is text change it to Number.
 

apr pillai

AWF VIP
Local time
Tomorrow, 02:11
Joined
Jan 20, 2005
Messages
735
The only solution that I can think of now is to create a SELECT Query with an extra column with the expression numEvidence:Val([evidence]), and place it on the Form, in addition to the actual field. But, this will serve the purpose of sorting only.
 

missinglinq

AWF VIP
Local time
Today, 16:41
Joined
Jun 20, 2003
Messages
6,423
And that's still not going to take into account the Alpha suffixes the OP has indicated they sometimes have. I'd use two Fields:

Field1: Defined as a Number Field for the numeric part of the evidence ID

Field2: Defined as Text to hold the Alpha suffix that the ID sometimes has

You could then do a Primary Sort on the Numeric Field and a Secondary Sort in the Suffix Field.

This would give you something like

1
2
3A
3B
4
5
6
7
8
9
10
11


Linq ;0)>
 

Pat Hartman

Super Moderator
Staff member
Local time
Today, 16:41
Joined
Feb 19, 2002
Messages
43,365
I just had to solve this problem for a drawing log. The following code works in most cases but I'm sure you could find situations where it fails.
In my journey to this end I discovered that two of the functions I had been using for years failed when used in this context.
For starters -- isnumeric thinks 2D1 is numeric???
And Val("2D1") returns 20????
So, I ended up writing my own functions to solve the problem. In my case, I was only worried about drawing numbers <= 10 characters. I could have created a longer string but all the drawing
numbers I saw that the users considered "numeric" were pretty short.

Code:
Public Function funcRJust(strvalue As Variant) As Variant
Dim strBuild As String
Dim iLength As Integer
Dim i As Integer
Dim Filler As String
Dim strNumbers As String
Dim strLetters As Variant
Dim strPrefix As String
Dim strRest As Variant

'right justify drawing numbers of 10 characters or less
    funcRJust = strvalue
    If funcRJust & "" = "" Or Len(strvalue) > 10 Then   'ignore strings > 10 char
        Exit Function
    End If
    If IsAlphabetic(Left(strvalue, 1), False) = True Then   'handle "E" numbers separately
        If IsNumeric(Mid(strvalue, 2, 1)) = True Then
            GoSub FormatENumbers
        End If
        Exit Function
    End If
    strNumbers = PatsVal(strvalue)
    If strNumbers & "" <> strvalue & "" Then
        strLetters = Mid(strvalue, Len(strNumbers) + 1)
    Else
        strLetters = ""
    End If
    iLength = Len(strNumbers)
    strBuild = ""
    For i = iLength To 1 Step -1
        strBuild = Mid(strNumbers, i, 1) & strBuild
    Next i

    Filler = Space(10 - Len(strNumbers))
    funcRJust = Filler & strBuild & strLetters
ExitProc:
    Exit Function
FormatENumbers:
    strPrefix = Left(strvalue, 1)
    strRest = Mid(strvalue, 2)
    strNumbers = PatsVal(strRest)
    If strNumbers & "" <> strRest & "" Then
        strLetters = Mid(strRest, Len(strNumbers) + 1)
    Else
        strLetters = ""
    End If
    iLength = Len(strNumbers)
    strBuild = ""
    For i = iLength To 1 Step -1
        strBuild = Mid(strRest, i, 1) & strBuild
    Next i
    Filler = Space(10 - Len(strNumbers))
    funcRJust = strPrefix & Filler & strBuild & strLetters
    Return
End Function

Public Function PatsVal(str As Variant) As String
    Dim strNumbers As String
    Dim i As Integer
    Dim ValLen As Integer
    Dim EndLoop As Boolean
    
    ValLen = Len(str)
    If ValLen = 0 Then
        PatsVal = ""
        Exit Function
    End If
    
    EndLoop = False
    i = 1
    
    Do Until EndLoop = True
        If i > ValLen Then
            EndLoop = True
        Else
            If IsNumeric(Mid(str, i, 1)) Then
                strNumbers = strNumbers & Mid(str, i, 1)
                i = i + 1
            Else
                EndLoop = True
            End If
        End If
    Loop
    PatsVal = strNumbers & ""
    
End Function
Public Function PatsFindFirstNumber(str As Variant) As Integer
    Dim strNumbers As String
    Dim i As Integer
    Dim ValLen As Integer
    Dim EndLoop As Boolean
    
    ValLen = Len(str)
    If ValLen = 0 Then
        PatsFindFirstNumber = 0
        Exit Function
    End If
    
    EndLoop = False
    i = 1
    
    Do Until EndLoop = True
        If i > ValLen Then
            PatsFindFirstNumber = 0         'none found
            EndLoop = True
        Else
            If IsNumeric(Mid(str, i, 1)) Then
                PatsFindFirstNumber = i     'number found at i
                EndLoop = True
            Else
                i = i + 1
            End If
        End If
    Loop
    
End Function

Function IsAlphabetic(char As String, Optional IncludeNumbers As Boolean) As Boolean
    If Len(char) <> 1 Then      'check length
        IsAlphabetic = False
        Exit Function
    End If
    If (Asc(char) >= 65 And Asc(char) <= 90) Or (Asc(char) >= 97 And Asc(char) <= 122) Then
        IsAlphabetic = True
    Else
        If IncludeNumbers = True Then
            If Asc(char) >= 48 And Asc(char) <= 57 Then  '0-9
                IsAlphabetic = True
            Else
                IsAlphabetic = False
            End If
        Else
            IsAlphabetic = False
        End If
    End If
End Function
 

missinglinq

AWF VIP
Local time
Today, 16:41
Joined
Jun 20, 2003
Messages
6,423
...isnumeric thinks 2D1 is numeric...

That's because 2D1 is a number... in Hex!

...Val("2D1") returns 20...

That would apparently be the Value of 2D1!

The IsNumeric() Function is problematic, as you've seen! It will return True for strings that have A-F in them if they can represent Hex numbers! It will also return True if a string has a single Decimal Point, leading Minus, Plus or Dollar Signs, Parens, if they surround around digits, i.e. (66), and probably others I haven't tested for!

Workarounds abound, out of necessity, and are always (to me) interesting to work out, but I usually use the simple expediency of only allowing digits to be entered:

Code:
Private Sub YourTextBox_KeyDown(KeyCode As Integer, Shift As Integer)

 Select Case KeyCode
  
  Case 48 To 57
   'Numerical characters (digits) are allowed
  
  Case vbKeyDelete, vbKeyBack, vbKeyReturn, vbKeyRight, vbKeyLeft, vbKeyTab
   'Allow these navigation/function keys to be used
  
  Case vbKeyNumpad0, vbKeyNumpad1, vbKeyNumpad2, vbKeyNumpad3, vbKeyNumpad4, vbKeyNumpad5, vbKeyNumpad6, vbKeyNumpad7, vbKeyNumpad8, vbKeyNumpad9
   'Allow input from Numbers Keypad

  Case Else
   'Don't allow any other keys to be used
   KeyCode = 0
 End Select

End Sub

Depending on the user group, I sometimes include a Messagebox if a user attempts to enter an illegal character, sometimes don't! Depends on my mood!

Linq ;0)>
 

ChrisO

Registered User.
Local time
Tomorrow, 06:41
Joined
Apr 30, 2003
Messages
3,202
Code:
Sub TestIt()

    [color=green]' Except when the argument is Null, the Val() function returns a Double:[/color]
    MsgBox TypeName(Val(Empty))             ' << Double
    MsgBox TypeName(Val(vbNullString))      ' << Double
    MsgBox TypeName(Val(""))                ' << Double
    MsgBox TypeName(Val("0"))               ' << Double
    MsgBox TypeName(Val("1"))               ' << Double
    MsgBox TypeName(Val("Fred"))            ' << Double
    MsgBox TypeName(Val("1Fred"))           ' << Double

    [color=green]' E means scientific notation: Number * (10 raised to +/- Exponent).
    ' D means the same except, in some languages, D also means force to Double.
    ' Since the Val() function returns a Double, D is equivalent to E in VBA.[/color]
    MsgBox Val("2E1")                       ' << 20
    MsgBox 2 * (10 ^ 1)                     ' << 20

    MsgBox Val("2D1")                       ' << 20
    MsgBox 2 * (10 ^ 1)                     ' << 20

    MsgBox Val("2E-1")                      ' << 0.2
    MsgBox 2 * (10 ^ -1)                    ' << 0.2

    MsgBox Val("2D-1")                      ' << 0.2
    MsgBox 2 * (10 ^ -1)                    ' << 0.2

    MsgBox Val("2E307")                     ' << 2E+307
    MsgBox 2 * (10 ^ 307)                   ' << 2E+307

    MsgBox Val("2D307")                     ' << 2E+307
    MsgBox 2 * (10 ^ 307)                   ' << 2E+307

    MsgBox Val("2E308")                     ' << Overflow
    MsgBox 2 * (10 ^ 308)                   ' << Overflow

    MsgBox Val("2D308")                     ' << Overflow
    MsgBox 2 * (10 ^ 308)                   ' << Overflow


    [color=green]' Hex has nothing to do with it. For Hex to be interpreted as such
    ' it would need the prefix of &H. That then allows the raising of
    ' the base to 16 depending on position; least significant to the right.[/color]
    MsgBox Val("&H2D1")                     ' << 721
    MsgBox (2 * 256) + (13 * 16) + (1 * 1)  ' << 721

End Sub

Chris.
 

ChrisO

Registered User.
Local time
Tomorrow, 06:41
Joined
Apr 30, 2003
Messages
3,202
Missinglinq.

Would you please stop bolding so much in your posts?
All it is doing is drawing attention to your mistakes.

Chris.
 

Users who are viewing this thread

Top Bottom