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

孤人 提交于 2020-01-25 06:38:09

问题


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;

回答1:


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


来源:https://stackoverflow.com/questions/59898124/how-to-automaticaly-calculate-a-new-field-column-in-ms-access-db-2016-each-mon

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!