How to create Access User Form to both look up and add data - sql

I have an access form that contains two subforms. The main form has three dropdown fields that allow the user to pick what data is displayed in the two linked subforms. The dropdown fields are all unbound as they are referenced in the datasource of the main form.
The SQL of the datasource for the main form is as follows:
SELECT tbl_RptPeriod.RptPrdID, tbl_BusUnits.UnitID, tbl_Categories.CategoryID, tbl_Categories.CategoryTitle, tbl_Categories.CategoryGroup, tbl_Categories.Inactive, tbl_Categories.RptPrdID, tbl_Categories.UnitID
FROM tbl_RptPeriod INNER JOIN (tbl_BusUnits INNER JOIN tbl_Categories ON tbl_BusUnits.UnitID = tbl_Categories.UnitID) ON tbl_RptPeriod.RptPrdID = tbl_Categories.RptPrdID
WHERE (((tbl_RptPeriod.RptPrdID)=[Forms]![Compliance]![cmbReportPeriod]) AND ((tbl_BusUnits.UnitID)=[Forms]![Compliance]![cmbBusinessUnit]) AND ((tbl_Categories.CategoryID)=[Forms]![Compliance]![CategoryTitle]));
This works perfectly to look up records. However, I want the users to be able to add new records to the ones they are looking up. That doesn't work as it should.
I can add records, but then the form elements that I am using to look up the data, specifically RptPrdID,UnitID, and CategoryID are not being populated in the table, thus the new records are unassociated and don't show up if you go to look for them again in the main form after closing it or moving to another record.
This makes sense in so far as the form elements I am using in the "WHERE" criteria of the SQL are unbound, but of course, if I add a new record, I want it to be correctly matched. The user must be able to find the records he adds if he looks up the same criteria again.
Question:
How can I get new records entered in the subforms to have RptPrdID,UnitID, and CategoryID filled in?
UPDATE
SELECT tbl_Activity.CategoryID AS CategoryID_X, tbl_Activity.RptPrdID AS RptPrdID_X, tbl_Activity.UnitID AS UnitID_X, tbl_Categories.SortKey, tbl_Categories.CategoryTitle, tbl_Categories.CategoryGroup, tbl_Categories.Inactive, tbl_Categories.Inactive, tbl_BusUnits.Unit_Name, tbl_RptPeriod.Rep_Month_Nr, tbl_RptPeriod.Rep_Month_Name, tbl_RptPeriod.Rep_Year
FROM tbl_RptPeriod INNER JOIN (tbl_Categories INNER JOIN (tbl_BusUnits INNER JOIN tbl_Activity ON tbl_BusUnits.UnitID = tbl_Activity.UnitID) ON tbl_Categories.CategoryID = tbl_Activity.CategoryID) ON tbl_RptPeriod.RptPrdID = tbl_Activity.RptPrdID
WHERE (((tbl_Activity.CategoryID)=[Forms]![Compliance_EXPERIMENT]![cmbCategoryTitle]) AND ((tbl_Activity.RptPrdID)=[Forms]![Compliance_EXPERIMENT]![cmbReportPeriod]) AND ((tbl_Activity.UnitID)=[Forms]![Compliance_EXPERIMENT]![cmbBusinessUnit]))
ORDER BY tbl_Categories.SortKey;
I had to change the query somewhat, but the key fields are still the same ones, though they are now on a different table.
Private Sub Form_BeforeInsert(Cancel As Integer)
Me.RptPrdID_X = Me.cmbReportPeriod
Me.UnitID_X = Me.cmbBusinessUnit
Me.CategoryID_X = Me.cmbCategoryTitle
End Sub

Add code for filling those 3 fields in Before Insert event of main form
Private Sub Form_BeforeInsert(Cancel As Integer)
Me.RptPrdID = Me.cmbReportPeriod
Me.UnitID = Me.cmbBusinessUnit
Me.CategoryID = Me.CategoryTitle
End Sub

Related

Make an MS Access Report label visible based on data in the report's record source query

