0

Access2003を実行しています。ブール基準に基づいて日付フィールドを選択するためにSwitchを使用しています。

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

つまり、「criterion」がtrueの場合は、Date1を返し、そうでない場合はDate2を返します。

Date1とDate2は、テーブルの日付/時刻タイプの列です。

問題は、Switchがそれらを日付/時刻ではなくテキストとして返すことです!

それらをDate-nessに強制する方法はありますか?私は試した

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

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

どちらも、いずれかのエラーメッセージで失敗します。

何か案は?

4

3 に答える 3

2

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

trySwitch( "today")は2009年10月6日を返し、 TypeName( trySwitch ( "today"))は日付を返します

于 2009-10-07T00:36:27.590 に答える
1

あなたの例には奇妙なことがあります。

Switchは式のペアを受け入れ、最初の引数がTrueと評価された場合はそのペアの値が返され、そうでない場合は2番目の引数に渡されてその引数が評価されます。

あなたは1をTrueとして扱っているようです。これは、Falesではないためですが、次のようにしたほうがよいでしょう。

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

ただし、これは、Immediate If関数、IIf()、およびIIf()の機能の複製にすぎません。

ただし、バリアントを返すという点で同じ問題があります。ただし、日付としてフォーマットできるデータ型にそれを強制できるはずです。

ただし、そのバリアントが暗黙的に強制されるか、明示的に行う必要があるかどうかは、使用している場所によって異なります。クエリ結果では、列が日付型に強制変換されるため、IIf([criterion]、Date1、Date2)からの出力を日付として並べ替えることができます。

強制を明示的に行う必要がある場合は、CDate()を使用する関数です。バリアント出力が現在までに明示的に強制されるようにするには、バリアント出力を生成する外部関数をCDate()関数でラップします。タイプ:

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

しかし、私は完全に別の道を進んでいるように見えるので、ここで重要な何かを見逃している可能性があります...

于 2009-10-07T02:46:28.110 に答える
1

問題を再現するためのコードとデータを投稿していただけますか?これはSQLコードにあるので、SQL DDL(など)とDML(データを追加するため)が最も適切SWITCH()だと思います:)CREATE TABLEINSERT INTO

[要点:AccessDatabaseSQLには「ブール」データ型がありません。値にYESNOなり得るデータ型があります。NULL3値論理はブール値ではありません。]

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#
          )
       );

'criterion'値のいずれかを変更すると、値は常に' Date'、つまりタイプが返されDATETIMEます。


アップデート:

そのTYPENAME関数は素晴らしいツールです...Accessは結果セットの「列」全体を異なる方法で解釈するようです

それはそう。列は1つのデータ型にしかなり得ないため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;

'弦'?!

...もちろん、これはAccessDatabaseEngineのSQLデータ型でもありません。したがってTYPENAME()、厄介なことに、「最適な」VBAタイプの名前を使用します。例えば:

SELECT TYPENAME(CBOOL(0));

上記のように、Access Database Engine SQLにブールデータ型がない場合でも、「ブール」を返します。と

SELECT TYPENAME(my_binary_col)

'String'を返します。同じVBAマッピングの制限がCAST関数に適用されることに注意してください(さらに別の煩わしさ)。たとえば、「キャスト先BINARY」関数はなく、 CDEC()Jet4.0以降関数は壊れたままです:(

于 2009-10-07T08:11:15.367 に答える