How do I get a query result into a textfield? - vba

I am creating an accounting database.
For the financial results, my form has a textfield ("Previous Solde") where the solde of previous months is shown. That exact amount is calculated with this query:
SELECT [sq Argenta Prep Vorig Saldo].Account,
Sum([sq Argenta Prep Vorig Saldo].SomVanBedrag) AS SomVanSomVanBedrag
FROM [sq Argenta Prep Vorig Saldo]
WHERE (((Year([Boekdatum]) & "/" & Month([Boekdatum]))<"2022/6"))
GROUP BY [sq Argenta Prep Vorig Saldo].Account
HAVING ((([sq Argenta Prep Vorig Saldo].Account)="BE61973184860917"));
The account number ("BE61973184860917") and the closing date ("2022/6") of course are replaced with variables.
The query does exactly what I want it to do.
When I run this query in Access, I get the expected result.
The question is: how do I get the result of the query into the textfield (Previous Solde) on the form?

Could simplify that SQL
SELECT Sum([sq Argenta Prep Vorig Saldo].SomVanBedrag) AS SomVanSomVanBedrag
FROM [sq Argenta Prep Vorig Saldo]
WHERE Format([Boekdatum], "yyyy/mm") < "2022/06"
AND [sq Argenta Prep Vorig Saldo].Account = "BE61973184860917";
Then use DLookup() domain aggregate function expression in textbox to pull from that query.
=DLookup("SomVanSomVanBedrag", "queryname")
Or don't use query and instead use DSum() domain aggregate function expression in textbox.
=DSum("SomVanBedrag", "sq Argenta Prep Vorig Saldo",
"Format(Boekdatum, 'yyyy/mm') < '2022/06' AND Account = 'BE61973184860917'")
Note the use of placeholder zero in the month part. Without it, records will not filter/sort correctly - 2022/12 would be less than 2022/6. This means query run in December would not retrieve Feb - Sep data for that same year. Even if the value is structured as a number without the /, the 0 would be needed. If users are selecting from a combobox, make sure values include placeholder 0 for 2-digit month.

The simple method is to use DSum in the ControlSource of that textbox.
To include your parameters from, I guess, two other textboxes named, say, txtDatum and txtAccount holding the values BE61973184860917 and 2022/6:
=DSum("[SomVanBedrag]","[sq Argenta Prep Vorig Saldo]","[Boekdatum] < DateValue(" & [txtDatum] & ") And [Account] = '" & [txtAccount] & "'")

Related

How to automaticaly calculate a new field (Column) in MS Access DB 2016 each month