In MS Access, I have a report based on a query that presents a summary of a medical checkup. I would like labels for each test to be visible ONLY when those tests were performed. For example, if Glucose was performed on a patient, then the label "lblGlucose" should appear in the report, next to the result. The results currently are present in the report, the problem is when a test is not performed the label is always present. This gives the patient a feeling that the testing was not performed correctly.
To hide the labels I have tried the following approaches:
Private Sub Report_Load()
'1st approach: Lookup column [GLUCOSE] from query qrySummary if not null then set visible property of label lblGLUCOSE to True, else set property to False
IIF(IsNotNull(DLookup("[GLUCOSE]", "qrySummary")),Me!lblGLUCOSE.Visible = True,Me!lblGLUCOSE.Visible = False)
'2nd approach: If value of field [GLUCOSE_RSLT] from table tblResults make textbox txtGlucose visible. FYI: Table tblResults is the table that holds all the results of all the test performed. The query qrySummary derives from this table.
Me!txtGlucose.Visible = Not IsNull([tblResults]![GLUCOSE_RSLT])
'3rd approach: Count column [GLUCOSE], from query qrySummary and if greater than 0 then label lblBHClbl visible
End Sub
I'm still coding the 3rd approach but I'm pretty much running out of ideas and getting nowhere. For first two approaches I get field or expression not found. I don't need for all approaches to work, just one, -in fact, I'm open to other ideas on how I can accomplish the above task.
Any help would be ENORMOUSLY appreciated! Thanks a million!
I'm sharing my DB structure for better understanding
The SQL statement for the summary report is:
PARAMETERS [Forms]![frmIngresoEmpleados]![IDChequeo] Long;
SELECT TblClienteCorp.NombreEmpresa, TblClienteCorp.Direccion, tblChequeo.IDChequeo, tblChequeo.FechaMuestreo, tblChequeo.ChequeoPeriodico, qryCountGenero.*, tblEmpleadosClienteCorp.Genero, tblResultados.Aud_RSLT, tblResultados.Otos_RSLT, tblResultados.AV_RSLT, tblResultados.EKG_RSLT, tblResultados.FR_RSLT, tblResultados.TGP_RSLT, tblResultados.TGO_RSLT, tblResultados.CS_RSLT, tblResultados.ESP_RSLT, tblResultados.PB_RSLT, tblResultados.BHC_RSLT, tblResultados.Plaquetas_RSLT, tblResultados.EGO_RSLT, tblResultados.EGH_RSLT, tblResultados.VDRL_RSLT, tblResultados.Gluc_RSLT, tblResultados.Col_RSLT, tblResultados.EFEC_RSLT, tblResultados.PL_RSLT, tblResultados.Derm_RSLT, tblResultados.Isop_RSLT, tblResultados.BAAR_RSLT, tblResultados.ExFarin_RSLT, tblResultados.Lep_RSLT, tblResultados.Copro_RSLT, tblResultados.Osteo_RSLT, tblResultados.RX_RSLT, tblResultados.US_RSLT
FROM TblClienteCorp INNER JOIN ((tblChequeo INNER JOIN (tblEmpleadosClienteCorp INNER JOIN qryCountGenero ON tblEmpleadosClienteCorp.IDEmpleado = qryCountGenero.IDEmpleado) ON tblChequeo.IDChequeo = tblEmpleadosClienteCorp.IDChequeo) INNER JOIN tblResultados ON tblEmpleadosClienteCorp.IDEmpleado = tblResultados.IDEmpleados) ON TblClienteCorp.IDClienteCorp = tblChequeo.IDClienteCorp
WHERE (((tblChequeo.IDChequeo)=[Forms]![frmIngresoEmpleados]![IDChequeo]));
Within the report that is one query per test, which is:
PARAMETERS [Forms]![frmIngresoEmpleados]![IDChequeo] Long;
SELECT Count(tblResultados.IDEmpleados) AS CuentaDeIDEmpleados, tblResultados.Gluc_RSLT, tblEmpleadosClienteCorp.IDChequeo
FROM tblEmpleadosClienteCorp INNER JOIN tblResultados ON tblEmpleadosClienteCorp.IDEmpleado = tblResultados.IDEmpleados
GROUP BY tblResultados.Gluc_RSLT, tblEmpleadosClienteCorp.IDChequeo
HAVING (((tblResultados.Gluc_RSLT)="P") AND ((tblEmpleadosClienteCorp.IDChequeo)=[Forms]![frmIngresoEmpleados]![IDChequeo]));
If qrySummary has multiple patient records, need WHERE CONDITION criteria:
Me.lblGlucose.Visible = Not IsNull(DLookup("[GLUCOSE]", "qrySummary", "PatientID=" & Me!PatientID))
However, VBA is not necessary. Calculate in textbox (or in query and bind textbox to calculated field) and set control with transparent BorderStyle. Options:
show "None" text when no data:
=Nz(DLookup("[GLUCOSE]", "qrySummary", "PatientID=" & Me!PatientID), "None").
instead of label, use a textbox with expression:
=IIf(IsNull(DLookup("[GLUCOSE]", "qrySummary", "PatientID=" & Me!PatientID)), "", "Glucose")

