DAO, SQL, VBA et "Bitwise"

C

CtiMcs

Bonjour,

Je suis surtout utilisateur du C++ (dans Visual C++) et du
Pascal (dans Delphi), ceci explique peut-être pourquoi
VBA me donne quelques soucis!

Il est écrit dans diverses docs sur VBA (dans Excel par exemple)
que l'opérateur And est l'opérateur logique entre des expressions
booléennes ET l'opérateur 'bitwise' entre des expressions numériques.

Il est écrit par ailleurs, que DAO 3.6 (MS Jet 4.0) utilise VBA
pour évaluer tout ce qu'il peut évaluer avant d'envoyer la requête.

Sous ces hypothèses, pourquoi le code suivant, appliqué à une table
où Attributs = 17, 18, ou 33 ne retourne rien, (rs=le recordset)
-----------------------------------------------------------------
rs.FindFirst(' (CLng(Attributs) And CLng(16)) = 16 ');

while not rs.NoMatch do
begin
attr:=rs.Fields.Item[2].Value; s:=Format('%3.3d: ',[attr]);
LstPersonnes.Items.Add(s+rs.Fields.Item[0].Value);
rs.FindNext(' (CLng(Attributs) And CLng(16)) = 16 ');
end;
-----------------------------------------------------------------

alors que le code suivant, retourne tout (Attributs n'est jamais 0):
(remarquer le -1 à la place du 16).
-----------------------------------------------------------------
rs.FindFirst(' (CLng(Attributs) And CLng(16)) = -1 ');

while not rs.NoMatch do
begin
attr:=rs.Fields.Item[2].Value; s:=Format('%3.3d: ',[attr]);
LstPersonnes.Items.Add(s+rs.Fields.Item[0].Value);
rs.FindNext(' (CLng(Attributs) And CLng(16)) = -1 ');
end;
-----------------------------------------------------------------

Manifestement, les précautions CLng() sont inopérantes, et le 'And'
travaille toujours sur des booléens, auquel cas l'expression est
toujours vrai (-1) du fait que Attributs n'est jamais = 0.

Merci par avance d'excuser exceptionnellement le multi-post sur
Delphi(pour le contexte et surtout les programmeurs interessés),
DAO (pour le coeur du sujet) et VBA (pour les expressions).

Cordialement,
 
E

Emilia Maxim

Bonjour Claude,

mon "francais d'ordinateur" n'est pas tres bon, mais je vais essayer
de t'expliquer.
Il est écrit dans diverses docs sur VBA (dans Excel par exemple)
que l'opérateur And est l'opérateur logique entre des expressions
booléennes ET l'opérateur 'bitwise' entre des expressions numériques.
Il est écrit par ailleurs, que DAO 3.6 (MS Jet 4.0) utilise VBA
pour évaluer tout ce qu'il peut évaluer avant d'envoyer la requête.

C'est exactement ici qu'il faut faire la différence. VBA et DAO
(autrement dit Jet ou bien SQL) utilise et interprète chacun
l'opérateur dans une manière spécifique. Ca veut dire, dans SQL, AND
est utilisé comme un opérateur logique retournant Faux (False, 0) ou
Vrai (True, -1). Quand on ouvre un recordset en VBA, c'est DAO qui
fait le boulot dans l'arrière-plan. VBA se contente de passer le SQL
(ou query) à DAO et de recevoir quoique DAO retourne.

OTOH si on utilise AND dans une pure expression VBA, il sera
interprété comme l'opérateur 'bitwise'. Par ex:

Resultat = 3 AND 2

rendra 2 comme résultat.
Sous ces hypothèses, pourquoi le code suivant, appliqué à une table
où Attributs = 17, 18, ou 33 ne retourne rien, (rs=le recordset)

Ici, AND s'utilisera comme opérateur boolean. CLng(Attributs) va
donner 17, 18 resp. 33, CLng(16) est 16. Les deux opérands n'étant pas
0, seront interprétés comme True (toute valeur numérique non 0 est
'vraie'). Alors AND rend True aussi, ca veut dire la valeur numérique
-1. Enfin, la comparaison -1=16, étant fausse, ne rendra aucun
résultat, quoique soit la valeur de Attributs.
alors que le code suivant, retourne tout (Attributs n'est jamais 0):
(remarquer le -1 à la place du 16).

Exactement :) Ici, l'expression finale - c'est à dire la comparaison
- sera -1=-1, qui donne True pour tous les records du table,
indépendamment des valeurs dans les records.

Cordialement
Emilia

Emilia Maxim
PC-SoftwareService, Stuttgart
http://www.maxim-software-service.de
 
C

CtiMcs

Merci pour ces eclaircissements,

Je crains d'avoir pris mes desirs pour des réalités.

What you said confirm what I observe, (and I was serching because
I red the opposite in the documentation upon DAO 3.6 (but not 3.5),
or I want to believe I red ...)

I think I will work on the possibility to define a function,
something like "variant MyAND(a,b)" and use it in the WHERE Clause.

Is this possible with Jet SQL (/DAO) ?? ... I will see.


Respectueusement,
 
E

Emilia Maxim

---------- "CtiMcs said:
Merci pour ces eclaircissements,

Je crains d'avoir pris mes desirs pour des réalités.

What you said confirm what I observe, (and I was serching because
I red the opposite in the documentation upon DAO 3.6 (but not 3.5),
or I want to believe I red ...)

I think I will work on the possibility to define a function,
something like "variant MyAND(a,b)" and use it in the WHERE Clause.

Claude,

l'aide pour Office 2000 (and DAO 3.6) - très très poliment dit - n'est
pas la meilleure.

Mais tu aura besoin d'une fonction seulement si tu as besoin de
l'opération "bitwise". Pour rechercher des records avec une valeur
donné ca suffit d'écrire par ex dans une query:

SELECT * FROM MonTable WHERE Attributs = 16

Dans ton code ca serait:

rs.FindNext('Attributs = 16')

le critère pour FindNext ayant la même syntaxe comme la WHERE clause
sans le mot WHERE. Le "=" sera interprété par Jet (DAO) comme une
comparaison, pas comme une assignement. Tu auras besoin de l'opérateur
logique AND seulement si tu voudrais rechercher avec plusieurs champs
qui tous doivent avoir des certains valeurs simultanément dans le même
record (voir tous les critères doivent être vrai simultanémant):

rs.FindNext('Attributs = 16 AND ChampX = "XYZ"')

Apropos, ton code n'est pas VBA, ca devait être plutôt VB :) Il y a
pas de 'begin...end' dans VBA, et l'assignement VBA est "=", sans le
deux-points :)