I'm using MS Access 2016 on a win10 platform. I have a table in Access tbl_OB_PLAN_ALLT_DISTRIB that has the months of the year as headers example: OCT, NOV, DEC, etc..
I have a query that calculates the total of the months dollar value for all my Organizations that money is sent to.
I am needing help modifying my code in my query to automatically add the next month field to that calculation. I currently have to go in the query and modify it every month.
Here is what I am using so far:
OB_Plan: Nz([Oct],0)+Nz([NOV],0)+Nz([DEC],0)+Nz([JAN],0)
This is placed as an expression in my query. So I would like a way to automatically add the next month in the expression. example:
OB_Plan: Nz([Oct],0)+Nz([NOV],0)+Nz([DEC],0)+Nz([JAN],0)+Nz([FEB],0)
I'm thinking I may need to make this a function and call the function in the expression.
Any ideas would be helpful.
SQL Script modified:
SELECT tbl_OB_Plan_ALLT_DISTRIB_Data.Record_ID, ([tbl_OB_Plan_ALLT_DISTRIB_Data]![Directorate] & " " & "(" & [tbl_OB_Plan_ALLT_DISTRIB_Data]![FUND_CENTER] & ")") AS Directorate, tbl_OB_Plan_ALLT_DISTRIB_Data.SAG, tbl_OB_Plan_ALLT_DISTRIB_Data.MDEP, Calc_OB_Plan([JAN],[FEB],[MAR],[APR],[MAY],[JUN],[JUL],[AUG],[SEP],[OCT],[NOV],[DEC]) AS OB_Plan, [001-FINAL_INTEGRATION_TABLE]![AFP-FMEDDW] AS Current_AFP, [001-FINAL_INTEGRATION_TABLE]![ALLT-FMEDDW] AS Allotment_YTD, [001-FINAL_INTEGRATION_TABLE].TITLE
FROM tbl_OB_Plan_ALLT_DISTRIB_Data INNER JOIN [001-FINAL_INTEGRATION_TABLE] ON (tbl_OB_Plan_ALLT_DISTRIB_Data.MDEP = [001-FINAL_INTEGRATION_TABLE].MDEP) AND (tbl_OB_Plan_ALLT_DISTRIB_Data.SAG = [001-FINAL_INTEGRATION_TABLE].SAG)
GROUP BY tbl_OB_Plan_ALLT_DISTRIB_Data.Record_ID, ([tbl_OB_Plan_ALLT_DISTRIB_Data]![Directorate] & " " & "(" & [tbl_OB_Plan_ALLT_DISTRIB_Data]![FUND_CENTER] & ")"), tbl_OB_Plan_ALLT_DISTRIB_Data.SAG, tbl_OB_Plan_ALLT_DISTRIB_Data.MDEP, "", [001-FINAL_INTEGRATION_TABLE]![AFP-FMEDDW], [001-FINAL_INTEGRATION_TABLE]![ALLT-FMEDDW], [001-FINAL_INTEGRATION_TABLE].TITLE;
The main reason that you are finding this difficult to achieve using standard MS Access functionality is because your database does not adhere to database normalisation rules.
The moment that you find yourself hard-coding month names into query expressions and consequently modifying the structure of your queries each month is a red flag that your database design should change.
In your case, based on the information you have provided, I would suggest defining either Month (preferably as an integer) or, better yet, a Date field in your table, with the data for each month appearing as separate records in the table, rather than on a single record.
Following this change, selection becomes simple, as you can easily calculate the months or date range that you wish to select within the selection criteria of your queries, without the need to modify the query definition going forward.
Without such redesign, the solutions will be ugly, for example:
select
choose
(
month(date()),
Nz([JAN],0),
Nz([JAN],0)+Nz([FEB],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0)+Nz([JUN],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0)+Nz([JUN],0)+Nz([JUL],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0)+Nz([JUN],0)+Nz([JUL],0)+Nz([AUG],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0)+Nz([JUN],0)+Nz([JUL],0)+Nz([AUG],0)+Nz([SEP],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0)+Nz([JUN],0)+Nz([JUL],0)+Nz([AUG],0)+Nz([SEP],0)+Nz([OCT],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0)+Nz([JUN],0)+Nz([JUL],0)+Nz([AUG],0)+Nz([SEP],0)+Nz([OCT],0)+Nz([NOV],0),
Nz([JAN],0)+Nz([FEB],0)+Nz([MAR],0)+Nz([APR],0)+Nz([MAY],0)+Nz([JUN],0)+Nz([JUL],0)+Nz([AUG],0)+Nz([SEP],0)+Nz([OCT],0)+Nz([NOV],0)+Nz([DEC],0)
)
from
tbl_OB_PLAN_ALLT_DISTRIB
Or:
select sum(t.amount)
from
(
select 1 as mon, Nz([JAN],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 2 as mon, Nz([FEB],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 3 as mon, Nz([MAR],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 4 as mon, Nz([APR],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 5 as mon, Nz([MAY],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 6 as mon, Nz([JUN],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 7 as mon, Nz([JUL],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 8 as mon, Nz([AUG],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 9 as mon, Nz([SEP],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 10 as mon, Nz([OCT],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 11 as mon, Nz([NOV],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
union
select 12 as mon, Nz([DEC],0) as amount
from tbl_OB_PLAN_ALLT_DISTRIB
) t
where
t.mon <= month(date())
Or, as a VBA function:
Function Calc_OB_Plan(vJan, vFeb, vMar, vApr, vMay, vJun, vJul, vAug, vSep, vOct, vNov, vDec) As Double
Dim Arr()
Arr = Array(vJan, vFeb, vMar, vApr, vMay, vJun, vJul, vAug, vSep, vOct, vNov, vDec)
Dim i As Integer
For i = 0 To Month(Date) - 1
Calc_OB_Plan = Calc_OB_Plan + Nz(Arr(i), 0)
Next i
End Function
Which could be called from your SQL query in the following way:
select Calc_OB_Plan([JAN],[FEB],[MAR],[APR],[MAY],[JUN],[JUL],[AUG],[SEP],[OCT],[NOV],[DEC]) as OB_Plan
from tbl_OB_PLAN_ALLT_DISTRIB
EDIT:
Since you are grouping by all fields, without any aggregation functions, you can replace the group by clause with a select distinct to obtain the same result more efficiently, e.g.:
SELECT DISTINCT
tbl_OB_Plan_ALLT_DISTRIB_Data.Record_ID,
([tbl_OB_Plan_ALLT_DISTRIB_Data]![Directorate] & " " & "(" & [tbl_OB_Plan_ALLT_DISTRIB_Data]![FUND_CENTER] & ")") AS Directorate,
tbl_OB_Plan_ALLT_DISTRIB_Data.SAG,
tbl_OB_Plan_ALLT_DISTRIB_Data.MDEP,
Calc_OB_Plan([JAN],[FEB],[MAR],[APR],[MAY],[JUN],[JUL],[AUG],[SEP],[OCT],[NOV],[DEC]) AS OB_Plan,
[001-FINAL_INTEGRATION_TABLE]![AFP-FMEDDW] AS Current_AFP,
[001-FINAL_INTEGRATION_TABLE]![ALLT-FMEDDW] AS Allotment_YTD,
[001-FINAL_INTEGRATION_TABLE].TITLE
FROM
tbl_OB_Plan_ALLT_DISTRIB_Data INNER JOIN [001-FINAL_INTEGRATION_TABLE] ON
tbl_OB_Plan_ALLT_DISTRIB_Data.MDEP = [001-FINAL_INTEGRATION_TABLE].MDEP AND
tbl_OB_Plan_ALLT_DISTRIB_Data.SAG = [001-FINAL_INTEGRATION_TABLE].SAG

Macro to Run Custom Sql Query in Access off Data in Table?

Coworker is completely Access adverse. I can't force him to update a SQL query with a to/from date and customer name. Current query is this:
SELECT [all customers]
FROM [information list]
WHERE
[date] Between [start date YYYYMMDD] and [end date YYYYMMDD]
and [all customers] = ['specific customer']
Group By [all customers] (this prevents duplicate entries or shipping a customer's order between factories counting as a separate order)
This coworker is so access adverse he wants a wysiwyg and a button to press to overwrite [start date YYYYMMDD] [end date YYYYMMDD] ['specific customer']
I can make a form just fine, but I have no idea how to populate the sql query with form answers. Having him copy and paste these three things into my perfectly good, working query is out of the question, as easy as that answer is.
How would i write a macro that can update this query with those answers replacing the three existing items (the two dates and customer ID)?
you concatenate the textbox values to create the sql query string
sql = "SELECT [all customers] FROM [information list]" _
& "WHERE [date] Between ['" & myForm.Textbox1.Text _
& "'] and ['" & myForm.Textbox2.Text _
& "'] and [all customers] = ['" & myForm.Textbox3.Text _
& "'] Group By [all customers]"
adjust the form name and the textbox names to fit your needs

Condition for Update vs insert

I have a table tblCosts which i display on an msaccess front end which enables users to add new entries as well as update existing ones. The table is structured as below.
ExpenseType Month Year Cost
Hardware June 2017 $500
Software July 2017 $300
Hardware Sept 2017 $150
I have an update and insert queries which work fine when run manually.
However I am having trouble differentiating the condition when to fire the query on the form. For example, if the record exists in the table, it should run the update query, if record does not exist, it should run the insert query.
For example if someone puts in
- Hardware Sept 2017 $120 it should update the 3rd entry from 150 to 120 but if someone puts in
- Furniture Sept 2017 $350 it should recognize that Furniture is not part of the DB and run the insert query. I have the update and insert queries but need help in identifying the condition when to run them.
The Update query I'm using is:
Update tblCosts
set tblCosts.Cost=[Forms]![frmCost]![txtCost]
where tblCosts.ExpenseType = [Forms]![frmCost]![txtExpType]
and tblCosts.Month = [Forms]![frmCost]![txtMonth]
and tblCosts.Year = [Forms]![frmCost]![txtYear]
The Insert query I'm using is:
Insert into tblCosts (ExpenseType , Month, Year, Cost)
Select [Forms]![frmCost]![txtExpType] as Exp1,
[Forms]![frmCost]![txtMonth] as Exp2,
[Forms]![frmCost]![txtYear] as Exp 3,
[Forms]![frmCost]![txtCost] as Exp 4
Need code (VBA or macro) behind a form that determines which action query to run. In VBA something like:
If DCount("*", "tablename", "ExpenseType='" & Me.cbxExpense & "' AND [Month]='" & Me.tbxMonth & "' AND [Year]=" & Me.tbxYear) = 0 Then
CurrentDb.Execute "INSERT INTO tablename (Expense, [Month], [Year], Cost) VALUES ('" & Me.cbxExpense & "', '" & Me.tbxMonth & "', " & Me.tbxYear & ", " & Me.tbxCost & ")"
Else
CurrentDb.Execute "UPDATE tablename SET Cost=" & Me.tbxCost & " WHERE Expense='" & Me.cbxExpense & "' AND [Month]='" & Me.tbxMonth & ", [Year]=" & Me.tbxYear
End If
Probably also want some validation code to make sure all four controls have data before executing queries.
The real trick is figuring out what event to put code into - the Cost AfterUpdate will work as long as the other fields have data entered first, otherwise the validation will fail and user will have to re-enter cost.
Could have code that doesn't make each control available until previous value is entered.
Month and Year are reserved words and should not use reserved words as names for anything.
Would be better to save month numbers instead of month names for sorting purposes.
Why updating a value which really should be a calculated aggregation of transaction records?

Dynamically named SQL fields

I have a query that, given a starting date, gives that week and the next 11 weeks' summarized data. Currently the field names for the weeks are week1, week2... Is there a way to name the fields with the dates they represent? (using only SQL)
If the given input is #11/9/13# then I'm looking for something like this.
SELECT
[Qry Week Totals By Billto and CC].CC,
Sum([Qry Week Totals By Billto and CC].[Week 1]) AS [inputdate],
Sum([Qry Week Totals By Billto and CC].[Week 2]) AS [inputdate] +7 ...
FROM
...
Of course this doesn't work for me. But I hope it communicates what I'm looking for.
You might be able to work something out with partition before you crosstab:
SELECT Partition([adate], #3/1/2013#, #4/1/2013#, 7) AS Part1,
table1.adate,
Mid([part1], 1, Instr([part1], ":") - 1) AS Mid1,
Mid([part1], Instr([part1], ":") + 1) AS Mid2,
Format([mid1], "yyyy/mm/dd") & " - " & Format([mid2], "yyyy/mm/dd") AS
TheDateRange
FROM table1
WHERE table1.adate>#3/6/2013#
Otherwise, you might consider a bucket table.

Group By for Combobox Filter Sort

I've created a basic Combobox Filter Sort that sorts through Company Regions for my company (Acronyns mostly) we refer to these as AOR's or Area of Reference. After defining your AOR, it limits the next combo box to show only Countries in that specific AOR, hense the Filter Sort. But, my problem is - when it displays the countries after selecting an AOR - It displays ALL RECORDS in that specific country, instead of just 1 country listing.
Basically, It isn't grouping my countries - and when I select "Totals" which normally gives me only unique results, this doesnt work.
My question, How can I re-write this code to include a Group By?
My Code:
Private Sub cboRegion_AfterUpdate()
' Region -> Country
Dim sManagerSource As String
sManagerSource = "SELECT [FullEmail].[AORID], [FullEmail].[ID], [FullEmail].[Country] " & _
"FROM FullEmail " & _
"WHERE [AORID] = " & Me.cboRegion.Value
Me.cboCountry.RowSource = sManagerSource
Me.cboCountry.Requery
End Sub
My SQL statement looks like this (It's got Group By in it, but it doesn't GROUP)
SELECT FullEmail.AORID, FullEmail.ID, FullEmail.Country
FROM FullEmail
GROUP BY FullEmail.AORID, FullEmail.ID, FullEmail.Country
HAVING (((FullEmail.AORID)=1));
Thanks in advance for reading through!
The previous answer is correct, except with a having clause you need to use aggregates... so just use where.
SELECT Country
FROM FullEmail
WHERE AORID=1
GROUP BY Country;
That should fix you up. When you use HAVING it looks at what you've selected, since you didn't select AORID, it didn't know what to do.