Accessing Data in Listbox columns not displayed

I have a ListBox with several columns of data. I want to display 6 columns of data and populate hidden textboxes with other data in order to reference for other call.
The information is a SQL statement stored in the rowsource of my listbox.
SELECT TBLactionstaken.ProcessedDate, TBLreasons.Description,
TBLactionstaken.MANHType, TBLactionstaken.ActionStatus,
TBLactionstaken.ReceiptDate, TBLactionstaken.LetterTo,
TBLactionstaken.ActionTakenID, TBLactionstaken.TranProcDate,
TBLactionstaken.RecordNumber, TBLactionstaken.ActionDate,
TBLreasons.ReasonID FROM TBLreasons
RIGHT JOIN TBLactionstaken ON
TBLreasons.ReasonID = TBLactionstaken.ReasonID
WHERE (((TBLactionstaken.ActionStatus)="Processed" Or (TBLactionstaken.ActionStatus)="Received" Or (TBLactionstaken.ActionStatus)="Printed by PS")
AND ((TBLactionstaken.TranProcDate) Is Null)
AND ((TBLactionstaken.RecordNumber)=[Forms]![frmParticipant]![txtRecordNumber]) AND ((TBLactionstaken.ActionDate)>=Now()-180)
AND ((TBLreasons.ReasonID)=20 Or (TBLreasons.ReasonID)=21 Or (TBLreasons.ReasonID)=22 Or (TBLreasons.ReasonID)=36 Or (TBLreasons.ReasonID)=38 Or (TBLreasons.ReasonID)=42 Or (TBLreasons.ReasonID)=34))
ORDER BY TBLactionstaken.ActionTakenID DESC;
The first 6 items in the select will be the columns of my listbox, the other items I would like to reference in my textboxes. I am able to pull the items displayed in VBA with:
txtDesc = [lstAssignTransactions].[Column](1)
txtReasonDesc = [lstAssignTransactions].[Column](4)
txtReasonID = [lstAssignTransactions].[Column](3)
How do I reference the information not displayed. I did try to utilize:
txtActionID = [lstAssignTransactions].[Column](7)
because this information would technically be the 7th column, but no luck.

Cascading Combo Box on Form not allowing any selection

I have a form with 2 different cascading combo boxes set-up. Each has one box that requeries a second combo box after a selection is made. The second combo has criteria to only show values that correspond with the selection chosen in the first box.
The AfterUpdate() event is with a macro:
Requery
Control Name: StageID
Example: ProjectType is box 1, with choices of either Capital or Development. The selection then influences the drop down on the Stage combo box. The table structure that they are generated from is 3 fields: "StageID", "StageName" and "ProjectType", therefore all 3 fields are in the Stage combo box with only the stage name being shown and the "ProjectType" being linked using criteria: [Forms]![Project Update]![ProjectType]
The SQL are as follows
ProjectType - Value List
Stage -
SELECT Stage.StageID, Stage.StageName
FROM Stage
WHERE (((Stage.ProjectType)=[Forms]![Project Update]![ProjectType]));
Business -
SELECT Business.BusinessID, Business.Business
FROM Business;
Problem Statement -
SELECT ProblemStatements.ProblemStatementID, ProblemStatements.ProblemStatement
FROM ProblemStatements
WHERE (((ProblemStatements.BusinessID)=[Forms]![Project Update]![Combo493]));
The control sources for the Stage and ProblemStatemenet fields are from a table named ProjectList which has the fields ProjectID which is filtering the form as well as the fields ProblemStatementID and StageID. The business and ProjectType fields however have a control source from the "ProblemStatement" table and the "Stage" table respectively.
The combo boxes update fine, however after it is requeried/the Project type is changed I am unable to select a new Stage. If I change it back to the original Project Type the original stage is automatically chosen but I'm unable to select a different one. Also, I can change the stage before I select a projecttype (before the first requery).
I'm having the exact same problem with a Business/ProblemStatement combo, the only difference is the table structure.
Table 1: Business, fields: BusinessID and Business
Table 2: ProblemStatements, fields: ProblemStatementID, BusinessID, ProblemStatement
The SQL for the query that is generating the form is as follows:
SELECT ProblemStatements.BusinessID, Business.Business,
ProjectList.StageID, Stage.ProjectType, ProjectList.ProjectID,
ProjectList.ProjectTitle, ProjectList.SiteID, ProjectList.CodeName,
ProjectList.Type, ProjectList.RegionalGlobal, ProjectList.Category,
ProjectList.Status, ProjectList.StartDate, ProjectList.Sensitivity,
ProjectList.ProblemStatementID, ProblemStatements.ProblemStatement,
ProjectList.Attachment, ProjectList.Keywords, ProjectList.Tracking
FROM (Stage RIGHT JOIN (Site RIGHT JOIN (ProblemStatements RIGHT JOIN
ProjectList ON ProblemStatements.ProblemStatementID =
ProjectList.ProblemStatementID) ON Site.SiteID = ProjectList.SiteID) ON
Stage.StageID = ProjectList.StageID) LEFT JOIN Business ON
ProblemStatements.BusinessID = Business.BusinessID;
I am using the same method on a form that is used strictly for new data entry and it works fine. The form its not working on is used for updating existing records.

