MS Access Subform conditional format based on data on a table - forms

My database has a Form view for the Lab to input the results of their tests to each batch we produce.
I have a query as Subform data source and I use a date combo box for the lab guys to see the production for the day. My problem is that when they write the value of the test (say batch 5, product A, test result= 10), I need the subform to do a conditional formatting based on a min/max specification located in another table. Say this table says product A allows a range from 11-15. Then when the technician writes 10, he should be prompted to quarantine the product. One easy way is to mark the CELL in BOLD RED.
This is my Subform layout:
Product | Batch # | Test result
My Spec sheet is something like this:
Product | Min | Max
I tried using DLookup without success, maybe the syntax is wrong.
Any recommendations on how to tackle this?
One nice idea that came through my mind would be to have a button to automatically notify my quality guy.
Thank you.
Updated for easy understanding

Autonumber ID field in Products is set as primary key yet the Product field in Batch is text. Change to number long integer type. This is correctly done in [Product Specification] table.
Once that field type is fixed, can include [Product Specification] table in LabBatchQuery and the specification fields will be available for direct reference in Conditional Formatting.
SELECT Batch.*, [Product Specification].*
FROM [Product Specification] RIGHT JOIN Batch ON [Product Specification].[Product Code] = Batch.Product
WHERE (((Batch.[Production Date])=[Forms]![TNA Batch Analysis]![Today Date]));
Change the RecordSource to simply reference LabBatchQuery instead of the SQL statement. Or instead of having dynamic parameter in the query object (I never do), put it in RecordSource SQL statement. SELECT * FROM LabBatchQuery WHERE [Production Date]=[Forms]![TNA Batch Analysis]![Today Date];
The Conditional Formatting rules will be like: Value Is Not Between [pH Min] And [pH Max]
Change the [Today Date] textbox AfterUpdate code to: Me.[LabBatchQuery subform].Requery
Advise not to use spaces nor punctuation/special characters (underscore only exception) in naming convention.
Also recommend not setting lookups in tables.
If Products and [Product Specification] have 1-to-1 relationship, why not combine as 1 table?

You can use Form_BeforeUpdate to validate / conditional formatting the data
Below code will restrict PH values if they are out of range defined in Product Specification table. Similarly you can define for other fields.
Put this code to your subform:
Private Sub Form_BeforeUpdate(Cancel As Integer)
Dim pH_Min As Double, pH_Max As Double
If Nz(Product, -1) <> -1 And Nz(Me.Batch__, "") <> "" And Nz(Me.pH, -1) <> -1 Then
pH_Min = DLookup("[pH Min]", "Product Specification", "[Product Code]=" & Product)
pH_Max = DLookup("[pH Max]", "Product Specification", "[Product Code]=" & Product)
If Me.pH.Value >= pH_Min And Me.pH.Value <= pH_Max Then
'no action
Else
MsgBox "Invalid Value", vbInformation
Cancel = True
End If
End If
End Sub

Related

SQL: Change the datetime to the exact string returned

See below for what is returned in my automated test for this query:
Select visit_date
from patient_visits
where patient_id = '50'
AND site_id = '216'
ORDER by patient_id
DESC LIMIT 1
08:52:48.406 DEBUG Executing : Select visit_date from patient_visits
where patient_id = '50' AND site_id = '216' ORDER by patient_id DESC
LIMIT 1 08:52:48.416 TRACE Return: [(datetime.date(2017, 2, 17),)]
When i run this in workbench i get
2017-02-17
How can i make the query return this instead of the datetime.date bit above. Some formatting needed?
What you got from the database is python's datetime.date object - and that happens due to the db connector drivers casting the DB records to the their corresponding python counterparts. Trust me, it's much better this way than plain strings the user would have to parse and cast himself later.
Imaging the result of this query is stored in a variable ${record}, there are a couple of things to get to it, in the form you want.
First, the response is (pretty much always) a list of tuples; as in your case it will always be a single record, go for the 1st list member, and its first tuple member:
${the_date}= Set Variable ${record[0][0]}
Now {the_date} is the datetime.date object; there are at least two ways to get its string representation.
1) With strftime() (the pythonic way):
${the_date_string}= Evaluate $the_date.strftime('%Y-%m-%d') datetime
here's a link for the strftime's directives
2) Using the fact it's a regular object, access its attributes and construct the result as you'd like:
${the_date_string}= Set Variable ${the_date.year}-${the_date.month}-${the_date.day}
Note that this ^ way, you'd most certainly loose the leading zeros in the month and day.

