Add Query with Month filter to an Access Database with Date/Time Field - vb.net

I have an Access Database with many fields connected through a datagridview in my vb.net project. Two of these fields contain Date/Time Values. I want to create a query through the query builder that uses input from the user to find records that match the dates the user wants. This "where clause" works :
WHERE BETWEEN ? AND ?
This creates a toolstrip in which I can input 2 dates so that the query can fill the datagridview with the records.
What I want now is to make a query like the above only this time the user inputs the name of a month he wants (ex. February or 02 ). Is there any way to do that ?
EDIT: Tried using Plutonix's code (Sailing is the Column name) :
WHERE SAILING BETWEEN #01/31/yyyy# AND #03/01/yyyy#
and I got this error: "Cannot convert entry to valid datetime TO_DATE function might be required"
EDIT 2: I have created a combobox containing all 12 months and I have a commandbutton. I want to find a way so that if the user selects one of the 12 months from that combobox and clicks the commandbutton, to have the datagridview control (access database) show him only the records that go with that month based on their datetime(Short Date) fields. What code should I put in my commandbutton_click ?

Eventually I created a long query where I added a "Between ? and ?" in my where clause for every Year included in the database (2004-2015), created a huge if clause that gives the beginnings and endings of the month requested for every year and used all those strings to query the database.
If Month.Text = "JANUARY" Then
A04A = "01/01/04"
A04B = "31/01/04"
A05A = "01/01/05"
A05B = "31/01/05"
A06A = "01/01/06"
A06B = "31/01/06"
A07A = "01/01/07"
A07B = "31/01/07"
A08A = "01/01/08"
A08B = "31/01/08"
A09A = "01/01/09"
A09B = "31/01/09"
A10A = "01/01/10"
A10B = "31/01/10"
A11A = "01/01/11"
A11B = "31/01/11"
A12A = "01/01/12"
A12B = "31/01/12"
A13A = "01/01/13"
A13B = "31/01/13"
A14A = "01/01/14"
A14B = "31/01/14"
A15A = "01/01/15"
A15B = "31/01/15"
A16A = "01/01/16"
A16B = "31/01/16"
ElseIf etc etc

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")

How do I bind a report field in Report_Open when I build the record Source on the fly?

For an existing report, I build the record source in the Report_Open event, so that it looks like this (it varies according to values passed in OpenArgs):
> SELECT tblSpecies.commonname AS Species,
> Month(tblLocationVisit.VisitDate) AS qMonthNumber,
> MonthName(Month(tblLocationVisit.visitdate)) AS qMonth,
> (SUM(Nz(tblSighting.Adults)) + SUM(Nz(tblSighting.Emerging))) AS TotalAdults,
> tblSighting.SpeciesID FROM tblSpecies INNER JOIN
> ((tblSite INNER JOIN tblLocationVisit ON tblSite.ID =
tblLocationVisit.SiteID)
> INNER JOIN
> tblSighting ON tblLocationVisit.ID = tblSighting.LocationVisitID) ON
> tblSpecies.ID = tblSighting.SpeciesID GROUP BY
tblSpecies.commonname, Month(VisitDate), MonthName(Month(visitdate)),
> tblSighting.SpeciesID HAVING (((SUM(Nz(tblSighting.Adults)))>0) OR
(SUM(Nz(tblSighting.Emerging)) > 0));
Species, MonthName, TotalAdults and a sum of TotalAdults are the only values presented in the report and it all works.
In the design sheet for the report, there is a static query given as the Record Source but this is replaced in the Report_Open event, as described above.
The static query exists purely for binding the report fields.
I now want to add a count to the report, so that:
> SELECT COUNT(tblLocationVisit.ID) AS qVisitCount,
> tblSpecies.commonname AS Species,
> Month(tblLocationVisit.VisitDate) AS qMonthNumber,
> MonthName(Month(tblLocationVisit.visitdate)) AS qMonth,
> (SUM(Nz(tblSighting.Adults)) + SUM(Nz(tblSighting.Emerging))) AS TotalAdults,
> tblSighting.SpeciesID FROM tblSpecies INNER JOIN
> ((tblSite INNER JOIN tblLocationVisit ON tblSite.ID =
tblLocationVisit.SiteID)
> INNER JOIN
> tblSighting ON tblLocationVisit.ID = tblSighting.LocationVisitID) ON
> tblSpecies.ID = tblSighting.SpeciesID GROUP BY
tblSpecies.commonname, Month(VisitDate), MonthName(Month(visitdate)),
> tblSighting.SpeciesID HAVING (((SUM(Nz(tblSighting.Adults)))>0) OR
(SUM(Nz(tblSighting.Emerging)) > 0));
The new query works when run standalone; there is no "Order By" in the property sheet for the query.
I have replaced the static query in the report's Record Source with the new query including the Count; I have also added code so that the
Report_Open event adds the Count to the record source. The new report field, xVisitCount, is bound to qVisitCount in the static query.
On running the report, I am asked to "Enter Parameter Value" for xVisitCount, so the binding isn't working; whatever I enter there, appears in the report.
If I remove the control source for the new field, there is no "Enter Parameter Value" prompt and the report field values are blank.
I think I need to change the binding for the new display field (xVisitCount) during the Report_Open event, either before or after assigning Me.RecordSource but I don't know how to do this.
I developed the original project a couple of years ago and my MS Access, while never very strong, is now very rusty. I have tried to format the code sensibly but I'm not sure it will display very well - I may have even trashed the accuracy of the code but I'm hoping this won't prevent your understanding.
If Access asks for the value of xVisitCount, it looks for this field in the record source.
To avoid any confusion, you should name the field the same everywhere, e.g. qVisitCount:
in the static query
the report field Name
the report field ControlSource
in the dynamic query.
See also How to debug dynamic SQL in VBA - copy your created SQL to a new query to make sure it returns the fields and data you expect it to.

