We are currently using Access 2003. I have a vehicle maintenance log which has a text field for vehicle numbers. The field needs to be text as it will have a R in it when a vehicle is retired. They would like to have the field be a four digit number with leading zero's. So vehicle 22 would be displayed in the table and reports as 0022 and when retired it would be R0022. I have tried to change the format of the field to "0000" and "0000"# but neither of these will display the leading zero's.
Do you really want you users to manually edit that field?
I don't like solutions like this, because it's error-prone (unless you check a lot of things to make sure that no one enters invalid data) and feels unelegant to your users.
I would just save the following in the table:
the vehicle number in a numeric field (22, not 0022)
a boolean field which indicates if the vehicle is retired
This is much easier for your users to work with:
they can just enter new vehicle numbers without having to think about leading zeros
to retire a vehicle, they just need to set a checkbox, instead of putting the right letter in front of the vehicle number
Plus, showing the desired number R0022 now becomes just a matter of displaying/formatting the data from the table:
Public Function GetDisplayNo(VehicleNo As Integer, IsRetired As Boolean) As String
GetDisplayNo = IIf(IsRetired, "R", "") & Right("0000" & VehicleNo, 4)
End Function
You can use this function like this:
GetDisplayNo(22, True) returns R0022
GetDisplayNo(22, False) returns 0022
And if you need to display a list of vehicle numbers in a report or a continuous form, you can directly use this function in the underlying query:
SELECT
Vehicles.VehicleNo,
Vehicles.IsRetired,
GetDisplayNo([VehicleNo],[IsRetired]) AS DisplayNumber
FROM Vehicles;
Related
data output
I am pretty new to Webi and am having an issue creating a variable. I'm trying to check if there is more than 1 email address for each entity legacy account number and if 1 of the contact names contains "Annual Report". So when I flag each entity legacy account number for no email only the ones without a contact name that contains "Annual Report" will be pulled. In the example above only the yellow groups should be called no email. Right now all of them are being pulled into no email. I have tried using if and match as those are what I am most familiar with. Does anyone have any suggestions?
There are number of ways you could do this. I am going to give an example using two variables, but you could easily combine them into one.
Has No Email Var=If(Match(Upper([Contact EmailAddress]); "NOEMAIL*"); 1; 0)
Annual Report Contact Name Var=If(Match(Upper([Contact Name]); "ANNUAL REPORT*"); 1; 0)
Then you would apply a report filter with two components...
Has No Email Var = 1
AND
Annual Report Contact Name Var = 0
Let me explain a few things...
The purpose of the Upper function is the Match function is case sensitive. If you know your email address are always lower case then you could remove that the Upper function and have it match on "noemail*".
It is significant that I only have a asterisk ("*") at the end of the string being sought. That will only find a match where the corresponding column value starts with that string. If you want it to be true whenever the string is found anywhere in the column being searched you would be asterisks on both ends.
You could also put limiting criteria in your query filter. But here is where thing can get confusing. Within the query filter you can choose the Matches pattern operator. However, the wildcard character is different ("%" rather than "*") and you do not put double-quotes around your search text. So you would have some thing like this...
Contact EmailAddress Matches pattern noemail%
AND
Contact Name Different from pattern Annual Report%
I am sure you noticed I didn't convert the search text to uppercase. In the Query Panel Web Intelligence is case-insensitive and would likely follow the case-sensitivity of the database of the source data. All of our databases are case-insensitive so if yours is case-sensitive you may need to play around this this a bit. Or just go with the approach of creating the variables and report filters as I initially laid out.
If you want a wildcard for a single character rather than multiple characters (which is what "*" and "%" will do) you need to use a "?" within your variable definition or a "_" in your query filter.
Hope this helps,
Noel
I'm working on an Access 2007 database and I'm having a problem with a query.
I have a table named Vehicles, which contains data such as ID, license plate and fuel type for each vehicle in it.
I'm trying to make a query which will populate a combobox in a Form with each vehicle's fuel type, based on the license plate chosen by the user beforehand.
The thing is, we have some some cars that work with two types of fuel and I cant' find a way to display them separately in the combobox.
So far it kinda works, code follows:
CheckDiesel: IIf([Diesel]="Yes";"Diesel";IIf([Gasoline] AND [Ethanol]="Yes";"Gasoline"+ "Ethanol";IIf([Ethanol]="Yes";"Ethanol";IIf([Gasoline]="Yes";"Gasoline";""))))
If you look at the second IIf, I have a condition for a bi-fuel car. I want to display Gasoline and Ethanol separately, each one in a row.
I've tried using "&Chr(10) Chr(13)&" and "\r\n" but I had no success so far.
Can anyone help me?
Storing multiple pieces of data in a single field rarely ends well. A few options I see
A series of binary fields for gasoline type. So you'd have a True/false for gasoline, ethanol, and diesel. This is easy to show with checkboxes on the form.
If you know there will only be certain combinations, like if there will not be a 'diesel and ethanol' without gasoline, you can build it as a single value combobox.
You will probably need some VBA to do what you need to do. Try something like this:
Dim R as String
R=""
if (Me.Diesel) then R = R & "Diesel;"
if (Me.Gasoline) then R = R & "Gasoline;"
… {add any other types of fuel}
Me.MyComboBox.Rowsource = R
Me.MyComboBox.Requery
This can be added tot he form's OnCurrent event so it will update the combo box every time a new record is displayed.
If your form does not include the various fuel types as fields, either add them as hidden fields or use DLookup to read them off the table.
I have a field with a customer ID that should be in the format of C0000000001, where it has a letter at the start and up to 10 numbers after the letter with leading zeros between the letter and the number. I want the users to be able to put in C1 and have the table save C0000000001 or C1234 and have the table save C0000001234.
I want the restriction to be on the hard data in the table. The table should contain the full customer ID but I only want the users to have to enter the C and the number of the customer when entering/searching for customers. I am using Access 2010.
I believe that the first character will always be a C, but either way, it would only be one alpha character if it wasn't.
I understand what you are saying, but the majority of the data (thousands of records) are going to be from another system that stores them that way. Doing it this way limits my margin of error. Otherwise, exports from the other system will need to be manually changed prior to being imported into the database and vice versa.
Searching would only be on existing records that will be saved in the C0000001234 format, but I would like user to be able to omit the leading zeros when entering the search criteria.
This question, combined with your previous question here, suggest to me that you are trying very hard to have the data structure in your Access database exactly match the legacy system from which you receive bulk updates. That may not be necessary, or even desirable.
For example, instead of maintaining the CustomerId as Text(11) (as in the old system) you could store it in your Access database as
CustomerIdPrefix: Text(1), and
CustomerIdNumber: Long Integer or perhaps Decimal if the numeric part really can exceed 2,147,483,647
Your Customers table in Access could also include a calculated field named CustomerId as
[CustomerIdPrefix] & Right("0000000000" & [CustomerIdNumber], 10)
to give you a single 'C0000012345' value for display purposes.
For searching, your form could have a Text Box for the Prefix (default value: 'C') and another text box for the numeric part. The search could then use a condition like
[CustomerIdPrefix] = txtPrefix.Value AND [CustomerIdNumber] = txtNumber.Value
or, if the user wanted to create a Filter on the Form (or Datasheet View) it would probably be sufficient to just filter on the number part.
If you ever needed to feed information back to the legacy system you could just export a query that includes the [CustomerId] calculated field (and omits [CustomerIdPrefix] and [CustomerIdNumber]) and you'd be fine.
My suggestion would be to use forms with associated queries using the FORMAT function.
You do need to clarify where you want this implemented, but I'm going to assume you have a table set up and that you would like to be able to enter/search data from a form.
I'll create one form for input frmAdd. For the input form, I created a query that would run when a button on the form was pressed. Add two text boxes newID and newOther to the forms which are unbounded but which the user can use to enter data. The query will then pull that data and append it to your table in an altered format. Here's the SQL for that query:
INSERT INTO Customers ( [Customer ID], [Other Field] )
SELECT Left([Forms]![frmAdd]![newID].[value],1)
& Format(Right([Forms]![frmAdd]![newID].[value],Len([Forms]![frmAdd]![newID].[value])-1),"0000000000")
AS Expr1, Forms![frmAdd]!newOther AS Expr2
FROM Customers;
I'm not sure exactly what search functionality you're looking for, but this query would pull up the record data matching that of a frmSearch with a textbox search which would have the format C### or whatever entered in:
SELECT Left([Customers].[Customer ID],1) & Replace(LTrim(Replace(Right([Customers].[Customer ID],9),'0',' ')),' ','0')
AS Expr1, Customers.[Other Field]
FROM Customers
WHERE (((Customers.[Customer ID])=Left([Forms]![frmSearch]![search].[value],1)
& Format(Right([Forms]![frmSearch]![search].[value],Len([Forms]![frmSearch]![search].[value])-1),"0000000000")));
Applying the input mask is just a way to ensure that your data is correct. If you feel the need to use one, go to the table in Design View and click on the Data Type box for the customer ID field. Find Input Mask under Field Properties -> General and click it. Then hit go to the toolbar -> Design tab -> Builder. This will walk you through it.
Input mask is not the answer for this. Input mask forces the user to input the data in a certain manner. What you need is some VBA code to run in the AfterUpdate event on a form. There's no way within the table to force the data into this pattern allowing the input method that you've requested.
There may be a more efficient way to do this, but this does the job.
http://pineboxsolutions.com/access/customeriddemo.accdb
I have a form that asks the user to enter some information into text boxes, then some VBA code that manipulates those values and enters them into a table.
One of these text boxes asks for a numeric serial number. This serial number value could be four or five digits in length, and it may contain one or more leading zero(s). e.g. 0001 or 00758 or 0463.
Once the VBA code enters this value into the table, it loops through it, increments it, and makes another entry. This repeats until all the serial numbers are added to the table. I have the serial number value taken from the text box declared as a string in my code, but it still drops my leading zeros.
I've had similar problems, using CStr() to force a string fixed it for me. So, something like: sMyString = CStr(vUserValue) instead of sMyString = vUserValue.
Also, you might be dropping the zeros when you increment the number. You can re-add them with something like: sMyString = String(5-len(sMyString),"0") & sMyString where 5 is the original number of digits.
sMyString = String(5-len(sMyString),"0") & sMyString
I'm working on a gig right now where the client wants the user to be able to search for a product by product code.
A product code is formatted like so: 123.4567.89
So, the search box should return that product whether the user enters the number with the periods, without the periods, or with spaces.
So, all of the following should return the product: 123.4567.89, 123456789, 123 4567 89.
My current query looks like so:
SELECT *
FROM products
WHERE product_code LIKE '%$search_code%'"
I'm at a loss as to how I would revise that to include all the different possibilities of how a user would input these numbers.
Thanks in advance for any help.
[Front End] Limit the characters the user can enter. Only allow periods and spaces. Don't allow any alpha characters (if all your product SKUs are numerical).
[Middle Tier] After the form is posted, double check the data for extraneous characters on the back end. If somehow the client managed to bipass the validation on the front end, you can catch it on the back end. Use a simple search and replace in your language of choice.
[Database/Back-End] Once the data is restricted to only numeric digits and you send the SKU to your database query, strip out all periods on your products table. If you know you only use periods to store the SKUs, just search excluding them, e.g.
SELECT *
FROM products
WHERE REPLACE(product_code,'.','') = #productCode
Avoid wildcard %% searches, they're expensive.
You have to normalize the number input by the user before doing the search, that is: make it have the same format as the number stored in the database.
For instance, if the numbers are stored in the database without the periods (like 123456789), you have to pre-process the number input by the user to also remove the periods, spaces and any other characters from it.
Edit: if the numbers are stored in the database with the periods, than you also need to normalize them by removing the periods as #HertzaHaeon pointed in his answer.
How about removing dots and spaces in both the database code and the searcg input, so you have just the digits? Something like this:
WHERE REPLACE(product_code, '.', '') LIKE '%formatted_search_code%'
For the search input, you can strip everything but digits form it with a regular expression or simple substring replacement.
I think the best solution to your problem is to format the search value so that is matches the format used in your database. But than you will only find the product, if the user fills in the whole product number. If this is not the desired solution and you want to be able to let the user fill in any part of a product code and find al the products that have a code containing that that I think you should filter out the periods in your database.
The fasted solution would be to do it actually in your database. Remove the dots from your product code or add an extra field containing the product code without dots. This will speed up the query when the dataset gets larger.
If you not want to do that you can always filter out the dots in the search query:
REPLACE(product_code,'.','') LIKE '%$search_code%'
This will do the thrick but can be very slow when the dataset gets bigger.
I work with this all the time with social-security numbers. My solution is to take your input string, strip out and characters that are not digits, make sure that the string is the proper length and then use the substring function to break the string up and then put it back together with the delimiters. If you're using PHP, the function might look like this this:
<?php
function FormatProductCode($String) {
$String = preg_replace("/[^0-9]/", "", $String);
if ($String == "") {
return null;
}
$String = str_pad($String, 9, "0", STR_PAD_LEFT);
return substr($String, 0, 3) . "." . substr($String, 3, 4) . "." . substr($String, 7, 2);
}
?>
Use this function any time that you need to input data into the database or compare data.