How to make a command button collection ms access - ms-access

Let’s say i have a 100 command buttons and images in an access form i need to deal with them as groups for example in English : Group1 includes commandbutton1 To Commandbutton10 and Image1 To Image10
me.group1.visible = false
The result would be hide buttons from 1 To 10 and hide images from 1 to 10
I need to declare the groups names and each group includes which command buttons and images then deal with them as i mentioned above how can i do that ? thanks in advance

One thing that you could look at is using the .Tag property of the controls. You could either just have a single piece of text and check for equality, or else you could have several pieces of text and check if a piece of text exists (which allows you to have controls being members of several groups). A basic example is:
Private Sub cmdVisible_Click()
On Error GoTo E_Handle
Dim ctl As Control
For Each ctl In Me.Controls
If ctl.Tag = "Group1" Then
ctl.Visible = Not ctl.Visible
End If
Next ctl
sExit:
On Error Resume Next
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "frmVisible!cmdVisible_Click", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Regards,

Related

How to reference control names dynamically in MS Access

I have the following code in an MS Access Form object.
Private Sub UpdatePMText(sLang As String)
'Used to pass both Mandate and Language Info to called Sub that will execute the queries
Dim iMandate As Integer
'Check if there is text in the box.
If Me.Controls("txtInput_PM_" & sLang & "_DRAFT") = Null Or Me.Controls("txtInput_PM_" & sLang & "_DRAFT") = "" Then
MsgBox ("There is no text in the " & sLang & " DRAFT Field." & vbNewLine & "The operation will not be executed.")
Exit Sub
End If
iMandate = Me.txtMandateID
Call modUpdateText.macro_PMText(iMandate, sLang)
End Sub
If I refer to the Controls directly and simply type out the names of the forms, for example txtInput_PM_EN_DRAFT then the code works as intended.
The error message I get is that Access can't find the "Field" I'm referring to when I am on the first IF statement line. I have tried changing the .Controls to .Fields but that didn't work either.
I do not want to repeat the same code for every language I need to run. How do I reference control names dynamically in MS Access? What am I missing?
I think you need to add some basic troubleshooting. The answer is probably simpler than you think. It's likely you're just trying to lookup a textbox with mispelled name or it's failing on the Null comparison (as suggested by #HansUp)
I would try modifying your basic sub and testing it with this subroutine. As long as your code is in your current form and you're not referencing a subform your method will work.
Private Sub UpdatePMText(sLang As String)
Const ERR_MISSING_CONTROL As Long = 2465
On Error GoTo Err_UpdatePMText
Dim sTextBox As String
sTextBox = "txtInput_PM_" & sLang & "_DRAFT"
'Check if there is text in the box.
If Nz(Me.Controls(sTextBox).Value, "") = "" Then
MsgBox ("There is no text in the " & sLang & " DRAFT Field." & vbNewLine & "The operation will not be executed.")
Exit Sub
End If
Exit Sub
Err_UpdatePMText:
If Err.Number = ERR_MISSING_CONTROL Then
MsgBox "Error: No Such Textbox: " & sTextBox
Else
MsgBox "Error Looking Up Textbox: """ & sTextBox & """" & vbCrLf & Err.Description
End If
End Sub

my for next loop is not working and gives error94

Cannot understand why my for and next loop is not working. What I am trying to do is to print a report for the same number of records details depending on the number value of a particular field called [nts].
If the field is empty it tells me I have error: 94. If the field has a value it goes to errorhandler mention in the program. Can any body be so kind and help me please? Thank you in advance :)** I am using ACCESS2007
Option Compare Database
Option Explicit
Private Sub Report_Close()
' Delete previous data from tabMeal
DoCmd.SetWarnings False
DoCmd.RunSQL "Delete from tabAmeal"
End Sub
Private Sub Report_Load()
Dim intNOM As Integer
'NOM means number of nights meals
Dim mTimes As Integer
On Error GoTo errorhandler
intNOM = 1
mTimes = 0
mTimes = DLookup("nz([nts],0)", "tabAmeal", "[nts] > 0")
'mTimes means number of meals
If mTimes = 0 Then
MsgBox "File is empty GO to Query" & vbCrLf & "Error - Run the Query", vbQuestion
Else
'now print the information found in table "tabmeal" number of times depending on the value field "nts"
For intNOM = 1 To mTimes
DoCmd.OpenReport "repAmeal?", acViewPreview
Next intNOM
End If
errorhandler:
MsgBox "Error #:- " & Err.Number & vbCrLf & "LOOP not working" & vbCrLf & "Must find why this error" & vbCrLf & Err.Description
End Sub
Private Sub Report_NoData(Cancel As Integer)
MsgBox "Please note that you have no records to report." & vbCrLf & "You have to run the QUERY to get the required informatio."
End Sub
The first problem:
Nz() must be used outside of DLookup, not inside:
mTimes = Nz(DLookup("[nts]", "tabAmeal", "[nts] > 0"), 0)
The second problem, I'm not sure. You can't open a report multiple times in acViewPreview (it will open only once), but it shouldn't give an error.
What is the exact error message you get when nts > 0 ?
Oops. You need Exit Sub befor your errorhandler: line - the code simply enters the error handler, without there being an error. :)

How is this returning a blank value?

So this code is meant to serve as a simple search system to go to certain records in a recordset. I originally had it so they had to click the btnGoToID button in order to perform the search. I decided to just make it a little more user friendly and make it so the search field listened for the Enter button and that would perform the search as well.
The issue that I am running into when the code gets to strID = Trim(Nz(Me.txtSearch.Value, "")) the value will randomly come back as an empty string even though visually I can see that there is a value in the textbox.
I haven't been able to narrow down any pattern for when this issue occurs. At this point I don't really even know how to troubleshoot this problem, nor the words to search for that could yield any results in Google. All I can say is that it SEEMS like changing between records will affect whether or not the search goes through.
This has always worked up until I put in the txtSearch_KeyPress sub procedure.
'============================================================================
' txtSearch_KeyPress
'============================================================================
Private Sub txtSearch_KeyPress(KeyAscii As Integer)
'If user pressed enter
If KeyAscii = 13 Then
Call btnGoToID_Click
End If
End Sub
'============================================================================
' btnGoToID_Click
'============================================================================
' <<Purpose>>
' Allow the user to search for a specific ID
'============================================================================
Private Sub btnGoToID_Click()
On Error GoTo Err_Handler
Dim rs As Recordset
Dim strID As String
Set rs = Me.RecordsetClone
strID = Trim(Nz(Me.txtSearch.Value, ""))
If (strID <> "") Then
'Go to the ID
rs.FindFirst "ID = '" & strID & "'"
If rs.NoMatch Then
MsgBox "ID does not exist"
Else
'If we have a match, set the record as the current record
Me.Bookmark = rs.Bookmark
End If
Else
MsgBox "Please enter a valid ID.", vbOKOnly, "Invalid ID"
End If
Exit_Handler:
On Error Resume Next
Me.txtSearch.Value = ""
rs.Close
Set rs = Nothing
Exit Sub
Err_Handler:
Call LogError(Err.Number, Err.Description, "txtSearch on " & Me.Name)
Resume Exit_Handler
End Sub
After the conversation in the comments I have narrowed down this question to be a whole lot simpler. This yields an "Invalid use of null" error message even after there are several characters in the text field. Why would that happen, and what can I do to make it pick up the values in the textbox?
'============================================================================
' txtUnitNoToSearch_KeyPress
'============================================================================
Private Sub txtUnitNoToSearch_KeyPress(KeyAscii As Integer)
MsgBox Me.txtUnitNoToSearch
End Sub
I think your problem is related to the fact that a text box has 2 properties, .Value and .Text, which appear similar but behave differently.
While you have an edit in progress in the text box, the changing content is available via the .Text property. However, the content of the .Value property has not yet been updated to match.
After the text box's After Update event, .Value will contain the new content. And if focus has moved away from the text box, its .Text property will no longer even be available.
Sorry, I couldn't think how to explain that better. But I think the situation will be clearer with this KeyPress event procedure:
Private Sub txtUnitNoToSearch_KeyPress(KeyAscii As Integer)
Debug.Print "Text: '" & Me.txtUnitNoToSearch.Text & "'"
Debug.Print "Value: '" & Me.txtUnitNoToSearch.Value & "'"
End Sub
Watch the output from Debug.Print in the Immediate window as you make changes to the context of the text box. (Ctrl+g will open the Immediate window.)
One final point is that just Me.txtUnitNoToSearch gets you its default property which is .Value. Keep that in mind as you work through the rest of your code.

Can two different continuous forms run off the same queryi in access 2010?

So I have two subforms, one to show internal training course completion for an employee and the other is the same thing but for vendor training.
Both subforms pull the same data from the same table, but display different selective data (different columns from the table).
I added the employee search combobox code to reflect the second "vendor training" subform:
Private Sub cboEmployee_AfterUpdate()
On Error GoTo Proc_Error
If IsNull(Me.cboEmployee) Then
Me.subEmployeeCourseTrainingCompletion.Form.Filter = ""
Me.subEmployeeCourseTrainingCompletion.Form.FilterOn = False
Me.subEmployeeVendorCourseTrainingCompletion.Form.Filter = ""
Me.subEmployeeVendorCourseTrainingCompletion.Form.FilterOn = False
Else
Me.subEmployeeCourseTrainingCompletion.Form.Filter = "[EmployeeID]=" & Me.cboEmployee
Me.subEmployeeCourseTrainingCompletion.Form.FilterOn = True
Debug.Print Me.subEmployeeCourseTrainingCompletion.Form.Filter
Me.subEmployeeVendorCourseTrainingCompletion.Form.Filter = "[EmployeeID]=" & Me.cboEmployee
Me.subEmployeeVendorCourseTrainingCompletion.Form.FilterOn = True
Debug.Print Me.subEmployeeVendorCourseTrainingCompletion.Form.Filter
End If
Proc_Exit:
Exit Sub
Proc_Error:
MsgBox "Error " & Err.Number & " in setting subEmployeeCourseTrainingCompletion filter:" & vbCrLf & Err.Description
MsgBox "Error " & Err.Number & " in setting subEmployeeVendorCourseTrainingCompletion filter:" & vbCrLf & Err.Description
Resume Proc_Exit
End Sub
The internval training subform still works and updates based on the employee ID in the combobox, but the second, vendor, subform doesn't update.
Any ideas as to why and possible solutions?
Force the update of the second form once you have made changes and saved the data in the first one:
Me.subEmployeeVendorCourseTrainingCompletion.Form.Requery
You could do this in the Form_AfterUpdate of the first subform:
Private Sub Form_AfterUpdate()
Parent.subEmployeeVendorCourseTrainingCompletion.Form.Requery
End Sub
UPDATE
Try another approach. Instead of setting filters use the Link Child Fields and Link Master Fields properties of the subforms in order to link the subforms to the main form.

Possible to set filter on subform from parent form before subform data loads

I have frmParentForm with multiple controls used to build a filter for frmSubForm.
On frmParentForm_Load, I am doing (simplified example):
Me.sbfInvoice_List.Form.filter = "[created_on] >= #" & Me.RecentOrderDateCutoff & "#"
Me.sbfInvoice_List.Form.FilterOn = True
The problem is, on initial load, it seems the subform load is occurring first, so the entire table is loaded.
Is there a way (in a different event perhaps) to properly set the subform filter from the parent form so it is applied before the subform does its initial data load? (The subform can exist on its own, or as a child of many different parent forms (sometimes filtered, sometimes not), so I'd rather not put some complicated hack in the subform itself to accomplish this.)
Because the subform loads before the parent form, the parent form can not set a subform filter before the subform initially loads.
If you want to use the subform flexibly (all records when stand alone, but different subsets of records when included on different parent forms), I think you have to modify the subform to do it.
Private Sub Form_Open(Cancel As Integer)
Dim strParent As String
Dim strMsg As String
On Error GoTo ErrorHandler
strParent = Me.Parent.Name
Select Case strParent
Case "frmYourParentForm"
'set filter to only records from today '
Me.Filter = "[created_on] >= #" & Date() & "#"
Me.FilterOn = True
Case "frmSomeOtherParent"
'do something else '
End Select
ExitHere:
On Error GoTo 0
Exit Sub
ErrorHandler:
Select Case Err.Number
Case 2452
'The expression you entered has an invalid reference to '
'the Parent property. '
Resume Next
Case Else
strMsg = "Error " & Err.Number & " (" & Err.Description _
& ") in procedure Form_Open"
MsgBox strMsg
End Select
GoTo ExitHere
End Sub
Edit: If you want to track the sequence of events in the parent form and subform, you can add procedures like this one to the forms' modules.
Private Sub Form_Load()
Debug.Print Me.Name & ": Form_Load"
End Sub
Here is what I get when tracking the Open and Load events for my parent form and subform.
fsubChild: Form_Open
fsubChild: Form_Load
frmParent: Form_Open
frmParent: Form_Load