IBM DB2 SQLException with "DB2 SQL Error: SQLCODE=-420, SQLSTATE=22018, SQLERRMC=DECFLOAT, DRIVER=3.66.46"

I am working on a Jasper report using iReport 5.6 and IBM DB2 as data source. I am passing a list of strings as a parameter to the report and that is where the problem rises. The query is below;
SELECT customers.mobile_number,
COALESCE(Count(DISTINCT transaction_entries.transaction_id), 0) AS
number_of_transactions,
COALESCE(Sum(Abs(transaction_entries.amount)) / 100, 0) AS
volume_of_transactions
FROM transaction_entries
JOIN customers
ON customers.id = transaction_entries.customer_id
WHERE transaction_entries.transaction_type = 'Seasonal'
AND transaction_entries.notification_text <> 'Notification'
AND customers.mobile_number IN ( $p ! {listOfMobileNumbers} )
GROUP BY customers.mobile_number
When I try to generate the report I get the error Caused by: com.ibm.db2.jcc.am.SqlDataException: DB2 SQL Error: SQLCODE=-420, SQLSTATE=22018, SQLERRMC=DECFLOAT, DRIVER=3.66.46.
Any idea why ? and the possible solution ?
I would first verify that by commenting-out the last predicate of the WHERE clause avoids the error; i.e. redact the failing statement such that the IN predicate referencing the Jasper variable as input is no longer part of the query.
Then, determine what defines that variable replacement, from the output of the following query:
select '$p ! {listOfMobileNumbers}' from sysibm.sysdummy1
If the effect of the above query, used to reveal the data in that list, presents something like '1234,567,890', then I would suggest modifying the data that defines that list to reflect either of '1234','567','890' or 1234, 567, 890 instead.
FWiW: IMO the actual DDL [for column(s) or the TABLE] is much clearer to a reader than suggesting merely that:
The mobile_number field is returned from the database as a String and not a DECIMAL

Construct SQL where clause to pull data within Power Query

