Page 1 of 2 12 LastLast
Results 1 to 15 of 18
  1. #1
    Join Date
    Aug 2017
    Posts
    8

    Access Not Retrieving Correct Records Due to Criteria Issue

    My Select query has two tables -- MASTER and TCDS_Data. The two tables are left-joined on MASTER.[MFR MDL CODE] = TCDS_Data.CODE. The query has five fields -- MASTER.[N-NUMBER], MASTER.[MFR MDL CODE], MASTER.[SERIAL NUMBER], TCDS_Data.tcdsSerialStart1, and TCDS_Data.tcdsSerialEnd1. The Criteria in the SERIAL NUMBER field is "Between [tcdsSerialStart1] And [tcdsSerialEnd1]" (without the quotes), so the query seeks to return all records where SERIAL NUMBER falls between tcdsSerialStart1 and tcdsSerialEnd1 for a given MFR MODEL CODE. All of the fields in all tables are Short Text formatted.



    Here's the problem: For TCDS_Data.CODE= "1151410", the serial number range is CE-1 to CE-179. The query should return 116 records from MASTER, but it is only returning the records where the serial number is CE-1* -- it won't return any records where the first number following "CE-" is 2, 3, 4, 5, 6, 7, 8, or 9. In other words, it won't return the records matching serial numbers CE-2 or CE-90 even though CE-2 and CE-90 fall between CE-1 and CE-179. Access thinks that CE-2 and CE-90 are bigger than CE-179 since "2" and "9" are bigger than "1" in the first character after "CE-". Access is treating the alphanumeric more like a number instead of text, even though the field is formatted as Short Text and the data is, by definition, alphanumeric.

    How do I get Access to treat the data as text and evaluate the entire field, versus treating it as a number and evaluating just the first numeric digit? In other words, how do I get Access to acknowledge that CE-2 falls between CE-1 and CE-179, and not outside of it?

    Here is the query:

    SELECT MASTER.[N-NUMBER], MASTER.[MFR MDL CODE], MASTER.[SERIAL NUMBER], TCDS_Data.tcdsSerialStart1, TCDS_Data.tcdsSerialEnd1
    FROM MASTER LEFT JOIN TCDS_Data ON MASTER.[MFR MDL CODE] = TCDS_Data.CODE
    WHERE MASTER.[SERIAL NUMBER] Between [tcdsSerialStart1] And [tcdsSerialEnd1]
    ORDER BY MASTER.[N-NUMBER];

  2. #2
    davegri's Avatar
    davegri is offline Excess Access
    Windows 10 Access 2016
    Join Date
    May 2012
    Location
    Denver
    Posts
    3,413
    If all your serial numbers start with CE-
    You will have to convert them (for sorting and comparison) to numbers like this example:
    Code:
    SELECT Master.[Serial Number], CLng(Mid([Master].[Serial Number],4)) AS Num
    FROM Master
    ORDER BY CLng(Mid([Master].[Serial Number],4));
    The behavior you describe is an alphanumeric sort, which you don't want. The query above strips off the CE- and converts the result to a long integer and it sorts as expected for numbers.
    You'll have to do the same with the start1 and end1 fields. The numeric comparisons for between will also work as expected.

    The conversion in the query does not change your table data at all. The conversion occurs only in the query to get the desired sorting/comparison criteria.
    Last edited by davegri; 08-23-2017 at 10:25 PM. Reason: clarif

  3. #3
    John_G is offline VIP
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2011
    Location
    Ottawa, ON (area)
    Posts
    2,615
    Access is treating the alphanumeric more like a number instead of text,
    No, it's the other way around. Access is treating the data as text, and not numeric at all. When it is making the comparison, it compares character by character, left to right, until it reaches the end of the shorter of the two strings. So, when comparing "CE-2" with "CE-179", it can only compare the first three characters, i.e. "CE-2" vs "CE-1", and "CE-2" IS greater than "CE-1".

    Access has no way of knowing that there are numbers in there - they are just strings of characters.

    This is a common problem when trying to sort numeric data stored as text, and even more of a problem when only part of the data is "numeric".

    If you are able to do it, the easy fix is to store the serial numbers as fixed lengths, with leading zeros in the numeric part, e.g. "CE-009", "CE-010". Doing so will ensure that they sort and compare correctly. If the serial number is always the same format, i.e. aa-nnn, it should be easy to write an update query to reformat them.

  4. #4
    Join Date
    Aug 2017
    Posts
    8
    Thanks, davegri and John_G.

    Unfortunately, not all of the serial numbers in the table follow that same format, so I won't be able to strip the leading alphas consistently and reliably with the Mid function. For the same reason, I won't be able to consistently and reliably do the leading-zeros / fixed-length string method.

    However, I think that I can beat Access at its own game. I think that I will check each character of the serial number using the Mid and IsNumeric functions. I will then concatenate all of the numeric parts into a string with "&", and then coerce the string to an integer with CInt. I'll have to do the same thing with tcdsSerialStart1 and tcdsSerialEnd1. Once everything is an integer, the [Integer] Between [Integer1] And [Integer2] should work. I'll report back.

    Thanks again for the ideas.

  5. #5
    John_G is offline VIP
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2011
    Location
    Ottawa, ON (area)
    Posts
    2,615
    Does the serial number always contain a dash, followed by digits? If so, the expression to get the number part will be quite a bit simpler.

  6. #6
    Join Date
    Aug 2017
    Posts
    8
    Unfortunately, no. Here is a sample of varying serial numbers throughout the table: 5334, A28, 79-030, T18208245, BG-72, 210Q58839, 15AC-2, 108-3741. It's all over the map. Hence, the lack of a single, clean solution. I am making headway with the solution that I proposed -- just haven't completed it yet.

  7. #7
    orange's Avatar
    orange is offline Moderator
    Windows 10 Access 2010 32bit
    Join Date
    Sep 2009
    Location
    Ottawa, Ontario, Canada; West Palm Beach FL
    Posts
    16,726
    However, I think that I can beat Access at its own game.
    Access thinks that CE-2 and CE-90 are bigger than CE-179
    And Access is correct, and so are all other dbms's.

    Trying to sort a text field as a number is not something specific to Access. And you are not the first to discover this.

    Part of the issue is the variations in format for a field that you seem to be treating as common across your application. That seems to be the root of the issue.

    I'm not sure how far along you are in your project, but this design issue seems to be something that should be addressed. You can certainly create workarounds for a design issue, but it will be forever. Perhaps your requirements have changed, or perhaps the analysis was not thorough.
    You know more about the project than any reader, so it is you who should make any decisions.

    Good luck.

  8. #8
    John_G is offline VIP
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2011
    Location
    Ottawa, ON (area)
    Posts
    2,615
    I think that I will check each character of the serial number using the Mid and IsNumeric functions. I will then concatenate all of the numeric parts into a string with "&", and then coerce the string to an integer with CInt.
    Some are easy enough, but what is something like "79-030" supposed to yield - 30 or 79030? Similarly, what is "15AC-2" - 2 or 152?

    Using what you have described, "15AC-2", "A-152", "15BC-2A" and "15B-2X" will all yield 152, which probably is not what you want.

    How many different manufacturer model codes (MFR MODEL CODE) are there to deal with?

  9. #9
    John_G is offline VIP
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2011
    Location
    Ottawa, ON (area)
    Posts
    2,615
    There may be a way to deal with this. If the serial number range is being entered through a form (as it should be!), then input masks could be applied to the two controls, and the masks could be changed according to a selected manufacturer. The Manufacturer codes and corresponding masks could be kept in a (possibly separate) table.

    VBA would then put together the query SQL where clause for you, with the proper where clause. How are you using the query?

  10. #10
    Join Date
    Aug 2017
    Posts
    8
    orange, I have absolutely not control over the data in the SERIAL NUMBER field. The serial-number formats are what they are. They come from an external source completely out of my control. I have to play the hand that I've been dealt.

  11. #11
    Join Date
    Aug 2017
    Posts
    8
    John_G, agreed that there is a risk in extracting the alpha characters and getting the same result depending on the starting serial number. However, for a given MFR MODEL CODE, there shouldn't be any corresponding serial numbers that would cause this condition. Thorough testing will reveal the weaknesses of the approach.

    To answer your other question, there are over 85,000 unique MFR MODEL CODE in the MASTER table.

  12. #12
    Join Date
    Aug 2017
    Posts
    8
    The data is being imported from an external source.

  13. #13
    orange's Avatar
    orange is offline Moderator
    Windows 10 Access 2010 32bit
    Join Date
    Sep 2009
    Location
    Ottawa, Ontario, Canada; West Palm Beach FL
    Posts
    16,726
    Who assigns the serial number?
    Perhaps you could tell us clearly about the Manufacturers and Models. What a Code is? And what a serial number represents to your organization? TCDS? Master?

    What is your role in this database?

  14. #14
    John_G is offline VIP
    Windows 7 32bit Access 2010 32bit
    Join Date
    Oct 2011
    Location
    Ottawa, ON (area)
    Posts
    2,615
    To answer your other question, there are over 85,000 unique MFR MODEL CODE in the MASTER table.
    Ah, not very practical. Well it was a thought.

    Since all serial numbers for any one MFR MODEL CODE should be the same format, maybe you could look at extracting your numbers by working backwards from the end of the serial number until you reach a non-numeric character, and then using the digits found as the number. It might make a bit easier for the users.

    Code:
    Function Serial(strSerial As String) As Long
      Dim J As Integer 'loop counter
      J = Len(strSerial)
      
      '
      ' Return -1 if last character is not numeric
      '
      If Not IsNumeric(Mid(strSerial, J, 1)) Then
        Serial = -1
        Exit Function
      End If
        
      Do Until Not IsNumeric(Mid(strSerial, J, 1))
        J = J - 1
        If J = 0 Then Exit Do
      Loop
      
      J = J + 1  ' J is position of first of the trailing digits
      
      Serial = Val(Mid(strSerial, J))
      
    End Function

  15. #15
    Join Date
    Aug 2017
    Posts
    8
    I'm one error away from having the character-by-character evaluation working. The only problem is that I'm getting a parameter error with no parameters defined (i.e. Access claims to not be able to find the parameter in the query). Here is the new query (shortened-for-clarity and using "1151410" as the MFR MODEL CODE for testing):

    SELECT MASTER.[MFR MDL CODE],
    IIf(Len([SERIAL NUMBER])>=1,IIf(IsNumeric(Mid([SERIAL NUMBER],1,1)),Mid([SERIAL NUMBER],1,1),""),"") & ... & IIf(Len([SERIAL NUMBER])>=5,IIf(IsNumeric(Mid([SERIAL NUMBER],5,1)),Mid([SERIAL NUMBER],5,1),""),"") AS [SERIAL NUMBER LEFT],
    IIf(Len([SERIAL NUMBER])>=6,IIf(IsNumeric(Mid([SERIAL NUMBER],6,1)),Mid([SERIAL NUMBER],6,1),""),"") & ... & IIf(Len([SERIAL NUMBER])>=10,IIf(IsNumeric(Mid([SERIAL NUMBER],10,1)),Mid([SERIAL NUMBER],10,1),""),"") AS [SERIAL NUMBER RIGHT],
    CInt([SERIAL NUMBER LEFT] & [SERIAL NUMBER RIGHT]) AS [SERIAL NUMBER WHOLE], MASTER.[SERIAL NUMBER], TCDS_Data.CODE
    FROM MASTER LEFT JOIN TCDS_Data ON MASTER.[MFR MDL CODE] = TCDS_Data.CODE
    WHERE (((MASTER.[MFR MDL CODE])="1151410"))
    ORDER BY CInt([SERIAL NUMBER LEFT] & [SERIAL NUMBER RIGHT]);

    If I run the query without the ORDER BY, it works fine. But if I manipulate the [SERIAL NUMBER WHOLE] field in any way, either with ORDER BY or, more importantly, putting something in Criteria, then Access throws up the parameter dialogue asking for [SERIAL NUMBER LEFT] and [SERIAL NUMBER RIGHT].

Page 1 of 2 12 LastLast
Please reply to this thread with any new information or opinions.

Similar Threads

  1. Replies: 7
    Last Post: 05-17-2016, 06:04 PM
  2. Replies: 3
    Last Post: 11-09-2015, 10:32 AM
  3. Retrieving records according to criteria
    By jruizmesa in forum Forms
    Replies: 2
    Last Post: 03-24-2012, 11:43 AM
  4. Replies: 9
    Last Post: 06-26-2011, 09:14 PM
  5. Replies: 2
    Last Post: 03-31-2009, 11:15 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Other Forums: Microsoft Office Forums