Вложенный оператор iif () слишком сложен для запуска в MS Access - PullRequest
1 голос
/ 27 июня 2019

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

Для установки этапа

Транзакции (RefID) могут быть следующими:

  • 3PL
  • 4PL
  • Авиаперевозки
  • Только для таможни

Одна из сложностей этой задачи заключается в том, что код оплаты ("CC"), аналогичный номеру товараили название услуги, может быть 3PL или 4PL в зависимости от обстоятельств сделки.Например, если CC для Ocean_Freight существует для RefID, который также имеет CC для PO_Management, транзакция является транзакцией 3PL.Однако, если CC для PO_Management существует без Ocean_Freight для RefID, это будет транзакция 4PL.

У меня есть следующие CC, которые можно использовать для определения транзакции:

Описания CC

только 3PL

  • Ocean_Freight
    • этот CC будет определять транзакцию, если только нет CC из "3PL или 4PL в зависимости от ситуации"нижеприведенный раздел
  • Управление дренажем
    • этот CC будет определять транзакцию, если не имеется CC из раздела "3PL или 4PL в зависимости от ситуации" ниже

Только авиаперевозки

  • Авиаперевозки

3PL или 4PL в зависимости от ситуации

  • PO_Management
    • 3PL, когда CC существует для RefID с Ocean_Freight или Drayage Management
    • 4PL, когда CC существует для RefID без вышеупомянутых CC
  • Плата за CROM

    • 3PLкогда CC существует для RefID с Ocean_Freight или Drayage Management
    • 4PL, когда CC существует для RefID без Ocean_Freight, Drayage Management или PO_Management
  • EDI

    • 3PL, когда CC существует для RefID с Ocean_Freight или Drayage Management
    • 4PL, когда CC существует для RefID без Ocean_Freight, Drayage Management или PO_Management
  • Плата за управление бронированием
    • 3PL, когда CC существует для RefID с Ocean_Freight или Drayage Management
    • 4PL, когда CC существует для RefID без Ocean_Freight, Drayage Management, PO_Management или EDI
  • Комиссия за переадресацию
    • 3PL, когда CC существует для RefID с Ocean_Freight или Drayage Management
    • 4PL, когда CC существует для RefID без Ocean_Freight, Drayage Management, PO_Management, EDIили Комиссия за управление бронированием
  • Плата за обработку
    • 3PL, если CC существует для RefID с Ocean_Freight или DrayУправление возрастом
    • 4PL, когда CC существует для RefID без Ocean_Freight, управления дренажем, PO_Management, EDI, платы за управление бронированием или платы за переадресацию

Только для таможни

В качестве примечания - каждый из предыдущих CC может рассматриваться как то, что я классифицирую как код определения транзакции (TDCC), при отсутствии одного из этих CCи наличие таможенного въезда CC, транзакция определяется как транзакция «Только таможня».

Пример транзакции:

https://imgur.com/e57buni

ЧтоЯ сделал к этому моменту

Ранее я выполнял это в Access, используя вложенный оператор iif (), но в некоторых случаях я извлекал дублирующиеся записи, потому что не изолировал каждый из CC.Например, если PO_Management и Handling Charge существуют в одной и той же транзакции, оба получат значение «4PL», хотя в действительности я хочу, чтобы только одна определяла транзакцию.Это то, что отправило меня по пути исправления кода.

Запрос, который управляет большей частью этого, называется «Шаг 2)», и он выполняет суммирование (если (критерии здесь), 1,0) в зависимости от того, существует или нет CC для RefID.Он предоставляет значение> 0, если CC существует в RefID, что позволяет мне ссылаться на этот запрос, чтобы определить, как я должен определить RefID.

Чтобы еще больше усовершенствовать мою первоначальную методологию, я сделал еще один запрос под названием «Шаги».В этом запросе я применяю логику сверху в разделе описаний CC выше.

Я пытался использовать вложенный оператор iif (), а также пытался использовать функцию Switch (), но оба получили одно и то же.пункт "Введенное вами выражение слишком сложное".Я провел некоторое исследование, и я считаю, что ответом является частная функция с использованием VBA, но мне не повезло понять, как создавать функции.У кого-нибудь есть лучший способ решения этой проблемы?Ниже приведен пример моей последней попытки использования функции switch (), которая выдает ошибку ниже:

Transaction Type: 

    Switch(
      [Steps]![OF] > 0           And [Steps]![CC] = "Ocean Freight","3PL",
      [Steps]![AF] > 0           And [Steps]![CC] = "Air_Freight","Air Freight",
      [Steps]![Dray] > 0         And [Steps]![CC] = "Drayage Management","3PL",
      [Steps]![PO 4PL] > 0       And [Steps]![CC] = "PO_Management","4PL",
      [Steps]![PO 3PL] > 0       And [Steps]![CC] = "PO_Management","3PL",
      [Steps]![CROM 4PL] > 0     And [Steps]![CC] = "CROM Fee","4PL",
      [Steps]![CROM 3PL] > 0     And [Steps]![CC] = "CROM Fee","3PL",
      [Steps]![EDI 4PL] > 0      And [Steps]![CC] = "EDI","4PL",
      [Steps]![EDI 3PL] > 0      And [Steps]![CC] = "EDI","3PL",
      [Steps]![BMF 4PL] > 0      And [Steps]![CC] = "Booking Management Fee","4PL",
      [Steps]![BMF 3PL] > 0      And [Steps]![CC] = "Booking Management Fee","3PL",
      [Steps]![FF 4PL] > 0       And [Steps]![CC] = "Forwarding Fee","4PL",
      [Steps]![FF 3PL] > 0       And [Steps]![CC] = "Forwarding Fee","3PL", 
      [Steps]![Handling 4PL] > 0 And [Steps]![CC] = "Handling Charge","4PL", 
      [Steps]![Handling 3PL] > 0 And [Steps]![CC] = "Handling Charge","3PL"
    )

