How to create a universal MS Access form? - forms

I have a database that has a two tables which differ only in several fields so I thought of creating a single form for them and adding an option group (radio switch) witch would determine to which table the data from fields should go. The thing i I dont know how to hange the destination and some field should be hidden or at least on one but not another option.
This gave me an idea that for small databases this could be used to create universal form.
How to control data destination from form field in MS Access depending on option goup?

You can call different tables based on variables you create in a blank form. Here's an example if you use the table name in a combo box.
Dim var as String
Dim myR as Recordset
var = me.combo_box_name.column(0)
Set myR = CurrentDb.OpenRecordset (var, dbOpenDynaset)
'Code here based on variable, use an if statement if you want
Set myR = Nothing

Related

Role-based Form recordsource

Is there a best practice around opening a form based on recordsources whose columns are limited by the user's role?
We have some users who modify data that don't want to see the columns marking criteria for inclusion on different reports (columns with boolean values named isOnRpt1, isOnRpt2, etc. used for filtering purposes) and other users who only run reports that need to sort and filter data but not see columns used for internal calculations. Say we have 65 columns total and everyone wants to see the same 5 key columns and 10 filtering columns but some users need visibility of 30 additional columns and others want to see 20 other columns. What I have now is the God view with all of everyone's columns, and it's freaking them out.
Is there a best practice for maintaining a form for users in different roles whose datasheet view contains different subsets of columns? I'm not worried about visibility of controls on the form view, users in the reporter role won't use that view at all.
I don't want to create different forms for each role (frmDetailReporter, frmDetailWriter) whose only difference is the qry in the recordsource property. I have a main form staff in any role could use to navigate to a role-specific instance of this detail form (they need to navigate to other forms with aggregate data) but I'm not sure if I should have an entry point for each role in the form's VBA code or change the recordsource property before opening the form or if there's a better way to support users of different views of the same data source.
TIA
Let's say I've identified two roles, Reporter and Writer. I can create two queries for those roles, qryDetailReporter and qryDetailWriter with different columns. I have two buttons on a main form for the two different roles, btnDetailReporter and btnDetailWriter used to open the shared detail form, frmDetail, containing all the VBA code for all the roles. Is there a best practice for the VBA code behind frmMain.btnDetail* for loading frmDetail? I'd like to set the recordsource property to one of the two queries before loading the form, but Access forms don't work that way, so I'm thinking I could have a global variable containing a roleID referenced in frmDetail's load event that sets the recordsource property, but I'd prefer to do this without a global variable.
Here's what I have now:
' module
Public g_roleID As Integer
' frmMain
Private Sub btnDetailWriter_Click()
g_roleID = 1
DoCmd.OpenForm "frmDetail", acFormDS
End Sub
Private Sub btnDetailReporter_Click()
g_roleID = 0
DoCmd.OpenForm "frmDetail", acFormDS
End Sub
' frmDetail
Private Sub Form_Open(Cancel As Integer)
Dim objCtl As Control
Dim sTxt As String
Dim sFld As String
Select Case g_roleID
Case 0
RecordSource = "qryDetailReporter"
Case 1
RecordSource = "qryDetailWriter"
Case Else
RecordSource = "vw_detail"
End Select
On Error GoTo noFld
For Each objCtl In Controls
Select Case objCtl.ControlType
Case acTextBox, acComboBox
sTxt = objCtl.ControlSource
objCtl.ColumnHidden = False
sFld = RecordsetClone.Fields(sTxt) & ""
End Select
Next
Exit Sub
noFld:
objCtl.ColumnHidden = True
Resume Next
End Sub
I would suggest to create different queries for each role with different set of fields and change RecordSource property of form depending on user role. The form should have set of all available columns. After selecting required recordsource a simple VBA code should compare set of available fields in recordsource with set of ControlSource properties of each form's control. If the field is missing in recordsource, hide the column using ColumnHidden control's property.

How to store DLookup from [Form] to Table Field in MsAccess 2013?

