Как автоматически рассчитать новое поле (столбец) в MS Access DB 2016 каждый месяц - PullRequest
0 голосов
/ 24 января 2020

Я использую MS Access 2016 на платформе win10. У меня есть таблица в Access tbl_OB_PLAN_ALLT_DISTRIB, в которой в качестве заголовков используются месяцы года: OCT, NOV, DEC, et c ..

У меня есть запрос, который вычисляет сумма в долларах за месяцы для всех моих организаций, которым отправляются деньги.

Мне нужна помощь в изменении кода в моем запросе, чтобы автоматически добавить поле следующего месяца к этому вычислению. В настоящее время мне нужно go в запросе и изменять его каждый месяц.

Вот что я использую до сих пор:

OB_Plan: Nz([Oct],0)+Nz([NOV],0)+Nz([DEC],0)+Nz([JAN],0)

Это помещено в качестве выражения в моем запросе. Поэтому я хотел бы, чтобы способ автоматически добавить следующий месяц в выражение. пример:

OB_Plan: Nz([Oct],0)+Nz([NOV],0)+Nz([DEC],0)+Nz([JAN],0)+Nz([FEB],0)

Я думаю, мне может понадобиться сделать это функцией и вызвать функцию в выражении.

Любые идеи будут полезны. SQL Сценарий изменен:

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 Ответ

2 голосов
/ 24 января 2020

Основная причина, по которой вам трудно добиться этого с помощью стандартных функций MS Access, заключается в том, что ваша база данных не соответствует правилам нормализации базы данных .

В тот момент, когда вы испытываете трудности - кодирование названий месяцев в выражениях запросов и, следовательно, изменение структуры запросов каждый месяц - это красный флаг, который должен изменить дизайн вашей базы данных.

В вашем случае, основываясь на предоставленной вами информации, я бы предложил определить либо Month (желательно в виде целого числа), либо, что еще лучше, поле Date в вашей таблице, в котором данные за каждый месяц отображаются в виде отдельных записей в таблице, а не в одной записи .

После этого изменения выбор становится простым, поскольку вы можете легко рассчитать месяцы или диапазон дат, которые вы выберете sh для выбора в рамках критериев выбора ваших запросов, без необходимости изменять Определение запроса в будущем .

Без таких повторных дизайн, решения будут некрасивыми, например:

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

Или:

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

Или, как функция VBA:

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

Что может быть вызывается из вашего SQL запроса следующим образом:

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:

Поскольку вы группируете по всем полям без каких-либо функций агрегирования, вы можете заменить предложение group by с select distinct для более эффективного получения того же результата, например:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...