How to limit the characters in access to more than 255? for example, I want it the memo or text box to limit it to max 300 characters.
In Access 2010
If you want to limit a memo field in a table to no more than 300 characters, open the table in design view and add this as the field's Validation Rule property.
Len([memo_field])<301
Substitute your field's name for memo_field. You can also add a Validation Text property to display a more user-friendly message when the rule is violated. With no Validation Text, that rule would produce this message ... which might not be very clear to a user:
*One or more values are prohibited by the validation rule 'Len([memo_field])<301' set for 'YourTableName.memo_field'. Enter a value that the expression for this field can accept.*
You also mentioned a text box. If it is a text box bound to a memo field, you can validate the character length in the text box's Before Update event. If the text box is named txtMemo_field:
Private Sub txtMemo_field_BeforeUpdate(Cancel As Integer)
If Len(Me.txtMemo_field) > 300 Then
MsgBox "Please limit data to maximum of 300 characters."
Cancel = True
End If
End Sub
After the message box, the cursor will be still located within the text box, and the user will not be allowed to move to another form field without supplying an acceptable value for txtMemo_field.
Just to address a point in #HansUp's answer:
Is Null Or Len([memo_field])<301 ... If you don't want to allow
Nulls, drop the "Is Null Or" part.
There is no need to explicitly test for nulls in a constraint. A constraint doesn't have to evaluate TRUE for it to be satisfied.
If the Access database engine (ACE, Jet, whatever) actually had a spec it would read like this:
A table constraint is satisfied if and only if the specified
search condition is not false for any row of a table.
According to three-valued logic required to handle nulls, the search condition LEN(NULL) < 301 evaluates to UNKNOWN and the table constraint would be satisfied (because UNKNOWN is not FALSE).
However, Access has no such spec, so we must test and see that the above assertions are indeed true (simply copy and paste into any VBA module, no references required, creates a mew blank mdb in the user's temp folder, then creates table, Validation Rule -- without the explicit test for null -- then attempts to add a null with success, Q.E.D.):
Sub WhyTestIsNull()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = _
"CREATE TABLE Test (" & _
" ID INTEGER NOT NULL UNIQUE, " & _
" memo_field MEMO" & _
");"
.Execute Sql
End With
' Create Validation Rules
Dim jeng
Set jeng = CreateObject("JRO.JetEngine")
jeng.RefreshCache .ActiveConnection
.Tables("Test").Columns("memo_field") _
.Properties("Jet OLEDB:Column Validation Rule").Value = _
"LEN(memo_field) BETWEEN 1 AND 300"
jeng.RefreshCache .ActiveConnection
Sql = "INSERT INTO Test (ID, memo_field) VALUES (1, NULL);"
.ActiveConnection.Execute Sql
Sql = "SELECT * FROM Test;"
Dim rs
Set rs = .ActiveConnection.Execute(Sql)
MsgBox rs.GetString(2, , , , "<NULL>")
Set .ActiveConnection = Nothing
End With
End Sub
Change its Data type to Memo.
max field size of text field
Regards
Related
I am working on a MS-Access database to keep track of last names and addresses and several other records. I am making a table and would like for it to be updated by the user by inputting info from a form. The question I have is can I have several key items that would warn if a duplicate is found. Mainly if a duplicate is found in the last name and the address fields. I need the form to accept the duplicate because how the info is being obtained duplicates are possible but need to be able to enter the duplicate and warn the user while entering the data that a previous entry has already been made that is similar.
Is this possible in Access, and easy to implement that many different users may be entering the data? I haven't used Access for some time, sorry if I'm not using the correct terms, as I'm still learning the basics of Access, as I mainly work in Excel. Excel is the current solution that is being used, but finding quickly that a better solution is needed.
Thanks
Names aren't good candidates for primary keys and it seems that you have set the name as the primary key of one of your tables. You should either use a better candidate key (social insurance number, for example) or create a surrogate (artificial, if you want) key with no meaning other than being a key for your table.
Without more detail about your table structure it's hard to be more specific.
Warn the user but allow her to proceed if she wishes?
If so, a key constraint would be too, ahem, constraining. Just check for the duplicates manually (by explicitly querying existing data from your code). You may wish to index the field(s) being searched.
Yes, you can validate through this code:
If Nz(DCount("FieldName", "table", "FieldName= '" & Me.FieldName.Value & "'"), 0) > 0 Then
If MsgBox("The FieldName already exist", vbOKCancel, "Duplicate Warning") = vbCancel Then Cancel = True
Me.Undo
Exit Sub
End If
End If
In general terms, Access (and relational databases generally) are about preventing duplicate data from being entered in the first place. If you merely want to 'warn', then it will take a bit of custom code. So, say the table is called Customers and it has fields such as CustomerID (AutoNumber, primary key) and LastName (Text). The form then has a text box called txtLastName that is bound to the LastName field. In this situation, you could handle the text box's BeforeUpdate event like this:
Option Compare Database
Option Explicit
Const DuplicateWarningTitle = "Duplicate Record"
Const DuplicateValueWarning = "A record already exists with " + _
"the value you have entered. Are you sure you want to continue?"
Function GetSQLLiteral(Value As Variant) As String
Select Case VarType(Value)
Case vbNull
GetSQLLiteral = "Null"
Case vbString
GetSQLLiteral = "'" + Replace(Value, "'", "''") + "'"
Case Else
GetSQLLiteral = CStr(Value)
End Select
End Function
Sub HandleKeyFieldBeforeUpdate(Control As Access.TextBox, Cancel As Integer)
Dim RS As DAO.Recordset
Set RS = CurrentDb.OpenRecordset( _
"SELECT 1 FROM Customers " + _
"WHERE " + Control.ControlSource + " = " + GetSQLLiteral(txtLastName.Value) + _
" AND CustomerID <> " & Me.CustomerID)
If Not RS.EOF Then
Select Case MsgBox(DuplicateValueWarning, vbExclamation + vbYesNo, DuplicateWarningTitle)
Case vbYes
' just proceed
Case vbNo
Cancel = True
Control.Undo ' if desired!
End Select
End If
End Sub
Private Sub txtLastName_BeforeUpdate(Cancel As Integer)
HandleKeyFieldBeforeUpdate txtLastName, Cancel
End Sub
By pushing the duplicate checking code into a generic helper routine, other key fields can be handled in the same way easily:
Private Sub txtAddress_BeforeUpdate(Cancel As Integer)
HandleKeyFieldBeforeUpdate txtAddress, Cancel
End Sub
First off I'd like to make perfectly clear that my knowledge of Access and VBA is extremely limited at best. I have an employee database system that due to it's age has been prone to small data corruption issues and controls breaking due to differences between 2003/2007 and 2010. While I've managed to hash out the bulk of the problems, one that has me especially concered is the script we're using to manage access to the database. The system is split between two files, a frontend where users can access the database and a backend file that contains all of the tables.
The issue I have is in the frontend form that handles the logon for the users. The way the access system is set up is the user enters their SSN, then the script finds their SSN in the table and if it exists looks if an access checkbox is checked. If they have access, they're directed to the main menu, if not they get a denied message. What I've found though is for some reason or another, if an entry in the personnel table has an incomplete SSN, the script breaks and anyone can gain access to the database.
There's a query that runs in the frontend that looks at the master personnel table and pulls just the first two columns, SSAN and Access.
The form itself has a visible text box, "Text8", and a hidden Combo Box "Combo4". Combo4 uses the previously mentioned query for the row source (SELECT qryAccess.SSAN FROM qryAccess;), while Text8 is where the user enters their SSN.
Here's the code right now:
Option Compare Database
Private Sub Combo4_AfterUpdate()
' Find the record that matches the control.
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
If Not rs.EOF Then Me.Bookmark = rs.Bookmark
If Me![Access] = True Then
DoCmd.RunMacro "Access"
Else
DoCmd.OpenForm "frmDenied"
End If
End Sub
Private Sub Text8_AfterUpdate()
Me![Combo4] = Me![Text8]
' Find the record that matches the control.
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
If Not rs.EOF Then Me.Bookmark = rs.Bookmark
If Me![Access] = True Then
DoCmd.RunMacro "Access"
Else
DoCmd.OpenForm "frmDenied"
End If
End Sub
Like I said before, as long as every entry for the SSNs is a full 9-digits, this system works. However, if for some reason the entry is not the full 9 like I just found in my database (and no, I have no idea what caused that to happen, there is an input mask in place, 000-00-0000;;_), this system breaks. You could type in "abc" for the SSN and gain access to the database.
How can I write a small script that pre-checks the table for SSN entries that don't fit the 9-digit format that is set, and if it finds them, resets them to an unused number, such as 000000000, 000000001, etc?
Also, if you have any suggestions on how to streamline the existing code, I'd be more than happy to take them.
Add this function to you application
Public Function IsValidSSN(ByVal SSN As String) As Boolean
'Determines if SSN is a valid social security number
'requires SSN to be in either "#########" or "###-##-####" format
IsValidSSN = (SSN Like "###-##-####") Or _
SSN Like ("#########")
End Function
Also change your function to this:
Private Sub Combo4_AfterUpdate()
' Find the record that matches the control.
If IsValidSSN(Me![Combo4]) Then
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
If Not rs.EOF Then Me.Bookmark = rs.Bookmark
If Me![Access] = True Then
DoCmd.RunMacro "Access"
Else
DoCmd.OpenForm "frmDenied"
End If
Else
DoCmd.OpenForm "frmDenied"
End IF
End Sub
Private Sub Text8_AfterUpdate()
Me![Combo4] = Me![Text8]
If IsValidSSN(Me![Text8]) Then
' Find the record that matches the control.
Dim rs As Object
Set rs = Me.Recordset.Clone
rs.FindFirst "[SSAN] = '" & Me![Combo4] & "'"
If Not rs.EOF Then Me.Bookmark = rs.Bookmark
If Me![Access] = True Then
DoCmd.RunMacro "Access"
Else
DoCmd.OpenForm "frmDenied"
End If
Else
DoCmd.OpenForm "frmDenied"
End If
End Sub
EDIT
Also why are you using a combobox to enter a SSN? You can use input mask on text box. Also I would highly suggest that you convert your system to some other identification other than SSN because it is easily passable to get past this code to look at the table containing everyones SSN, by holding down shift when opening the application. As for streamlining your code just remove that combobox altogether. If they are typing it into a textbox there is no need to put it into a hidden combobox.
You have a text field, SSAN, and with that input mask the dashes are not included in the stored values. So valid values would be 9 digit strings.
If that is correct, you can use a query to identify any invalid stored values.
SELECT y.SSAN, Len(SSAN) AS LenghtOfSSAN
FROM YourTable AS y
WHERE Len(SSAN)<>9 OR y.SSAN ALike '%[!0-9]%';
That query will return rows where SSAN includes < or > 9 characters, and any values which include characters other than digits.
Note the ALike keyword tells the db engine to expect ANSI wild card characters. If you prefer Access' * wild card instead, change it to Like '*[!0-9]*'
Once you fix the stored values, add a Validation rule for that SSAN field (Like "#########") to require all values consist of 9 digits.
Since it looks like this became more of a "How do I find the user" than "How do I fix the existing entries", let me throw my hat into the ring.
Unless I completely misunderstand this, the existing (and accepted answer) function is HORRIBLE. You can do this all much more efficiently and with less code. First of all, delete Combo4. No need for it. Then do this:
Private Sub Text8_AfterUpdate()
Dim X as Integer
X = DLookup("Access", "qryAccess", "SSAN = '" & Me!Text8 & "'")
If Nz(X) = True Then
DoCmd.RunMacro "Access"
Else
DoCmd.OpenForm "frmDenied"
End If
End Sub
That's all you need. If the user's SSN was stored incorrectly, he's gonna be denied. 7 digits, 8 digits, doesn't make a difference. Only exact matches get through. That is, assuming 0 = False and 1 = True, which should be the default anyway.
I have the following vbscript code:
hemisphereConnectionString = "Driver={MySQL ODBC 5.1 Driver};" & _
"Server=" & hemisphereServer & ";" & _
"Database=" & hemisphereDatabase & ";" & _
"User=" & hemisphereUsername & ";" & _
"Password=" & hemispherePassword & ";"
Set hemisphereConnection = CreateObject("adodb.connection")
hemisphereConnection.Open(hemisphereConnectionString)
hem_sql = "SELECT * FROM hei_vision_update WHERE id IN (SELECT MAX(id) FROM hei_vision_update WHERE done = 'N' GROUP BY name)"
Set hemisphereResult = hemisphereConnection.Execute(hem_sql)
if hemisphereResult.EOF = false then
hemisphereResult.MoveFirst()
end if
msgbox isnull(hemisphereResult("home_publish").value)
msgbox hemisphereResult("home_publish").value
It is part of a much larger script (too big to post here but these are the key lines)
My message boxes display false (ie the field has a value that is not null) and the next message box crashes saying "Invalid use of Null"
Anyone have any Ideas??
I have modified my code to the above, This is all of it (except the server and password details). There are no OERN/OEG0 lines now. The row I am getting from the database has a 'Y' in the home_publish field, hence the first message box displaying false is correct. Just the second one displaying "Invalid use of Null" is the mystery. I am beginning to wonder if there is an issue with the MySQL Driver?
Now this is getting silly:
I changed the last 2 lines to these 3:
msgbox hemisphereResult("home_publish").value
msgbox isnull(hemisphereResult("home_publish").value)
msgbox hemisphereResult("home_publish").value
The first message box displays my value 'Y'.
Now the second message box displays true (which it obviously isn't).
And finally my third message box gives my "Invalid use of null" error.
Anyone else ever experienced variables losing their value just because you have used them?
If hemisphereResult is ADODB.Recordset, then hemisphereResult("home_publish") is ADODB.Field, at which point the following happens.
IsNull does not try to further investigate the passed object and returns False because the field itself exists as an object in the recordset.
MsgBox, on contrary, cannot do a meaningful thing to an object, so it calls the default property of that object (the Field object) in order to display it. The default property is .Value, and that is Null.
So despite the arguments to IsNull and MsgBox look the same in code, they are not actually the same.
You might want to be explicit in your demands:
msgbox isnull(hemisphereResult("home_publish").value)
While the above is true, you might have been affected by a MySQL bug too (44831, 42385 etc.)
The suggested workaround is to use client-side cursor:
set hemisphereResult = CreateObject("ADODB.Recordset")
hemisphereResult.CursorLocation = 3 'adUseClient
hemisphereResult.open "select ...", hemisphereConnection
What I did was append the checkboxes as additional columns of a query which was then used to create a recordset. This recordset was then assigned to a combobox control.
Previously, it worked fine for me to then reference columns of the selected row in the combobox that were not displayed. However, no matter what I try, when I attempt to reference these checkboxes, all I get is a null value.
To illustrate:
Set rs = db.OpenRecordset("SELECT AG.Acttype, AG.ActGroupID, AT.HasLots, AT.IsLotSrce, " _
& "AT.HasStructs FROM ActivityGroup AG, ActivityType AT WHERE (" _
& FormatToSQLVal(Me![WizardSubformDisplay].Form![ActLinkedProjInput].Column(1)) _
& " = AG.ProjectID) AND (AG.Acttype = AT.ActType);")
Set Me![WizardSubformDisplay].Form![ActTypeInput].Recordset = rs
(in this case there is the additional following tinkering which didn't cause trouble for other cases that didn't deal with checkboxes)
Me![WizardSubformDisplay].Form![ActTypeInput] = Me![ActTypeName]
Me![WizardSubformDisplay].Form![ActTypeInput].Locked = True
(I set the combobox to a specific choice and then lock it)
Me![WizardSubformDisplay].Form![ActTypeInput].Column(2),
Me![WizardSubformDisplay].Form![ActTypeInput].Column(3),
Me![WizardSubformDisplay].Form![ActTypeInput].Column(4)
all return null, rather than -1 if the box is checked and 0 otherwise.
I have an access form that runs a query. However it runs a query using vba code and sometimes it searches the table for text fields and sometimes for number fields depending on the field they choose on a combo box in the form.
I have left a note that if they wish to search for a text field they must enter double quotes or the code will not work. However, if the user does not follow these directions they will get a popup that exlains the coding issue with the options debug and end. I do not want them to see this message.
Is there a way to suppress this error message and write my own?
Edit:
Dim dbsCurrent As Database
Dim qryTest As QueryDef
varWhere = "WHERE InclusiveParent." & Combo0.Value & "=" & Text2
varWhere = "select Location, IcmService, IcmScript, ThresholdVariable, PbxVdn, Domestic, FirstSecondLook, DNIS, Tollfree, Outdial, Description, Carrier, DefaultTollfree, BlockedRoute, Variable3, Variable4, Variable5, Variable9, ValueScrVdn, Cvp from InclusiveParent " & varWhere
'Filter frmCustomers based on search criteria
'Dim dbsCurrent As Database
'Dim qryTest As QueryDef
Set dbsCurrent = CurrentDb
Set qryTest = dbsCurrent.QueryDefs("Broaden")
qryTest.SQL = varWhere
'Close frmSearch
DoCmd.Close acForm, "SearchDependents"
InclusiveParent is a query that I'm requery-ing and Broaden is the requery. SearchDependents is the name of the Form. Combo0 is a combo box that lets them select which field to choose to filter. And Text2 is the text field that they enter the filter criteria in. However, not all fields are numbers, so when they choose to filter by a text field they must enter double quotes or the code fails.
Try this and remove the note to require quotation marks:
varWhere = "WHERE InclusiveParent." & Combo0.Value & "="
If IsNumeric(Text2.Value) Then
varWhere = varWhere & Text2.Value
Else
varWhere = varWhere & """" & Text2.Value & """"
End If
Since Combo0.Value is the name of a field in InclusiveParent query, check the data type of that field. You can use that information to determine whether or not you need to wrap Text2.Value in quotes. By knowing the field's data type, you can also validate Text2.Value ... make sure it is a valid number when Combo0.Value is a number field. This will also allow you to ensure sure the value is quoted when the user enters only digits for Text2.Value but Combo0.Value is a text field.
Select Case dbsCurrent.QueryDefs("InclusiveParent").Fields(Me.Combo0.Value).Type
Case dbBigInt, dbByte, dbCurrency, dbDecimal, dbDouble, _
dbFloat, dbInteger, dbLong, dbSingle
If Not IsNumeric(Me.Text2.Value) Then
'* warn user and request a valid number *'
Else
'* build WHERE clause without quotes around Text2.Value *'
End If
Case dbChar, dbMemo, dbText
'* build WHERE clause with quotes around Text2.Value *'
Case Else
'* decide what you want for field which is neither text nor numeric *'
End Select