I have two MS Access tables: IdMhs and T_UKT. I want to automatically fill in [IdMhs].[SPP] from some criteria in [T_UKT].[UKT]. I cannot put it in query relationship, because the row cannot be edited on a form.
So I make a form and I get the number SPP (a textbox on form) automatically by using and it works fine:
=DLookUp("SPP";"T_UKT";"UKT = " & [Form].[UKT])
The problem is: the lookup value just shows on the form, and the results are not filled in the field in table ([IdMhs].[SPP]).
Any idea what an expression I should write to fill it in IdMhs table automatically?
Need macro or VBA code to save value into table. If form is bound to IdMhs table, simply like:
Me!SPP = Me.tbxSPP
The real trick is figuring out what event to put the code into. You have a control (possibly combobox) where the UKT value is selected? Use its AfterUpdate event.
Why do you need to save the SPP value and not just retrieve it in a query that joins tables?
What is nature of table relationship? Is T_UKT a lookup table? If so should be able to include it in form RecordSource and then the SPP value would be available for display in textbox and DLookup not needed. Domain aggregate functions can perform slowly on forms and reports and should be a last resort option. The same code would be used to save the value. The query join should be 'show all records from IdMhs and only those from T_UKT that match'. Set textbox bound to T_UKT SPP field as Locked Yes, TabStop No.

How to add a multiple values field to an MS Access form

I have a database which records and tracks the training records for each employee within our group of companies.
One of the forms on the database is 'add training record' and currently this is done per person ID, adding the course id, date, certificate, etc. What I would love to do is be able to add multiple person IDs, as a number of people can attend the same course/ date, so I have to add the course details in many times, which is very time consuming and annoying.
You're going to need extensive VBA behind the scenes to do this, as well as a couple of controls to make your life easier (multi-select combo or list boxes). You could do it in a text box if you want, using the semi-colon between User IDs.
Since the text box is easier, let's look at that. What you would do is have something like this behind the Submit button:
Dim db as Database
Dim rec as Recordset
Dim str as String
Set db = CurrentDB
Set rec = db.OpenRecordSet("SELECT * FROM tblMyTable")
'Throw the User IDs into an array
Dim var As Variant
Dim i As Long
str = me.txtUserIDs
var = Split(str, ";")
'For every User ID, add a new record to the database
For i = 0 To UBound(var)
rec.AddNew
rec("UserID") = var(i)
rec("CourseID") = Me.txtCourseID
rec("CourseDate") = Me.txtCourseDate
'ETC... adding fields as needed
rec.Update
Next i
This is completely off-the-cuff and (of course) requires you to change the appropriate variable names, but it should give you a solid outline for how to solve the problem.

Trying to design form to query and edit records Access

I'm trying to make an Access database where we can scan in a list of bar-codes, batch edit information for them, then save all the records. Later, they will need to be scanned again to batch edit more information such as shipping and order numbers.
Does anyone have suggestions on how to best design this? To start with, I've (1) made separate tables for "orders" and "parts" and (2) created a form of text boxes and a button attempting to apply this info to a part subform where records are created via the bar-code scanner. I'm a rather new Access designer. Thanks!
The questions are:
I'm not sure how to query these records via the bar code (Part_ID field) to apply order information to them later.
I can't currently update all new part records at once through my form.
Here's a little guide on how to do it. Let me know if you have any questions.
Dim db As DAO.Database
Dim Rs As DAO.Recordset
'Here is an example of a vba qarry in access. tblOrdersWhere is obviously your table.
'orderNum is a column name in your table pref a primary key
'txtOrderNum.Value is the value of a text box
'If you want just a simple select * from table you can put after db.OpenRecordset("tblOrders")
set rs = db.OpenRecordset("Select * from tblOrders Where orderNum like '*" & txtOrderNum.Value & "*';", dbOpenDynaset)
'This is how you update records in Access
'If you want to update it's Rs.Edit instead of Rs.AddNew
Rs.AddNew
Rs("OrderItem").Value = txtGroupName.Value
Rs("OrderTime").Value = txtGroupNum.Value
rs.Update