Basically I want to retrieve rows of data that meet my clause conditions using Power Query.
I got 400 rows of lookup values in my spreadsheet.
Each row represent 1 lookup code for example, code AAA1, AAB2 and so on
So lets say I have a select statement and I want to construct the where clauses using the above codes so my end sql statement will look like
select * from MyTable where Conditions in ('AA1', 'AAB2')
so so far I have this
let
Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Form ID",
Int64.Type}}),
test = Sql.Database("myserver", "myDB", [Query="SELECT * FROM myTable where" & #"Changed Type" & "])"
in
test
Obviously that didnt work but thats my pseduo scenario anyway.
Please could you advice what to do?
Thank you
Peddie
I would create a "lookup" Power Query based on the Excel table. I would set the "Load To" properties to "Only Create Connection".
Then I would start the main Query by connecting to the SQL server using the Navigator to select "MyTable". Then I would add a Merge step to the main Query, to join to the "lookup" Query, matching the "Conditions" column to the "lookup" code. I would set the Join Type to "Inner". The Merge properties window will show you visually if the 2 columns you select actually contain matching data.
This approach does not require any coding, and is easier to build, extend and maintain.
Mike Honey's join is best for your problem, but here's a more general solution if you find yourself needing other logic in your where clause.
Normally Power query only generates row filters on an equality expression, but you can put any code you want in a Table.SelectRows filter, like each List.Contains({"AA1", "AAB2"}, [Conditions])
So for your table, your query would look something like:
let
Source = Excel.CurrentWorkbook(){[Name="Table5"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Form ID", Int64.Type}}),
test = Sql.Database("myserver", "myDB"),
yourTable = test{[Name="myTable"]}[Data],
filtered = Table.SelectRows(yourTable, each List.Contains(#"Changed Type"[Form ID], [Conditions]))
in
filtered
The main downside to using the library functions is that Table.SelectRows only knows how to generate SQL where clauses for specific expression patterns, so the row filter probably runs on your machine after downloading the whole table, instead of having the Sql Server run the filter.

Converting complex query with inner join to tableau

I have a query like this, which we use to generate data for our custom dashboard (A Rails app) -
SELECT AVG(wait_time) FROM (
SELECT TIMESTAMPDIFF(MINUTE,a.finished_time,b.start_time) wait_time
FROM (
SELECT max(start_time + INTERVAL avg_time_spent SECOND) finished_time, branch
FROM mytable
WHERE name IN ('test_name')
AND status = 'SUCCESS'
GROUP by branch) a
INNER JOIN
(
SELECT MIN(start_time) start_time, branch
FROM mytable
WHERE name IN ('test_name_specific')
GROUP by branch) b
ON a.branch = b.branch
HAVING avg_time_spent between 0 and 1000)t
GROUP BY week
Now I am trying to port this to tableau, and I am not being able to find a way to represent this data in tableau. I am stuck at how to represent the inner group by in a calculated field. I can also try to just use a custom sql data source, but I am already using another data source.
columns in mytable -
start_time
avg_time_spent
name
branch
status
I think this could be achieved new Level Of Details formulas, but unfortunately I am stuck at version 8.3
Save custom SQL for rare cases. This doesn't look like a rare case. Let Tableau generate the SQL for you.
If you simply connect to your table, then you can usually write calculated fields to get the information you want. I'm not exactly sure why you have test_name in one part of your query but test_name_specific in another, so ignoring that, here is a simplified example to a similar query.
If you define a calculated field called worst_case_test_time
datediff(min(start_time), dateadd('second', max(start_time), avg_time_spent)), which seems close to what your original query says.
It would help if you explained what exactly you are trying to compute. It appears to be some sort of worst case bound for avg test time. There may be an even simpler formula, but its hard to know without a little context.
You could filter on status = "Success" and avg_time_spent < 1000, and place branch and WEEK(start_time) on say the row and column shelves.
P.S. Your query seems a little off. Don't you need an aggregation function like MAX or AVG after the HAVING keyword?

Filemaker summarize related field if

I have a FM13 DB with a table "machines" and its related table "consumption" connected with the IDs.
My layout is showing the machines data and a portal with the related consumption entries.
Now I want to summarize the fields "amount" of all related entries where "fuelType" is "diesel" and the "year" is "2015" into one calculted field within the machines table.
Can anyone give me a clue how to do that?
thx
dan
In addition to the ways Michael suggested, FM13 introduced the ExecuteSQL command, which can used in a calculated field. The calculation would look something like this:
ExecuteSQL (
"SELECT SUM(amount)" & ¶ &
"FROM consumption" & ¶ &
"WHERE FuelType = 'diesel' AND \"Year\" = 2015" ;
"" ; ""
)
Create another relationship based on a calculation field in both tables based on concatenate fields:
id_fueltype_year: 12345_diesel_2015
You can then create a Calculation field in Machines containing Sum(newrelation: amount)
If you hard code the fueltype in the calc field machines table, then the result will always be the specified fuel type (e.g. diesel). Thus you would need to create multiple fields for each field type. Or you could create a fuel type field and as you change it the summary calc field would update upon selection.
If this is for display only, you could simply create a one-row portal based on the existing relationship and filter it to show only records where =
Consumption::FuelType = "diesel" and Consumption::Year = 2015
or (preferably, IMHO) =
Consumption::FuelType = Machines::gFuelType
and
Consumption::Year = Machines::gYear
with Machines::gFuelType and Machines::gYear being global fields where you can select any type/year to summarize.
Place a summary field defined (in the Consumption table) as Total of [Amount] inside the filtered portal.
If you need the result as data for further processing, then you will need to add a dedicated relationship (using another occurrence of the Consumption table) as:
Machines::MachineID = Consumption 2::MachineID
AND
Machines::gFuelType = Consumption 2::FuelType
AND
Machines::gYear = Consumption 2::Year
and use Sum ( Consumption 2::Amount ) to summarize the relevant entries.