Question

Je suis en cours d'exécution Access 2003. Je l'aide du commutateur pour sélectionner des champs de date basée sur un critère booléen:

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

i.e.., Si "critère" est vrai, puis revenez Date1, sinon revenir Date2.

date1 et date2 sont date / heure colonnes de type dans un tableau.

Le problème est, Switch les retourne sous forme de texte - non Date / Heure

Y at-il un moyen de les forcer à date-ness? J'ai essayé

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

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

Les deux qui échoue avec un message d'erreur ou d'une autre.

Toutes les idées?

Était-ce utile?

La solution

Je pense que la fonction immédiate Si [IIf ()] est une meilleure correspondance pour ce que vous essayez de faire:

IIf(<criterion>, Date1, Date2)

Mais la fonction Switch () ne doit pas briser les types de données et ne sont pas incompatibles avec les types de données date / heure. Considérez cette fonction:

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 ( "aujourd'hui") retourne 10/6/2009 et TypeName (trySwitch ( "aujourd'hui")) retourne Date

Autres conseils

Il y a quelque chose d'étrange avec votre exemple.

commutateur accepte des paires d'expression, et si la première est TRUE, sa valeur paire est retournée, sinon, il passe à la deuxième, et évalue cet argument.

Vous semblez traiter 1 vrai, qu'il est parce que ce n'est pas Fales, mais vous seriez mieux avec:

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

Mais c'est une réplique de la fonctionnalité de la fonction immédiate Si, IIf (), et IIf () prend moins d'arguments.

Mais il a le même problème, en ce qu'elle renvoie une variante. Mais vous devriez être en mesure de contraindre qui à un type de données qui peut être formaté comme une date.

Mais si cette variante sera implicitement sous la contrainte ou vous aurez besoin de le faire explicitement, dépend de l'endroit où vous l'utilisez. Dans un résultat de la requête, vous pouvez trier la sortie de IIf ([critère], date1, date2) comme une date, parce que la colonne se contraint à type de date.

Si vous avez à faire la contrainte explicitement, CDate () est la fonction à utiliser - vous souhaitez envelopper la fonction extérieure qui produit une sortie de variante avec la fonction CDate () afin d'être certain que la sortie variante est explicitement sous la contrainte de type date:

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

Mais je pourrais très bien être manque quelque chose d'important ici, comme je semble être hors sur une piste complètement différente ...

Pouvez-vous envoyer un code et des données pour reproduire le problème, s'il vous plaît? Comme cela est SWITCH() dans le code SQL, alors je pense que SQL DDL (CREATE TABLE etc) et DML (INSERT INTO pour ajouter des données) seraient les plus appropriées:)

[Point Picky: base de données Access SQL ne dispose pas d'un type de données 'boolean'. Il a un type de données YESNO qui peut être la valeur NULL; logique à trois valeurs ne sont pas booléenne.]

Voici une DML SQL ( ANSI-92 mode de requête syntaxe ) pour montrer comment il fonctionne comme prévu pour moi:

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

Modifiez les valeurs « critère » et la valeur est toujours renvoyée comme « date » à savoir le type DATETIME.


Mise à jour:

  

Cette fonction TYPENAME est un grand   outil ... L'accès semble interpréter la   toute « colonne » de la resultset   autrement

En effet. Parce qu'une colonne ne peut être un type de données, les résultats de TYPENAME() à la ligne peuvent induire en erreur. Les valeurs de ligne de types mixtes doivent être « promus » à un type de données plus élevé. Comme cela est habituel avec le moteur de base de données d'accès, le processus est tout à fait opaque et la documentation sur le sujet complètement absent, il vous suffit de le sucer et voir, par exemple

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

Date de rendement »et « décimal » respectivement, mais ce sera la colonne être? Apparemment, la réponse est:

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;

'String'!

... qui bien sûr est même pas une base de données d'accès type de données du moteur SQL. Alors TYPENAME(), agaçante, utilise le nom du « meilleur ajustement » de type VBA. Par exemple:

SELECT TYPENAME(CBOOL(0));

retourne 'Boolean', même si, comme indiqué plus haut, il n'y a pas le type de données Boolean dans Access Database Engine SQL. Et

SELECT TYPENAME(my_binary_col)

renvoie String. Notez la même limitation de mappage VBA applique aux fonctions de CAST (encore une gêne), par exemple il n'y a pas de fonction « jeter à BINARY » et la fonction CDEC() reste cassé depuis Jet 4.0: (

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top