Incorrect use of DISTINCT

I have a form view that displays the ListingID, PropertyID, ListingAgentID, SaleStatusID, EndListDate and AskingPrice from a database in SQL.
I have a DropDownList that displays the LastNames of agents that when selected it returns back the relevent information in the formView corresponding to the selection.
It's working, but the only problem is that each last name in the dropDownList is duplicated as they each have more than one listing. What I need it to do is when selecting one last name from the DropDownList it returns one value in the FormView, while being able to use paging to view different listings from that agent.
The code in the FormView is:
SELECT[ListingID],
[PropertyID],
[ListingAgentID],
[SaleStatusID],
[EndListDate],
[AskingPrice]
FROM [Listings]
WHERE ([ListingID] = #ListingID)
The code in the DropDownList is:
SELECT Agents.LastName,
Listings.ListingID,
Listings.PropertyID,
Listings.ListingAgentID,
Listings.SaleStatusID,
Listings.BeginListDate,
Listings.EndListDate,
Listings.AskingPrice
FROM Agents
INNER JOIN Listings
ON Agents.AgentID = Listings.ListingAgentID
Where ever I try and put a DISTINCT function it returns an error or doesn't work
Thanks
For the dropdown all you need is an ID as value and the LastName to display.
SELECT DISTINCT Agents.LastName FROM Agents INNER JOIN Listings ON Agents.AgentID = Listings.ListingAgentID

Move a row from one gridview to another

I'm not sure how to go about this. Currently, in the first gridview, is a list of groups a member has access to. The second gridview is bound to a table that contains a list of every type of group and has an Add button which adds it to the first gridview and updates a table adding that group to a member.
This is what I am trying to do:
When the Add button (in the second gridview) for a row is clicked, it will be added to the first one (like it currently does), but I would also like it to disappear from the second gridview. So basically, a group should only be visible in either the first gridview or the second, not both. The problem I have is I don't want to modify the table because obviously the table contains all possible groups. Any suggestions?
I would do all the work on the database side. Data source for first one is:
Select g.*
From membership m
inner join groups g on m.groupid=g.groupid
Where m.userid = #userid
Data source for the second one looks like
Select g.*
From groups g
Where not exists
(Select 1 from membership m
Where m.GroupID=g.GroupID and m.userid = #userid
Then your add button inserts the appropriate row in the table and requeries both grids.
You could simply make changes to the Dataset, then .AcceptChanges and re-bind. This would ensure the data would update on the screen without actually pushing it to the database.
Pseudo example:
Dim dt as Datatable = GetData1(strSQL.toString)
Dim dt2 as Datatable = GetData2(strSQL.toString)
Public Sub MoveRecord(ByVal dt1 as DataTable, ByVal dt2 as Datatable, ByVal index as Integer)
'Record being moved '
Dim dr as Datarow = dt.Rows(index)
dt2.Rows.Add(dr)
dt2.AcceptChanges
dt.Rows.RemoveAt(index)
dt.AcceptChanges
'Bind Gridview
Perhaps store new changes in Viewstate,
Cache, or Session for Paging, Sorting'
End Sub
Of course, this assumes the grids have the same fields. If they don't, you'd have to:
Dim drN as DataRow - dt2.Rows.NewRow
'Assign rows from moving datarow to new datarow'
dt2.Rows.Add(drN)
dt2.AcceptChanges