Вопрос

Я использую Access 2003.Я использую Switch для выбора полей даты на основе логического критерия:

Switch(<criterion>, Date1, 1, Date2)

т. е. если «критерий» истинен, верните Date1, в противном случае верните Date2.

Date1 и Date2 — это столбцы типа «Дата/время» в таблице.

Проблема в том, что Switch возвращает их как текст, а не дату/время!

Есть ли способ заставить их присоединиться к свиданию?Я пытался

Switch(<criterion>, #Date1#, 1, #Date2#)

И

Switch(<criterion>, Val(Date1), 1, Val(Date2))

Оба из них терпят неудачу с тем или иным сообщением об ошибке.

Есть идеи?

Это было полезно?

Решение

Я думаю, что функция Immediate If [IIf()] лучше соответствует тому, что вы пытаетесь сделать:

IIf(<criterion>, Date1, Date2)

Но функция Switch() не должна нарушать типы данных и не является несовместимой с типами данных даты и времени.Рассмотрим эту функцию:

Public Function trySwitch(ByVal pWhichDay As String) As Variant
    Dim varOut As Variant
    varOut = Switch(pWhichDay = "yesterday", Date - 1, _
        pWhichDay = "today", Date, _
        pWhichDay = "tomorrow", Date + 1)
    trySwitch = varOut
End Function

попробуйтеSwitch("сегодня") возвращает 10/6/2009 и ИмяТипа(trySwitch("сегодня")) возвращает Дата

Другие советы

Что-то странное в вашем примере.

Switch принимает пары выражений, и если первое оценивается как True, возвращается его парное значение, в противном случае оно передается второму и оценивает этот аргумент.

Кажется, вы рассматриваете 1 как True, потому что это не Fales, но вам было бы лучше:

  Switch(<criterion>, Date1, True, Date2)

Но это всего лишь копирование функциональности функции «Немедленное если», IIf() и IIf(), принимающих меньше аргументов.

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

Но будет ли этот вариант принудительно принуждаться неявно или вам придется сделать это явно, зависит от того, где вы его используете.В результате запроса вы можете отсортировать выходные данные IIf([критерий], Date1, Date2) как дату, поскольку столбец привязывается к типу даты.

Если вам нужно явно выполнить приведение, следует использовать функцию CDate(): вы должны обернуть внешнюю функцию, которая производит вывод варианта, функцией CDate(), чтобы быть уверенным, что вывод варианта явно приводится к дате. тип:

  CDate(IIf(<criterion>, Date1, Date2))

Но я вполне могу упустить здесь что-то важное, поскольку, похоже, я иду совершенно по другому пути...

Можете ли вы опубликовать код и данные, чтобы воспроизвести проблему, пожалуйста?Как это SWITCH() в коде SQL, то я думаю, что SQL DDL (CREATE TABLE и т. д.) и DML (INSERT INTO добавить данные) было бы наиболее уместно :)

[Сложный момент:SQL базы данных Access не имеет логического типа данных.Оно имеет YESNO тип данных, который может быть NULL ценить;трехзначная логика не является логической.]

Вот некоторый SQL DML (Режим запроса ANSI-92 синтаксис), чтобы продемонстрировать, как это работает, как я ожидал:

SELECT TYPENAME
       (
          SWITCH
          (
             NULL, #2009-01-01 00:00:00#, 
             FALSE, #2009-06-15 12:00:00#, 
             TRUE, #2009-12-31 23:59:59#
          )
       );

Измените любое из значений «критерия», и значение всегда будет возвращено как «Дата», т.е.типа DATETIME.


ОБНОВЛЯТЬ:

Что TYPENAME Функция - отличный инструмент ...Доступ, кажется, по -разному интерпретирует весь «столбец» результатов

Действительно.Поскольку столбец может иметь только один тип данных, результаты TYPENAME() в ряду может ввести в заблуждение.Значения строк смешанных типов должны быть «повышены» до более высокого типа данных.Как это обычно бывает с Access Database Engine, процесс совершенно непрозрачен, а документация по этому вопросу полностью отсутствует, поэтому вам просто нужно смириться с этим и посмотреть, например.

SELECT #2009-01-01 00:00:00# AS row_value, 
       TYPENAME(#2009-01-01 00:00:00#) AS row_type
  FROM Customers
UNION ALL
SELECT 0.5, 
       TYPENAME(0.5) AS row_type
  FROM Customers

возвращает «Дата» и «Десятичный» соответственно, но каким будет столбец?Судя по всему, ответ:

SELECT DT1.row_value, TYPENAME(DT1.row_value) AS column_type
  FROM (
        SELECT DISTINCT #2009-01-01 00:00:00# AS row_value 
          FROM Customers
        UNION ALL
        SELECT DISTINCT 0.5
          FROM Customers
       ) AS DT1;

'Нить'?!

... что, конечно, даже не является типом данных SQL Access Database Engine.Так TYPENAME(), к сожалению, использует имя «наиболее подходящего» типа VBA.Например:

SELECT TYPENAME(CBOOL(0));

возвращает «Boolean», хотя, как обсуждалось выше, в Access Database Engine SQL нет логического типа данных.И

SELECT TYPENAME(my_binary_col)

возвращает «Строка».Обратите внимание, что то же ограничение сопоставления VBA применяется к CAST функции (еще одна неприятность), например.нет никакого приведения к BINARY' функция и CDEC() функция остается неработающей начиная с Jet 4.0 :(

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top