Что должно произойти?

В конечном счете, я хочу сослаться на «Шаги«Запросить управление полем в моем выходном запросе, называемом« тип транзакции ».Это, конечно, где-то для меня, потому что я не могу получить достаточно гнезд в моем заявлении iif ().Это наводит меня на мысль, что я все делаю неправильно, и существует гораздо более простое решение.

Ответы [ 3 ]

4 голосов
/ 28 июня 2019

У вас относительно простая ситуация сопоставления 1: 1. Эффективным и гибким способом решения этой проблемы было бы создание таблицы сопоставления, которая инкапсулирует ваши правила:

OF  AF  Dray  [PO 4PL]  [PO 3PL]  [CROM 4PL]  CC                     RefId
1                                             "Ocean Freight"        "3PL"
    1                                         "Air_Freight"          "Air Freight"
        1                                     "Drayage Management"   "3PL"
              1                               "PO_Management"        "4PL"
                        1                     "PO_Management"        "3PL"
                                  1           "CROM Fee"             "4PL"

Добавьте в таблицу больше столбцов для других полей, которые вы хотите проверить.

Теперь можно написать SELECT (или аналогичный оператор UPDATE), который выбирает RefId на основе правил в таблице (предупреждение, это псевдокод, у меня нет MS Access для проверки этого прямо сейчас):

SELECT
  t.*
  r.RefId
FROM
  Transactions t
  LEFT JOIN TransactionMappings m ON
    t.CC = m.CC
    AND (
      (t.OF > 0 AND m.OF = 1) OR
      (t.AF > 0 AND m.AF = 1) OR
      (t.Dray > 0 AND m.Dray = 1) OR
      (t.[PO 4PL] > 0 AND m.[PO 4PL] = 1) OR
      (t.[PO 3PL] > 0 AND m.[PO 3PL] = 1)
    )

Преимущества будут

  • сравнительно чистый код
  • вы можете изменять правила отображения без необходимости переписывать SQL
  • JOIN (вероятно) будет быстрее, чем вложенный / комплексный Switch(), хотя это должно быть измерено
  • сделать это более сложным сравнительно легко (такие вещи, как «добавить числовой диапазон для проверки» или «сделать исключение в некоторых случаях» сводятся к добавлению большего числа столбцов в таблицу сопоставления и указанию большего количества условий JOIN), вложенная Switch() более сложная, так же сравнительно сложная.
3 голосов
/ 28 июня 2019

Ошибка Too complex возникает, когда у вас слишком много аргументов для функции.Простое решение - разделить коммутатор:

Вы можете легко разделить Switch(Compare1, Result1, Compare2, Result2, Compare3, Result3, Compare4, Result4) на Switch(Compare1, Result1, Compare2, Result2, True, Switch(Compare3, Result3, Compare4, Result4)).Хотя мы действительно увеличили сложность, наши отдельные операторы switch принимают меньше аргументов, поэтому Access с меньшей вероятностью будет жаловаться.

Для вашего примера разделение на две части будет выглядеть так:

Switch([Steps]![OF]>0 And [Steps]![CC]="Ocean Freight","3PL",
    [Steps]![AF]>0 And [Steps]![CC]="Air_Freight","Air Freight",
        [Steps]![Dray]>0 And [Steps]![CC]="Drayage Management","3PL",
            [Steps]![PO 4PL]>0 And [Steps]![CC]="PO_Management","4PL",
                [Steps]![PO 3PL]>0 And [Steps]![CC]="PO_Management","3PL",
                    [Steps]![CROM 4PL]>0 And [Steps]![CC]="CROM Fee","4PL",
                        [Steps]![CROM 3PL]>0 And [Steps]![CC]="CROM Fee","3PL",
                            [Steps]![EDI 4PL]>0 And [Steps]![CC]="EDI","4PL",
                                True, Switch(
                                     [Steps]![EDI 3PL]>0 And [Steps]![CC]="EDI","3PL",
                                        [Steps]![BMF 4PL]>0 And [Steps]![CC]="Booking Management Fee","4PL",
                                            [Steps]![BMF 3PL]>0 And [Steps]![CC]="Booking Management Fee","3PL",
                                                [Steps]![FF 4PL]>0 And [Steps]![CC]="Forwarding Fee","4PL",
                                                    [Steps]![FF 3PL]>0 And [Steps]![CC]="Forwarding Fee","3PL", 
                                                        [Steps]![Handling 4PL] >0 and [Steps]![CC]="Handling Charge","4PL", 
                                                            [Steps]![Handling 3PL] >0 and [Steps]![CC]="Handling Charge","3PL"))

Это все еще достаточное количество аргументов, поэтому вам, возможно, придется разделить его на 3 части.

0 голосов
/ 27 июня 2019

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

Private Function functionName(Arguments)

'your code here

End function

Единственная проблема заключается в том, что даже с функцией сам оператор switch слишком длинный и сложный.Вы получаете повторяющиеся значения, потому что он будет иметь несколько «истинных» значений.Чтобы решить эту проблему, набор операторов If и Else If будет работать лучше.Проверьте эту страницу для более подробной информации https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/using-ifthenelse-statements

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...