IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Access Discussion :

Stockage de bits dans un Integer


Sujet :

Access

  1. #1
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut Stockage de bits dans un Integer
    Bonjour.

    Autant annoncer la couleur tout de suite: je suis une brèle en bases de données...

    Mon problème à présent: je voudrais stocker dans ma base un tableau de booléens sous forme d'un Integer. Ce qui m'intéresse n'est donc pas tant la valeur de l'Integer que celle de chaque bit qui le constitue. Cela se fait les doigts dans le nez sous VB.NET (ou à peu près n'importe quel langage), mais qu'en est-il des requêtes?

    Y'a-t-il moyen de fixer une condition (... WHERE ...) permettant de récupérer tous les enregistrements pour lesquels le troisième bit (en partant du poids faible) de ce champ est à 1, par exemple.

    En vb.net, ce serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If (MonInteger AND 4) Then ...
    Toute assistance sera la bienvenue

  2. #2
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Tu pexu très bien écrire une fonction en VBA :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function TestBit(i As Integer, n As Byte) As Boolean
    TestBit = i And n
    End Function
    Et tu utilises cette fonction dans ton SQL

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT *
    FROM MATABLE
    WHERE TestBit(MonChamp,4)

  3. #3
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Merci, c'est ce qu'on appelle une procédure stockée?

  4. #4
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    Non, c'est une fonction VBA

    C'est un peu comme une procédure stockée mais pas vraiment.

    Mais étant donné qu'il n'y a pas de procédure stcokée sous Access, on fait avec VBA

  5. #5
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut


    Bon, en ce qui me concerne, je suppose que c'est kif-kif.

    Encore merci, je vais essayer ça.

  6. #6
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Dernière petite question (j'ai prévenu, hein): vaut-il mieux passer par une macro ou un module?

  7. #7
    Expert éminent sénior

    Avatar de Tofalu
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Octobre 2004
    Messages
    9 501
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Octobre 2004
    Messages : 9 501
    Points : 32 311
    Points
    32 311
    Par défaut
    module

    Les macros sont très limitées :

    Pas de test, pas de boucle, pas de gestion d'erreur, pas d'objets, etc...

  8. #8
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Merci, je m'y mets!

  9. #9
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Bonjour. J'ai encore un souci. J'ai créé la fonction avec la signature suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public Function TestBits(ByVal EntierStocke As Integer, ByVal ValeurMasque As Integer) As Boolean
    Dans un module appelé CodeIntegre.

    Ensuite, je l'appelle depuis ma requète:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT DISTINCT {...} FROM {...} WHERE CodeIntegre.TestBits([TableX].[ChampY],9);
    Et j'obtiens l'erreur: "Fonction CodeIntegre.TestBits non définie dans l'expression." Qu'est-ce à dire? Il semble ne pas trouver la fonction bien qu'elle soit déclarée en "Public". Y-a-t-il une subtilité de syntaxe que j'aurais zappée au passage?

  10. #10
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Bonjour
    Citation Envoyé par Mayamok
    Et j'obtiens l'erreur: "Fonction CodeIntegre.TestBits non définie dans l'expression." Qu'est-ce à dire? Il semble ne pas trouver la fonction bien qu'elle soit déclarée en "Public". Y-a-t-il une subtilité de syntaxe que j'aurais zappée au passage?
    N'utilise pas le nom du module, mais directement le nom de la fonction.

  11. #11
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Merci, je croyais l'avoir testé, mais il devait y avoir une faute dans le nom de la fonction (un "e" à "Test"). Maintenant ça marche (enfin, pas vraiment, mais c'est le code dans la fonction qui est en cause).

    Merci beaucoup.

  12. #12
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Décidément...

    J'ai complété ma requête, corrigé la fonction (VBA a une façon très personnelle d'effectuer des opérations sur les booléens! ) et maintenant, elle fonctionne quand je la lance depuis le créateur de requêtes (affichage SQL) dans Access.

    Mais quand je lance exactement la même requête (copier-coller à l'appui) depuis mon programme VB.NET, ça replante en me disant à nouveau que la fonction n'est pas définie. Ce truc aura ma peau...

  13. #13
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par Mayamok
    Décidément...

    J'ai complété ma requête, corrigé la fonction (VBA a une façon très personnelle d'effectuer des opérations sur les booléens! ) et maintenant, elle fonctionne quand je la lance depuis le créateur de requêtes (affichage SQL) dans Access.

    Mais quand je lance exactement la même requête (copier-coller à l'appui) depuis mon programme VB.NET, ça replante en me disant à nouveau que la fonction n'est pas définie. Ce truc aura ma peau...
    Ceci est "normal" et dépend du composant en charge de l'évaluation des expressions au sein d'une requête SQL (je te parle du moteur de bases de données JET).

    Lorsque tu exécutes une requête à partir de l'application Access, alors c'est Access qui est en charge de l'évaluation des expressions.
    Et Access reconnaît l'existence de ta fonction.

    Lorsque tu exécutes une requête à partir d'un autre environnement, alors c'est un composant d'évaluation standard qui est en charge de l'évaluation des expressions.
    Ce composant d'évaluation standard comprend un sous ensemble des fonctions Visual Basic élémentaires. En revanche, il ne comprend rien aux fonctions intégrées d'Access ni à celles définies dans des modules de code Access (comme ta fonction TestBits).

    Tu comprends mieux le problème

  14. #14
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    Tu comprends mieux le problème
    J'en ai peur... Il semblerait que je sois obligé soit de laisser tomber ACCESS, soit de créer un champ booléen par bit plutôt que de tout stocker dans un champ Integer...

  15. #15
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut [ACCESS][SQL][VBA] Tester un seul bit à la fois
    Citation Envoyé par Mayamok
    Il semblerait que je sois obligé soit de laisser tomber ACCESS, soit de créer un champ booléen par bit plutôt que de tout stocker dans un champ Integer...
    Pas de précipitation.
    Si tu souhaites seulement tester un bit à la fois, alors il y a une solution au moyen d'une expression mathématique que le composant d'évaluation peut traiter.

    Voici l'expression VB:
    (v/2^b) mod 2
    L'évaluation de cette expression retourne 1 si le bit est levé.
    Si le bit est baissé, l'évaluation retourne 0.

    Tu remplaces v par le nombre que tu veux tester (par ex. le champ integer).

    Tu remplaces b par la position à tester:
    0 si tu veux tester le premier bit (valeur 1),
    1 si tu veux tester le deuxième (valeur 2),
    2 si tu veux tester le troisième (valeur 4),
    ...
    7 si tu veux tester le huitième (valeur 128),
    ...
    etc

    En attendant de passer sous ORACLE tu peux déjà essayer cette solution "à moindre frais".

  16. #16
    Membre à l'essai
    Inscrit en
    Janvier 2004
    Messages
    28
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 28
    Points : 16
    Points
    16
    Par défaut
    C'est comme si vous utilisiez , qui retourne "True" si le bit b dans le nombre v est à 1. mais je ne sais pas si le composant d'évaluation sait traiter ça.

    De toutes manières, je teste plusieurs bits, et c'était l'objet de ma fonction. Je pense que je vais me rabattre sur une série de champs booléens (heureusement que j'ai un nombre fixe de positions à tester!)

    Encore un grand merci pour votre temps et votre attention.

  17. #17
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Citation Envoyé par Mayamok
    C'est comme si vous utilisiez , qui retourne "True" si le bit b dans le nombre v est à 1. mais je ne sais pas si le composant d'évaluation sait traiter ça.
    Justement non !
    Le composant responsable de l'évaluation ne reconnait l'opérateur AND que sous sa forme Logique (et non pas binaire).

    D'où la formule mathématique...

    Bon courage pour les modifications !

  18. #18
    Membre émérite

    Profil pro
    Inscrit en
    Février 2005
    Messages
    1 751
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 1 751
    Points : 2 368
    Points
    2 368
    Par défaut
    Pardonne moi si je t'importunes,

    Je réfléchissez au "coût" des modifications.

    Si tu passes sur des champs Booléens, dans ta requête tu devras quand même les tester un à un (donc 8 tests pour gérer un octet).
    Sans parler du coût des transformations de ton code.

    C'est peut-être une alternative sérieuse que de ne pas toucher au champ integer et de compléter ta requête avec autant de tests que nécessaires mais basés sur la formule mathématique.

    Dans v on place l'integer à tester.
    Dans b on place une chaîne de caractères avec le "rang" des bits qui doivent être levés:

    Par exemple pour tester si les bits de rang 0, 1 et 6 sont levés dans l'integer 73:
    v=73
    b="016"

    Expression pour tester le bit de rang 6, sous réserve que ce n° de rang apparaisse dans b:
    iif(instr(b,6), (v\2^6) mod 2,1)
    Il ne reste plus qu'à généraliser et simplifier l'expression pour être capable de tester si un ou plusieurs bits aux rangs compris entre 0 et 7, sont tous levés:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        IIf(InStr(b, 0), v Mod 2, 1) And
        IIf(InStr(b, 1), (v \ 2) Mod 2, 1) And 
        IIf(InStr(b, 2), (v \ 4) Mod 2, 1) And 
        IIf(InStr(b, 3), (v \ 8) Mod 2, 1) And 
        IIf(InStr(b, 4), (v \ 16) Mod 2, 1) And 
        IIf(InStr(b, 5), (v \ 32) Mod 2, 1) And 
        IIf(InStr(b, 6), (v \ 64) Mod 2, 1) And 
        IIf(InStr(b, 7), (v \ 128) Mod 2, 1)
    Je pense que ça vaut le coup d'utiliser cette expression complexe plutôt que de modifier la table.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/08/2005, 14h40
  2. Réponses: 8
    Dernier message: 18/07/2005, 14h04
  3. Insérer un entier sur 64 bits dans une base ?
    Par DJZiaK dans le forum SQLite
    Réponses: 1
    Dernier message: 10/05/2005, 17h37
  4. Ecriture d'un seul bit dans un fichier
    Par fantomasmusic dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 31/01/2005, 19h21
  5. stockage d'images dans Mysql
    Par sessime dans le forum Bases de données
    Réponses: 3
    Dernier message: 23/02/2004, 16h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo