6 messages in org.openoffice.fr.progRe: [prog] requietes SQL et operation...
FromSent OnAttachments
Snopie Snopie1Aug 29, 2005 10:31 am 
Bernard MarcellyAug 30, 2005 3:17 am 
Snopie Snopie1Aug 30, 2005 8:25 am 
Bernard MarcellyAug 31, 2005 12:46 am 
Snopie Snopie1Aug 31, 2005 5:09 am 
Bernard MarcellyAug 31, 2005 8:12 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:Re: [prog] requietes SQL et operations sur CurrencyActions...
From:Snopie Snopie1 (snop@yahoo.fr)
Date:Aug 30, 2005 8:25:24 am
List:org.openoffice.fr.prog

Bonjour Bernard Marcelly,

Il y a beaucoup de points à analyser séparément et posément dans ton mail, et il manque des informations pour que la communauté puisse (peut-être) t'aider. Pour ma part je ne suis pas spécialiste de mysql.

desole pour le manque d'info. je suis sous ubuntu hoary 5.04 avec la derniere update. OOo 1.1.3 est installe (je cherche une version stable). je dois avoir une 1.1.4 sur une knoppix dans le coin.

Question : y-a-t-il un problème seulement avec une somme, ou aussi en récupérant une valeur d'un enregistrement? Parce que la somme est calculée par le moteur mysql (sauf erreur de ma part).

le probleme est general au passage de res. mysql aux vars OOBasic. pour l'instant, en passant par val(string), j'arrive tout juste a recuperer la "partie entiere", comme si j'avais accede au champ .Short!

d'autant plus que je ne peux pas faire confiance au calcul flottant.

le contournement a consiste a multiplier par 100...

quel est le type du champ Columns(1) dans ta base mysql ?

decimal(12,2)

quelle est la version de mysql ?

mysql Ver 12.22 Distrib 4.0.23, for pc-linux-gnu (i386)

est-ce que tu as bien défini : Dim str_solde As String

oui, je suis en Option Explicit

msgbox("str_solde=" & str_solde) 'renvoie la sommme tronquee!

qu'est-ce que ça veut dire, tronquée ? il faudrait

tronquer au sens mathematique: 13.45 est une troncature de 13.4512. on appelle ca arrondi, aussi.

des exemples réels avec le contenu de la base et le résultat dans

qu'a cela ne tienne!

=====mysql====== mysql> desc mouvements_clients; +-----------------------------------+------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------------------------------+------------------+------+-----+---------+----------------+ | idmouvements_clients | bigint(20) | | PRI | NULL | auto_increment | | responsabilites_idresponsabilites | bigint(20) | | MUL | 0 | | | clients_idclients | int(10) unsigned | | MUL | 0 | | | acompte | decimal(12,2) | YES | | NULL | | | debit | decimal(12,2) | YES | | NULL | | | credit | decimal(12,2) | YES | | NULL | | +-----------------------------------+------------------+------+-----+---------+----------------+ 6 rows in set (0.00 sec)

mysql> select * from mouvements_clients where responsabilites_idresponsabilites=7 and clients_idclients=1; +----------------------+-----------------------------------+-------------------+---------+----------+--------+ | idmouvements_clients | responsabilites_idresponsabilites | clients_idclients | acompte | debit | credit | +----------------------+-----------------------------------+-------------------+---------+----------+--------+ | 40 | 7 | 1 | 0.00 | 145.75 | 0.00 | | 41 | 7 | 1 | 0.00 | 15000.90 | 0.00 | +----------------------+-----------------------------------+-------------------+---------+----------+--------+ 2 rows in set (0.01 sec)

mysql> select (sum(acompte)-sum(debit)+sum(credit)) from mouvements_clients where mouvements_clients.responsabilites_idresponsabilites=7 and clients_idclients=1; +---------------------------------------+ | (sum(acompte)-sum(debit)+sum(credit)) | +---------------------------------------+ | -15146.65 | +---------------------------------------+ 1 row in set (0.00 sec)

=====mysql======