Cordialement
Emilia

Emilia Maxim
PC-SoftwareService, Stuttgart
http://www.maxim-software-service.de
 
C

CtiMcs

Merci pour votre contribution,

SELECT * FROM MonTable WHERE Attributs = 16

Dans ton code ca serait:

rs.FindNext('Attributs = 16')

Pour pouvoir utiliser cette interrogation, il faut que l'utilisation des
bits soit exclusive; ce n'est pas mon cas:

Si j'ai des valeurs de Attibuts 16, 17, 18, 32, 33,
- l'interrogation (Attributs AND 1) =1 doit donner les 17 et les 33
- l'interrogation (Attributs AND 16)=16 doit donner les 16, 17, 18
.... Tu auras besoin de l'opérateur
logique AND seulement si tu voudrais rechercher avec plusieurs champs
qui tous doivent avoir des certains valeurs simultanément dans le même
record (voir tous les critères doivent être vrai simultanémant):

C'est bien mon cas!
Apropos, ton code n'est pas VBA, ca devait être plutôt VB :) Il y a
pas de 'begin...end' dans VBA, et l'assignement VBA est "=", sans le
deux-points :)

Non, c'est du Pascal!
J'écris les moteurs et fonctions de base (je dis "système") en C++ et je
les mets dans des serveurs DCOM (ou COM+) (avec Visual C++);

J'écris les interfaces utilisateurs (je dis "frontaux") sous Delphi
et donc en Pascal.

Pour finir, je vais utiliser ADO, qui est très voisin (semble-t-il!)
de DAO, et utiliser son opérateur BAND ('Bitwise AND').

Encore Merci,

Respectueusement,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top