Multiple entries in crystal reportviewer after adding a SQL expression field

I am using Visual Studio 2017 and I installed the latest crystal reportviewer (22)
What I want is to click a button and create a report from the customer that is selected in the datagridview and the addresses that are shown in the second datagridview.
I managed to do all that but the problem is that a few fields contain numbers which need to be converted to text. An SQL query I would use to do this would be like:
SELECT c.customer_nr, c.status, s.rename FROM CUSTOMERS c INNER JOIN SETUP s on s.id = c.status WHERE s.afk = 'STA'
In my SETUP database I have the columns ID,AFK and RENAME so if the status would be 1 it would convert to text: "ACTIVE", if status = 2 it would convert to "INACTIVE" for example.
I could do something with a formula field like this:
IF ({c.status} = 1) THEN "ACTIVE" ELSE
IF ({c.status}) = 2 THEN "INACTIVE"
but that is not good because i could add another status or change the name in the database etc.
So then I tried with an SQL expression field and I put something like this:
(
SELECT "SETUP"."RENAME" FROM SETUP
WHERE "SETUP"."AFK" = 'STA' AND "SETUP"."ID" = "CUSTOMERS"."STATUS"
)
There must be something wrong because I get the correct conversion but there is only one address in the database but I get 7 pages all with the same address. There should only be one address like I get when I remove the SQL expression field. Where does it go wrong?
* EDIT *
I found the problem. When I create a new database that contains only unique id's then it works. In my original database I have multiple times the id's 1,2,3,4,5 but with different abbreviations in column AFK. Somehow the query looks for the id value and every time it finds this id no matter the AFK value it generates an entry for the address value.
Maybe in the future I will find out how this exactly works for now I have a workaround.
Create a new table for example CrRepSta and add the following entries:
ID,AFK,RENAME
1,STA,Active
2,STA,Inactive
etc
The new query:
(
SELECT "CrRepSta"."RENAME" FROM CrRepSta
WHERE "CrRepSta"."AFK" = 'STA' AND "CrRepSta"."ID" = "CUSTOMERS"."STATUS"
)
And by the way the statement "CrRepSta"."AFK" = 'STA' is not really needed.

Date format problems when passing information from Access to Excel

just for documentation and future readers, the problem was solved and the answer is in the discussion between me and #varocarbas
My Application is reading a few columns from access data base and joining those columns into an existing datatable. one of the columns in the database has dates, the column is configured as date and time column in the database and in the data column of the datatable. the problem is when i am extrcting it into excel ,some of the dates are behaving in the oposite direction (i think the term is "english date"). what that i mean by "behaving", is that excel recognize the monthes as the days and the days as the months, for example a date that should be 11 in september 2015 the excel formula month(11/09/2015) is showing that the month is november and not september.
also, the date values in the access column are from sharepoint list that is also configured as dateandtime.. i have a filling that this behaving maybe belongs to excel(?),
here is the importent parts of my code:
' declaring the dateandtime column
Dim colString As DataColumn = New DataColumn("changed")
colString.DataType = System.Type.GetType("System.DateTime")
UnitedTable.Columns.Add(colString)
Storing it from the database:
If Not (IsDBNull(UnitedTable.Rows(i).Item("spcall"))) Then
spcall = UnitedTable.Rows(i).Item("spacll")
rowNum = Searchbinary(spcall) ' check that spcall exist in Projects table via binary search
If rowNum > -1 Then
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("PmUserName").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("OpertionalStatus").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("CrmCallNum").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("OperationStart").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("Approved").ToString
UnitedTable.Rows(i).Item("somecolumn") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("GeneralStatus").ToString
UnitedTable.Rows(i).Item("changed") = db.ReadDataSet.Tables(0).Rows(rowNum).Item("Changed")
Else
' the spcall not exist add it to arraylist
SpCalls_NotExist.Add(spcall)
'UnitedTable.Rows(i).Delete()
End If
Then I am populating it to excel with nested loop.

Creating filter with SQL queries

I am trying to create a filter with SQL queries but am having trouble with numeric values linking to other tables.
Every time I try to link to another table, it takes the same record and repeats it for every element in the other table.
For example, here is query:
SELECT ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID AND
ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0
The last line is the actual filtering criteria.
Here is an example result:
There should only be ONE result (Item has an RID of 0). But it's repeating a copy of the one record for every result inside the substitution groups table (there's 4).
Here is my database schema for reference. The lines indicate relationships between tables and the circles indicate the values I want:
You're forgot to join between ELEMENTS and SUBSTITUTION_GROUPS in your query.
SELECT
ELEMENTS.RID,TAXONOMIES.SHORT_DESCRIPTION,[type],ELEMENT_NAME,ELEMENT_ID,SUBSTITUTION_GROUPS.DESCRIPTION,namespace_prefix,datatype_localname
FROM
ELEMENTS,SUBSTITUTION_GROUPS,TAXONOMIES,SCHEMAS,DATA_TYPES
WHERE
ELEMENTS.TAXONOMY_ID = TAXONOMIES.RID AND ELEMENTS.ELEMENT_SCHEMA_ID = SCHEMAS.RID
AND ELEMENTS.DATA_TYPE_ID = DATA_TYPES.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = SUBSTITUTION_GROUPS.RID
AND ELEMENTS.SUBSTITUTION_GROUP_ID = 0