Microsoft Access How to retrieve current form ID to print - ms-access

I am trying to print a report called Carton Labels, and I want to print a specific record that the user just created. Every time I try using Me.cartonNo which is a actual field on the current form the user is on. He gets prompted for input. What am I doing wrong?
EDIT:
Dim strDocName As String
Dim strFilter As String
DoCmd.RunCommand acCmdSaveRecord
strDocName = "Carton Labels"
strFilter = "[cartonNo] = Forms![frm_addFinishedGoodsInventory]![cartonNo]"
DoCmd.OpenReport strDocName, acViewPreview, strFilter
my print button doesn't work, it acts as if nothing was stored in the strFilter, but if I create Dim intFilter As Integer and store it into a integer, I can clearly see the cartonNo if I set a break point, yet I dont in the strFilter.

You need to resolve the carton number before you pass it to OpenReport. By placing the Forms! reference outside the quotation marks like this:
strFilter = "[cartonNo] = " & Forms![frm_addFinishedGoodsInventory]![cartonNo]
you are creating the string [cartonNo] = 6 and then passing that to the report. If the field were a text field (or date), you'd need to include quotes (or #s) around the value.

Related

Editing listbox item

So i have a listbox that displays all the orders entered in the Order table using a select sql query. Now i also want to add the ability to edit the items from the listbox, i see the right click edit list item option but when i click it, it just opens the form but doesnt populate the fields. The form has textboxes that are unbound but i cant figure out how to get them to populate based on the right clicked entry. I have also tried to open the target form from vba and fill the fields through vba with the following code
Private Sub editrecordbttn_Click()
Dim valSelect As Variant
Dim v As Variant
Dim selector As Variant
Dim strValue As String ' just used for the demonstration
Dim splitvalue() As String
Dim selectedsampid As String
Dim selectedcusid As String
Dim Records As DAO.Recordset
Dim SQLcus As String
Dim SQLsamp As String
For Each valSelect In Me.searchlistbox.ItemsSelected
strValue = strValue & "" & Me.searchlistbox.ItemData(valSelect) & "," & "" & Me.searchlistbox.Column(1, valSelect) & ","
Next valSelect
' to remove trailing comma
strValue = Left(strValue, Len(strValue) - 1)
splitvalue() = Split(strValue, ",")
selectedsampid = splitvalue(0)
selectedcusid = splitvalue(1)
DoCmd.OpenForm ("Add Sample")
Forms![Add Sample].fnametxt.SetFocus
'query and fill cus info
SQLcus = "SELECT * FROM CustomerInfo WHERE CusID = '" & selectedcusid & "';"
Set Records = CurrentDb.OpenRecordset(SQLcus)
Me!clienttypetxt = Records![Client type].Value
End Sub
Ok, so say we have a listbox, and we do this:
The first column of the listbox is assumed to be the PK or "ID" of the rows.
so, we have this:
And thus you select a row, and then click on the button.
The button code would look like this:
Private Sub cmdEdit_Click()
Debug.Print "Hotel list id selected = " & Me.HotelList
DoCmd.OpenForm "frmEditHotels", , , "ID = " & Me.HotelList
End Sub
So, in most cases, for a better user experience, it probably better to approach things as per above.
There is of course the case in which you fill the listbox (or combo) with a "list" of values NOT from the database. In that case, you can use the "edit" list option. And this allows you to specify a form (or use the built in editor).
so, if this is NOT a list that you type in, and is from the database, then don't try to use the built in "list editing"
(add a button like above, and launch the form with the "where" clause to load the form to the ONE data record as I did above.
Since oh so very often, a listbox data will come from a table, then the edit list options are not really much particular use. And using a table (as opposed to a list) to fill + drive the combo/listbox is a much better design, and idea anyway.
This is especially the case if you ever want multiple-users, since the "list" edit feature would mean and suggest that each user editing the list would now have their own lists as opposed to using a table which everyone can edit.
Also, there is NO reason to use a loop to fill that list box. We can do this:
' setup critera for listbox.
Dim strSQL As String
' prompt user for Hotel city - we just hard code for this exmaple.
Dim strCity As String
strCity = "Banff"
strSQL = "SELECT ID,FirstName, LastName, City,HotelName FROM tblHotels " & _
"WHERE City = '" & strCity & "' " & "ORDER BY HotelName"
Me.HotelList.RowSource = strSQL
Note how we do not have some MESSAY value list, but can shove the data (sql) right to the listbox. Not only do we don't have loops, but we also don't have to worry about the size limits.
With "value list" (those messy delimited ";" list), then you have a rather small limit of 4,000 characters. Don't take many larger rows to "blow up" the listbox, since it can't handel very many rows.
In fact, I often still suggest you use the wizard to build the listbox, and you can choose a datasource (sql), or the MUCH lessor choice of "value list".
Value list is only a good choice if you have say a few choices like Mr., Mrs. or what not, and it not some large table, but only say 5-10 choices.
Anything larger? Use a data table driven listbox, and avoid use of value list.

Is it an access Bug? my problem with form filtering by txtBox entered value in a split DB

I have an Access 2016 DB 64bits contain related tables with a search split form that have an txtBox that filtered records accoring to its entered value.
Every thing is just fine with that for months and with thousands of records.
When I want to make it more proffesional to deploy it to other users by re-writing another similar DB but with 32bts Access 2016 and SPLIT it from the start into Tables Back-end and a Front end, the search form didn't show any record when I fire a searching parameter in the after update event!
the search form is linked to a query, I change it to a new one, also try to link the form directly to only one table for testing also not goes right, shows zero results.
when remove the filter, all records showing up again.
when I change the filter directly from the form properties it also fail for string search but when search for a primary key in a form control holding it its working just fine. ( search for Strings show no results, search for Numbers ( ex ID value, show correct results).
And Very strange, when I build another new DB (Same access application) just for testing for what is going on, with a form and joined to split back end tables and a textbox in the form to enter keywords to show the all related records in the that split form, it works fine, both for strings and for numbers?
Private Sub txtSearch_AfterUpdate()
Dim strFilter As String
On Error Resume Next
If Me.txtSearch.Text <> "" Then
strFilter = "[Complaints] Like '*" & Me.txtSearch.Text & "*'"
Me.Filter = strFilter
Me.FilterOn = True
Else
Me.Filter = ""
Me.FilterOn = False
End If
With Me.txtSearch
.SetFocus
.SelStart = Len(Me.txtSearch.Text)
End With
End Sub
when put a string into the txtsearch box , the code must search for any string with in [Complaints] similar to it and shows the records holding it.
with me it works in the old DB 64bits Not splitted, but its not working for the new DB 32bits split to back and front ends.
Be careful using .Text as it requires the control to have focus. So try:
Private Sub txtSearch_AfterUpdate()
Dim strFilter As String
' On Error Resume Next ' Don't use while debugging.
If Nz(Me!txtSearch.Value) <> "" Then
strFilter = "[Complaints] Like '*" & Me!txtSearch.Value & "*'"
Me.Filter = strFilter
Me.FilterOn = True
Else
Me.Filter = ""
Me.FilterOn = False
End If
With Me!txtSearch
.SetFocus
.SelStart = Len(.Value)
End With
End Sub

VBA Access Textbox returning Null Value

I have a VBA Access userform. In this useform there is a textbox with the name txtSearch_POBOX. I'm trying to get its value using the code below:
Private Sub txtSearch_FirstName_Change()
MsgBox ([Form_Client List].txtSearch_POBOX.Value)
End Sub
But this is constantly returning NULL. When even when there is a value inside the text box. Any ideas?
Your reference is wrong. It should read:
MsgBox Forms![Client List]!txtSearch_POBOX.Value
As it could be empty, you should use:
MsgBox Nz(Forms![Client List]!txtSearch_POBOX.Value)
remember that if you want to intercept the text box value while digiting, until you "validate" the content change (e.g. losing focus) the .Value property is not updated.
For instance I used a text box to make a running filter of a submask: I wanted to filter the submask while digiting.
To do this you need to use the .Text property.
In the following example I make a running filter of a list of Publishers:
Private Sub txtNameFilter_Change()
On Error Resume Next
Dim strFilter As String
If Not IsNull(Me.txtNameFilter.Text) Then
strFilter = "Publisher LIKE '*" + Me.txtNameFilter.Text + "*'"
Me.Filter = strFilter
Me.FilterOn = True
Me.txtNameFilter.SelStart = Len(Me.txtNameFilter.Text)
End If
End Sub
Bye
Wiz

how to write a script to look for and correct invalid entries in a table

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.

Databound CheckBoxList for Microsoft Access

In ASP.NET I have the option for building a CheckBoxList control from a data source where the values of the items can be the "Id" column (for example) while the text displayed next to the checkbox is from a "Name" column.
Is it possible to do something similar to this for Access 2003 with VBA? I am trying to avoid hardcoding the list of items if at all possible, but can't figure out how to do anything similar to this.
Just use a listbox. A list box in Access is great because it allows multiple columns, but will hide the first column as you ask. And you can just set the listbox to allow multiple selections (in the other tab of the property sheet for the listbox, set Multiselect to "simple"
And even better is you don't need any code to fill out the listbox, but can type in the sql or simply base the listbox on a SQL query.
So a listbox can look like this:
The code behind the button to turn the selected items into a useful list of PK id looks like this:
Private Sub cmdFax_Click()
Dim strIDList As String
Dim vID As Variant
Dim strSQLWhere As String
For Each vID In Me.lstFaxList.ItemsSelected
If strIDList <> "" Then strIDList = strIDList & ","
strIDList = strIDList & lstFaxList.ItemData(vID)
Next
If strIDList <> "" Then
strSQLWhere = " ID in (" & strIDList & ")"
End If
DoCmd.OpenReport "rptFax", acViewPreview, , strSQLWhere
End Sub
And if you want, you can in code for supply or set the SQL of the listbox like this:
Sub mytest()
Dim strSql As String
strSql = "Select ID, firstName, LastName, City " & _
"where city = 'Edmonton'"
Me.lstFaxList.RowSource = strSql
End Sub
So you don't need to type in any kind of list here. It not clear if you "must" have a actual check box here - you can use a continues form if you wanted, but I think the above is oh so much more simple and you don't need much code to set this up at all.