Create a new FileMaker layout showing unique records based on one field and a count for each

I have a table like this:
Application,Program,UsedObject
It can have data like this:
A,P1,ZZ
A,P1,BB
A,P2,CC
B,F1,KK
I'd like to create a layout to show:
Application,# of Programs
A,2
B,1
The point is to count the distinct programs.
For the life of me I can't make this work in FileMaker. I've created a summary field to count programs resetting after each group, but because it doesn't eliminate the duplicate programs I get:
A,3
B,1
Any help much appreciated.
Create a a summary field as:
cntApplicaiton = Count of Application
Do this by going into define fields, create a field called cntApplication, type summary. In the options dialogue make the summary field a count on application
Now create a new layout with a subsummary part and nobody. The subsummary should be sorted on Application. Put the Application and cntApplication fields in subsummary. If you enter browse mode and sort by Application you ought to get the data you want.
You can also create a calc field with the formula
GetSummary(cntApplication; Application)
This will allow you to use the total number of Applications with in a record
Since I also generate the data in this form, the solution I've adopted is to fill two tables in FileMaker. One provides the summary view, the other the detailed view.
I think that your problem is down to dupliate records and an inadequate key.
Create a text field called "App_Prog". In the options box set it to an auto-enter calc, unchecking the 'Do not replace...' option, and use the following calc:
Application & "_" & Program
Now create a self join to the table using App_Prog as the field on both sides, and call this 'MatchingApps'.
Now, create (if you don't alread have one) a unique serial number field, 'Counter' say, and make sure that you enter a value in each record. (Find all, click in the field, and use serial number option in'Replace Field Contents...')
Now add a new calc field - Is_Duplicate with the following calc...
If (Counter = MatchingApps::Counter; "Master Record" ; "Duplicate")
Finally, find all, click in the 'Application field, and use 'Replace Field Contents...' with a calculation to force the auto-enter calc for 'App_Prog' to come up with a value.
Where does this get you? You should now have a set of records that are marker either "Master Record" or "Duplicate". Do a find on "Master Record", and then you can perform your summary (by Application) to do a count of distinct application-program pairs.
If you have access to custom functions (you need FileMaker Pro Advanced), I'd do it like this:
Add the RemoveDuplicates function as found here (this is a recursive function that takes a list of strings and returns a list of unique values).
In the relationships graph, add another occurrence of your table and add an Application = Application relationship.
Create a calculated field in the table with the calculation looking something like this:
ValueCount(RemoveDuplicates(List(TABLE2::Program)))
You'll find that each record will contain the number of distinct programs for the given application. Showing a summary for each application should be relatively trivial from here.
I think the best way to do this is to create a separate applications table. So as you've given the data, it would have two records, one for A and one for B.
So, with the addition of an Applications table and your existing table, which I'll call Objects, create a relationship from Applications to Objects (with a table occurrence called ObjectsParent) based on the ApplicationName as the match field. Create a self join relationship between Objects and itself with both Application and Program as the match fields. I'll call one of the "table occurrences" ObjectsParent and the other ObjectsChildren. Make sure that there's a primary key field in Objects that is set to auto-enter a serial number or some other method to ensure uniqueness. I'll call this ID.
So your relationship graph has three table occurrences:
Applications::Applicaiton = ObjectsParent::Application
ObjectsParent::Application = ObjectsChildren::Application, ObjectsParent::Program = ObjectsChildren::Program
Now create a calculation field in Objects, and calculating from the context of ObjectsParent, give it the following formula:
AppCount = Count( ObjectsChildren::ID )
Create a calculation field in Applications and calculating from the context of the table occurrence you used to relate it to ObjectsParent with the following formula:
AppCount = ObjectsParent::AppCount
The count field in Objects will have the same value for every object with the same application, so it doesn't matter which one you get this data from.
If you now view the data in Applications in list view, you can place the Applications::Application and Applications::AppCount fields on the layout and you should get what you've requested.