Form Field Control Source

unclefink

Registered User.
Local time
Today, 11:46
Joined
May 7, 2012
Messages
184
I'm trying to create 3 like fields on a form that show the last 5 field records for "casenumber" in a specific table. I'm trying to get this accomplished without having to create new "sub queries". I am able to accomplish this with some sql but i'm trying to apply this to three different form data controls, each with a different "where" criteria.

SELECT TOP 5 MainDataTbl.CaseNumber
FROM MainDataTbl
WHERE (((MainDataTbl.CaseNumber) Like "*bs*"))
ORDER BY MainDataTbl.CaseNumber DESC;

Can anyone tell me how I can accomplish this in 3 different form field controls without having to create extra queries.
 
I don't understand the requirement. Can certainly have multiple LIKE expressions in WHERE clause.

Perhaps you should show us some sample data and the output you desire.

Could even provide db for analysis.
 
You have three different controls; you want each to show a different list of top 5 records based on different criteria, but don't want to create 3 different queries? The query structure can be consistent (variations in the WHERE clause), but three queries are needed I think. (instead of like *bs*) - an appropriate selection!
 
If you are looking for the top three entries matching the FROM/WHERE clauses of your SQL, your BEST bet would be for the three different form controls to be unbound. Then in the form's _Current routine, open a recordset for that query and do a .MoveFirst, then load a control. Do a .MoveNext and load a control. Do another .MoveNext and load the last of the three controls. One query, one recordset, three records, done - if you have at least 3 records returned by the query.
 
A control takes in 1 content, not 5. What are you doing there?
but three queries are needed I think
You can combine multiple subqueries into one query. That would then be a query as a data source for a continuous form.

But you could also place subforms or list boxes next to each other and display individual queries. It depends on.

Code:
CaseNumber Like "*bs*"
Maybe there are missing normalization steps.
When filtering for given atomic information, things might look different.

Thought game: The data origin of a list box or a form could look something like this, where the TIOP 5 values from several characteristics are displayed.
SQL:
SELECT
   N.*
FROM
   NormalizedTable AS N
WHERE
   N.ID IN
      (
         SELECT TOP 5
            X.ID
         FROM
            NormalizedTable AS N
         WHERE
            X.Attribute1 = N.Attribute1
               AND
            X.Attribute2 IN ("bs", "xy", "ok")
         ORDER BY
            X.Attribute3 DESC
      )
 
Last edited:
ok so I should have better explained my origional post resulting all of the clarifications; however that is OK because this is all part of my learning adventure.

I have a single table I'm pulling from that has a field called "CaseNumber". A case number will start with one of four acronyms based on the location as to where the case occurred at followed by a series of 2 numbers indicating the year followed by a four digit sequential number. For sake of conversation lets use Washington, Oregon, California, and Arizona, as "properties". Based on that logic.

The table might have WA23-0001 - WA23-500 while at the same time the same table will have records for OR23-0001 - OR23-500, OR23-0001 - OR23-500, CA23-0001 - CA23-500, or AZ23-0001 - AZ23-500.

What i'm trying to do on an unbound form is have a text box represent the last 5 records of each location that provides feedback to data entry users of what the last 5 cases were issued for each site. Each site would have its own text box representing the last 5 records. This is for data entry reference that tells one the last 5 records to illustrate where the last person completing data entry left off.
 
This is for data entry reference that tells one the last 5 records to illustrate where the last person completing data entry left off.
If you are doing this to help the user determine the next sequence number, don't. You should assign the sequence numbers programmatically. Never leave this to the user.

Take a look at this sample, to see how you can do this yourself.
 
I would never mash data together in a single field like this: WA23-0001 At some point in the past you must gave had to do the mashing, now you have to unmash. Store your data raw. Store each single data point in a single field.
 
Some of those identifiers have 3-digit sequence although you state should be 4-digit. If you want to use this data for sorting, need consistent structure - mashed together or not.
 
Last edited:
I would never mash data together in a single field like this: WA23-0001 At some point in the past you must gave had to do the mashing, now you have to unmash. Store your data raw. Store each single data point in a single field.
I guess you didn't look at the sample.

Storing the calculated value makes working with it later easier. Both the components as well as the final string are stored. The custom number is NOT the PK but it does have a unique index and may not contain a ZLS. The PK is an autonumber. If you look at the sample, you will see that the custom number is calculated when a record is created and the parts of it cannot change after the fact.

So, all we are quibbling about is whether or not to store the calculated string. I store it so that nowhere in the application does the string ever need to be recreated. That confines the logic to the maintenance form which means that if the rules ever change, they chang in this one place AND the old values can exist without disruption which would not be the case if the completed string were constantly recalculated throughout the app.
 
I was not responding to your post Pat, sorry if that was not clear. I would not mash data together like this: WA23-0001, WA23-500, OR23-0001, OR23-500, OR23-0001, OR23-500, CA23-0001, CA23-500, AZ23-0001, AZ23-500.
<state><year>-<sequence>

No, I did not look at the sample.
 
You might not choose to mush fields together to make an "intelligent" "key" but in my world, my clients get to decide things like this. I do get to choose how to implement the solution - hence the sample I posted since there are lots of ways to do this wrong as we can see by the formatting error in the question, but I don't get to tell the client they can't have what they asked for because I don't like it;) At best, I get to discourage the practice. But, users just don't like simple numbers, especially if they've been doing it this way forever.
 
make an "intelligent" "key"
In fact, a great many consider such composite information to be great and intelligent, and imitation is very high. But very few can handle it.
For the requested TOP 5 per location, you would have to disassemble the intelligent key with your own intelligence, and then the field that shakes it out of the sleeve is significantly smaller.
Disconnecting is more or less easy, but still solvable. In any case, you then have calculated values for which index use is securely switched off. I call something like this in a database with an expected amount of data a gross error or catastrophe.

A case number will start with one of four acronyms based on the location as to where the case occurred at followed by a series of 2 numbers indicating the year followed by a four digit sequential number.
These are clearly three atomic pieces of information that would also be stored in three separate table fields and provided with a composite unique index.
SQL:
SELECT
   Location,
   CaseYear,
   SeqNum,
   Location & CaseYear mod 2000 & Format(SeqNum, "-0000") AS CaseNumber
FROM
   AnyTable
The user has no place in tables and my queries. The composite value is displayed in forms, the user is happy. I can work and calculate with the atomic information underground, much more easily and quickly.

The rules of normalization also make sense in daily practice.
I don't have to show the user anything for a new CaseNumber, I can offer him MAX(SeqNum)+1 for the selected Loction and CaseYear immediately.

Using atomic information enables me to be variable, future-ready and easy to scale.
I can filter, count, sort, aggregate as I like, without any further preparatory work.
If the users get busy and need 6 digits for SeqNum instead of 4, if the year should be used with four digits, if there are extensions to the locations (number of locations, number and type of characters used), no problem: the reaction in extreme cases, this occurs in exactly one place - the composition and formatting of the expression for CaseNumber.

If I present such arguments to the user, he will very rarely insist on his own ideas.
 
Last edited:
I have a single table I'm pulling from that has a field called "CaseNumber". A case number will start with one of four acronyms based on the location as to where the case occurred at followed by a series of 2 numbers indicating the year followed by a four digit sequential number. For sake of conversation lets use Washington, Oregon, California, and Arizona, as "properties". Based on that logic.

The table might have WA23-0001 - WA23-500 while at the same time the same table will have records for OR23-0001 - OR23-500, OR23-0001 - OR23-500, CA23-0001 - CA23-500, or AZ23-0001 - AZ23-500.

What i'm trying to do on an unbound form is have a text box represent the last 5 records of each location that provides feedback to data entry users of what the last 5 cases were issued for each site. Each site would have its own text box representing the last 5 records. This is for data entry reference that tells one the last 5 records to illustrate where the last person completing data entry left off.
If you don't already have it in your single table, you should add a column for Site or something to that effect. This should be an easy one time update to the table and will simplify the whole process of getting your desired records per site info.

What is the primary key for the table that contains all of the CaseNumber fields? I hope it's not that CaseNumber field. If so, seriously reconsider going to a simple auto number primary key field.

Will those four locations ever change? Could more locations be added? This is important. I'll assume they are staying the same for now.

So five recent CaseNumber records copied into one text box on the form? How would you propose to format the individual bits of information? By a comma separated list or just spaces or what? Just explain exactly how the data is supposed to look like inside one of the four controls and what type of control we are talking about. If this is just for reference use only why not use subforms instead?

Potential Solution #1: Use an unbound main form that has three subforms that have as their recordsource each of the appropriate queries. This assumes that the user is just looking at the data and does nothing with it and does not intend on adding a new CaseNumber record from this form.

Potential Solution #2: Use a bound form that has three subforms that have as their recordsource each of the appropriate queries. This could allow the user to make a new CaseNumber entry while referring to the required last five cases at all four locations.

These four subforms can be placed on a Tab Control to make more efficient use of space. The user only has to select the appropriate tab to show the desired location data while they look at the data. If they want to see all locations at the same time, then ignore this suggestion. It's just an option.

I am able to accomplish this with some sql but i'm trying to apply this to three different form data controls, each with a different "where" criteria.
This is the part I do not understand. Three different form data controls? There is no such thing as a data control. There is a text box control, a combo box control, a subform control, etc... precision matters when describing what your requirement is. You also stated that there are FOUR locations. Why only show three then? Maybe you are referring to three fields from the table that contains the CaseNumber, please confirm.
 
For the requested TOP 5 per location, you would have to disassemble the intelligent key with your own intelligence,
I guess you didn't read my reply. I NEVER suggested NOT storing the atomic information. I NEVER suggested not using the atomic information for searching. You ALWAYS store the atomic information and that is what you use for searching. The question is whether you also store the generated "intelligent" "key". I say YES. Because sometimes the rules change. And if the rules change for new numbers, you can't change the old numbers because there are paper records associated with them. By saving the generated key, you can just leave what was old alone and apply the rules to the new keys.

When you store the generated "key", you restrict the build logic to the data entry form that makes it PERIOD. You never have to construct or deconstruct any other place EVER. The "key" becomes just another searchable field like company name. If you know the "key" you can type it in. Otherwise the code uses the parts for searching.

The OP implied that the reason for having the controls that display the last few "keys" was to help the user generate a new one. But, as I mentioned, the user should NEVER be building the "key". The application should ALWAYS build the "key". The "key" is for display/search only. So, technically, the controls with the old "keys" aren't necessary.
 
The question is whether you also store the generated "intelligent" "key".
There are important reasons not to save calculated values. There are risks of data anomalies by creating, changing and deleting the basic data for calculation, and there are redundancies. Some also call this the 0th normal form.

Code:
' approach
Public Function GetCaseNumber(ByVal CaseDate As Date, ByVal Location As String, _
                              ByVal CaseYear As Long, ByVal SeqNum As Long) As String
    Dim sRes As String
    Select Case CaseDate
        Case Is < #1/1/2023#
            sRes = Location & CaseYear Mod 2000 & Format(SeqNum, "-0000")
        Case Else
            sRes = Location & CaseYear & Format(SeqNum, "-000000")
    End Select
    GetCaseNumber = sRes
End Function
Cases come with a date and possibly other attributes. From this one can derive the calculation of the composite value precisely as tried in the example, at the same time one would have an obvious history of changes.
A composite value like CaseNumber is only there for viewing, exports and label printing.

restrict the build logic to the data entry form
I wouldn't limit myself to that, in my world, in addition to manual entries in a form, there are also imports and transfers (for example from other stocks), which will then take place as a mass action and code-controlled.

It would take very serious reasons for me to agree with you in this case and to open Pandora's box.
 
There are important reasons not to save calculated values. There are risks of data anomalies by creating, changing and deleting the basic data for calculation, and there are redundancies. Some also call this the 0th normal form.
@ebs17 You don't need to lecture me about normal forms. I understand why we don't generally store calculated values and I explained the reason for storing this one. I'll do it again. There is NO import of data that would generate new records. If there were, it would have to use a function to call the same generation code as is used by the data entry form. That means, It is always generated programmatically when a new record is entered. There is no other source for the calculation than the ONE data entry point of a new record. To the user, it is the ID for one record even though behind the scenes, there is an autonumber that serves the purpose of PK. In fact, the generated "key" should never be used as the PK. Once it is generated it cannot be modified. Just as the user cannot change the PK autonumber, the user cannot change this value. Why you would ever want to spread this type of calculation to multiple places is beyond me. Storing the generated number is specifically done to eliminate ever having to have that particular calculation any other place but one! Storing the full string does not prevent in any way the proper use of the constituent parts. What it prevents is having to decompose the "intelligent key" key for any reason. Think of this as a safety play. If the generation method ever has to change, you have one and only one place to modify the code. If one of the constituent parts changes, the "intelligent key" doesn't automatically change.

I'll give you a real world example. Social Security number in the US. I'm talking about the problem from inside the SSA, not how the SSN is used by employers. It was a 9 digit number. The first three digits were a geographic key and the next two digits were a group. That left the last four as a serial number. As population grows, the number of numbers available within a three digit geographic area and two digit group became constrained, the SSA had to change their method of assignment. If they were generating/decomposing this field throughout their application (it was and may still be COBOL, btw), they would have had to locate all the calculation spots and change them to lookups. Another problem is running out of numbers. Even though the SSN can support a billion numbers and the US population is just a little more than 1/3 of that, over time, the numbers will run out and reuse isn't really an option. So, either the number will be lengthened or letters will be introduced changing it from a number to a string. So, temporarily, the SSA changed to a randomized method of assigning the number so you can no longer look at an SSN and make any assumptions as to meaning. In the past couple of years the SSA has been issuing new SSN's to all original SSN holders that now include alpha characters. That "number" is to be used going forward.

Now from the perspective of companies who have to store the SSN, some made the mistake of storing the code as a number rather than text. With the use of leading zeros, that becomes problematic since numeric data types do not store leading zeros. You can overcome it with formatting but if you are using string functions to decompose the "number", they will no longer work with leading zeros unless you use the Format() function in all expressions. But, now that SSN contains alpha characters, storing the SSN as a number, is no longer possible so any company that made that mistake has to change the data type of the SSN to hold the new alpha code.

The SSA eliminated the geographical significance of the first three digits of the SSN, referred to as the area number, by no longer allocating the area numbers for assignment to individuals in specific states. The significance of the highest group number (the fourth and fifth digits of the SSN) for validation purposes was eliminated. Randomization also introduced previously unassigned area numbers for assignment excluding area numbers 000, 666 and 900-999. The SSA implemented the new assignment methodology on June 25, 2011

So, technically, storing or not storing the generated number is a choice. It is not wrong, nor is it right. It is a matter of risk avoidance. If you know for a fact that the generation method will never, ever have to change, then calculate it everywhere you want. If you don't care if the number changes if one of the underlying parts changes, live with it.

The prohibition against storing calculated values is to protect against anomalies when the underlying data changes. In this particular case, if the underlying data changes, you DO NOT want to generate a different code. What if the client wanted to use state as part of the "key", are you going to say NO? If you don't, you run the risk of the "unique custom key" changing on the fly if the customer moves. How about if you use a couple of letters of the user name as part of the "key". What if the name changes? Do you really want to all of a sudden have a new ID? I don't think so. You also can't just slip in the replacement state or other string, you actually have to generate a new serial number for consistency and to avoid potential duplication.

Yes, we don't want to store the customer's outstanding balance in the Customer table. But, when changes to the underlying data should NOT cause a change to the calculated value, you store the calculated value. You are applying a generalized rule to a specific situation to which it should not be applied.
 
Last edited:
If you don't care if the number changes if one of the underlying parts changes, live with it.
What makes you think that? Of course, the calculation approach is based on the fact that the basic data remain constant, as do the attribute-related calculation methods.
If you change around with your eyes closed, you will experience a fiasco, in all variants.

If the intelligent number becomes a piece of information of its own, detached from the original derivation and only in nostalgic memory of its original meaning, then it must of course be stored independently in a table field.
But you can wait that long.
You are applying a generalized rule to a specific situation to which it should not be applied.
Whether this specific situation occurs for an application remains to be seen. Of course, you can also stand at the bus stop (and tie up resources), because there may be a bus in 5 years.
 
If you don't want changes to the generated value if the underlying components change, you store the calculation when you make it. I am not charging around with my eyes closed or recommending the storing of calculated values as a general practice. Unless you are creating a data warehouse where the whole point is to store calculated values, you "almost never" store calculated values in a transactional system. This purpose falls into the "almost never" category. I was quite specific that the reason for storing this particular generated value is because you don't want a change to an underlying component (assuming any can be changed) to cause a change in the "intelligent key". Not every "intelligent key" will contain a changeable component. If it does, you need to store the generated number. If it doesn't, you don't.

Most of the time the "never" store calculated values comes up is because many developers don't understand why it is important to always calculate changeable values as you need them. The "intelligent key" is NOT a changeable value. That is why we say "almost never". Rather than blindly following a rule, you need to understand its intent so you know when a deviation is safe and appropriate. I'm pretty sure you don't create street address fields with 8 or more fields instead of the common 1 field. Why is it safe to mush 100 Main St (I'm not talking about city, state, and zip since those are always separate unless the developer made a mistake) into 1 field rather than using three or 8 or more because there's also compass direction, unit #, etc.? Because most applications don't do direct mail and so don't have to conform to post office rules to sort their outgoing mail. But, if you are a company like Reader's Digest whose lifeblood is direct mail, you care and so in order to ensure proper sequencing and more easily de-dupe addresses, you break them apart into various components. So probably 99% of the applications ever built mush the parts of street address into 1, 2, or 3 (lines (not constituant fields) for the convenience of snail mail printing of addresses) rather than using separate fields for each individual part. This is a risk avoidance issue. RD can't risk having the components mushed because different municipalities use different formats for how they assign addresses and the rules are too varied and not under the control of RD so to avoid the issue, they enter new addresses very carefully into separate fields so the code needed to generate bar codes and sort don't have to parse a string. But, in their case, they don't store the mushed result because they would want it to change should a constituent part change.
 
I am not ... recommending the storing of calculated values as a general practice.
Thanks for the clarification. The many words allowed a different interpretation.
Incidentally, one should also orientate oneself to the specific case of the thread.
 

Users who are viewing this thread

Back
Top Bottom