===mysqldump=== DROP TABLE IF EXISTS `mouvements_clients`; CREATE TABLE `mouvements_clients` ( `idmouvements_clients` bigint(20) NOT NULL auto_increment, `responsabilites_idresponsabilites` bigint(20) NOT NULL default '0', `clients_idclients` int(10) unsigned NOT NULL default '0', `acompte` decimal(12,2) default NULL, `debit` decimal(12,2) default NULL, `credit` decimal(12,2) default NULL, PRIMARY KEY (`idmouvements_clients`), KEY `mouvements_clients_FKIndex1` (`clients_idclients`), KEY `mouvements_clients_FKIndex2` (`responsabilites_idresponsabilites`) ) TYPE=MyISAM;

INSERT INTO `mouvements_clients` VALUES (40,7,1,'0.00','145.75','0.00'); INSERT INTO `mouvements_clients` VALUES (41,7,1,'0.00','15000.90','0.00'); ===mysqldump===

on pourra enlever les lignes contenant les cles etrangeres.

on voit bien que le probleme est externe a mysql.

maintenant le code Basic:

================ Public maConnexion

Dim maRequete As Object Dim res as Object Dim sSQL As String,sSQL100 As String Dim str_solde As String, str_solde100 As String Dim solde As Currency, solde100 As Currency

ConnecterSource()

sSQL="select (sum(acompte)-sum(debit)+sum(credit)) from mouvements_clients where mouvements_clients.responsabilites_idresponsabilites=7 and clients_idclients=1" sSQL100="select (sum(acompte)-sum(debit)+sum(credit))*100 from mouvements_clients where mouvements_clients.responsabilites_idresponsabilites=7 and clients_idclients=1"

maRequete = maConnexion.createStatement() res=maRequete.executeQuery(sSQL) res.next

str_solde=res.Columns(0).String solde=val(str_solde)

maRequete = maConnexion.createStatement() res=maRequete.executeQuery(sSQL100) res.next

str_solde100=res.Columns(0).String solde100=val(str_solde100)/100

msgbox "str_solde=" & str_solde & chr(13) & "solde=" & solde & chr(13) & chr(13) & "str_solde100=" & str_solde100 & chr(13) & "solde100=" & solde100 ' str_solde="-15146", solde=-15146.0000, str_solde100="-1514665", solde100=-15146.6500 ================

un problème de Locale (point ou virgule décimale, séparateur de milliers).

peut-etre, mais la conversion us->fr se passe correctement. (les points sont convertis en virgules)

de toute façon .Short va supprimer les décimales.

vrai

.Double n'est pas acceptable car les

calculs doivent etre exacts (cf. plus loin).

ça ce n'est pas évident. Les .Short .String .Double font des conversions entre le *résultat* de la requête et une représentation dans un type Basic. Mais le sum() dans la requête étant traité par le moteur de la base de

données, le type final n'a pas d'impact sur la précision du calcul.

si, justement. un Int, Short ou Long ne garderont que la "partie entiere" (environ...) un Double pourrait etre imprecis pour le stockage d'un nombre a decimales.

__________________________________________________________

je sépare, car ce qui suit est un autre problème qui aurait mérité d'être un mail séparé.

vrai, mais le code montre le lien.

Moi je ne vois plus ces erreurs avec ma "vieille" 1.9.113

hum, 1.1.3

en principe cela devrait marcher à condition de faire un arrondi à 4 décimales lors de la conversion Double > Currency.

le probleme est que le double perd deja l'information (cf la norme ieee du codage de flottant). c'est pour ca, que je ne veux pas passer par le calcul flottant.

Pour cela je viens de concocter une fonction qui a l'air de marcher (sur

je prends note.

- soit passer à la version 1.9 (en supportant les fautes résiduelles diverses)

est-ce qu'il y a une doc ou je pourrais evaluer le travail de migration 1.1.(3|4) -> 1.9 ?

- soit employer un autre langage que Basic. Si dans ton application, OOo n'est qu'un simple moyen de "reporting" il peut être

j'ai vu ca. ;)

plus judicieux d'utiliser un langage indépendant (Python, Java, Delphi, C++) pour interroger la base et faire des calculs, et de lui faire piloter OOo pour sortir les rapports.

ou en est justement le statut de python pour OOo? j'imagine que java est pret depuis longtemps pour la production. je serais interesse de passer a ces deux langages, vu toutes les complications qu'on a eues a developper cette appli.

Ouf! c'etait un peu long.

merci beaucoup, snopie