OUVRIR UN FICHIER EXCEL SANS AUCUNE DLL OFFICE

cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 - 16 juil. 2010 à 16:23
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 - 26 août 2010 à 09:25
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/52043-ouvrir-un-fichier-excel-sans-aucune-dll-office

Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
26 août 2010 à 09:25
bon ben "gros" update.
Je viens également d'implémenté le "MergeCells" mais je me trouve bien bête a ne pas savoir comment joindre des cellules dans un msHflexgrid.
Si une personne pouvait m'indiquer comment faire. comme cela j'update cette fonction également.
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
24 août 2010 à 13:34
nasserovski merci de ta suggestion. Cependant, même si il est vrai que l'affichage est lent dans une HFlexgrid, son but dans mon code est uniquement de tester la dll. Sa rapidité n'est donc pas importante.
Lorsque je parle de lenteur c'est uniquement celle de la dll qui m'interesse.
Avec le fichier que je donne en exemple, c'est invisible, mais sur un tres gros fichier le chargement est concidérablement plus long. Et encore, je ne charge pas toutes les informations données par le fichier. Telles que les hauteurs de ligne, largeur de colone, type de bordure, couleur de fond, de font et de bordure des cellules. Le font, le format, les formulas ...

amicalement,
nasserovski Messages postés 5 Date d'inscription jeudi 11 mai 2006 Statut Membre Dernière intervention 11 avril 2011
24 août 2010 à 11:36
N'oubliez pas le contrôle utilisé recevant les valeurs. Dans notre cas c'est le flex grid. Peut etre que le datagrid de .net est plus rapide. le grid utilisé dans Excel est pratiquement inconnu. Pourquoi ne pas essayer un Spreadsheet du Web Components (OWC).
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
23 août 2010 à 02:04
Supeeeeeeeeeer ! Continues.

Je ne saurais trop te conseiller d'oublier les optimisations pour le moment. Car c'est un truc a passer des nuits blanches pour pas grand chose. Concentres toi plutôt sur l'essentiel. Une fois ton programme "full featured" tu pourras commencer les optimisations.

Et je te confirme que tu peux faire ça en vb6 et sans multi-thread.

Courage.
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
20 août 2010 à 13:22
Je pensais à une fonction VB6 dont l'utilité est seulement pour assurer la compatibilité avec de vieux trucs, mais pas optimisé du tout, mais pour trouver laquelle c'est pas évident : il faut mettre des timers partout (je ne sais pas si on peut profiler le timing pour l'ensemble des fonctions comme en DotNet).
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
20 août 2010 à 13:08
Patrice99 merci de ta réponse. quand tu dis "une fonction prends du temps". Tu endends quoi par là ? Parsque mon code est trufé d'appels de fonctions, de property Get (qui en soit est une fonction) et de classes. Enfin, de choses normales quand on a la prétention de faire du langage objet ^_^.
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
20 août 2010 à 11:47
C'est déjà sûr et certain que ce n'est pas une question de multi-thread. C'est plutôt l'utilisation d'une fonction VB6 qui prend du temps (en DotNet, c'est souvent le levage d'une exception qui prend du temps, mais en VB6, c'est plutôt une fonction, reste à savoir laquelle. La dll que j'ai testée en DotNet est quasi-instantanée, il n'y a pas de pb de lenteur pour décoder un fichier Excel).
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
20 août 2010 à 11:13
Bonjour à tous,
La nouvelle version est maintenant sufisament avancée pour être utilisable.
Sous forme de dll on peut dors et déja ouvrir un fichier excel, lister les sheets et accéder aux valeurs des cellules des worksheets.

Il est à noter que sur les très gros fichiers, l'ouverture prends du temps. Les deux phases gourmandes sont le listage des secteurs du compound file; la seconde est le chargement de la table de chaines de caractères (SST). Je ne sais pas comment Excel fait pour charger "aussi vite". Il doit y avoir moyen d'optimiser (sans changer de langage car oui j'en suis tout a fait conscient, VB6 n'est pas ce qu'il y a de plus rapide ><) Je vais regarder du côté du multi thread.

J'atends vos remarques et suggestions avec impassience !
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
22 juil. 2010 à 09:33
Encore une fois bravo et surtout continues.
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
21 juil. 2010 à 23:00
une erreur est présente sur le cell_texte
j'ai mélangé indice de SST et texte
autant pour moi je corrige dès demain
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
21 juil. 2010 à 22:50
UPDATED !!!
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
21 juil. 2010 à 20:53
Bon ben il semblerait que j'ai résolu le problème de la conversion. ^_^
j'avais oublié que les doubles sont sur 8 bytes et non sur 4

je termine le chargement des formula et j'update
nasserovski Messages postés 5 Date d'inscription jeudi 11 mai 2006 Statut Membre Dernière intervention 11 avril 2011
21 juil. 2010 à 19:18
bravo!!!!!
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
21 juil. 2010 à 15:15
J'arrive maintenant a charger les sheets, obtenir leur nom, leur position, si ils sont caché, si ils sont protégés

je sais également le nombre de cellules non vides et comment les charger
je charge les valeurs string
et je suis maitenant bloqué sur le chargement des valeurs numériques.
rt_RK et rt_MulRK
mon problème vien de mon incapacité à décodé ce foutu RKNumber
si une personne (de bon niveau) pouvait jeter un coup d'oeuil et me dire comment m'y prendre ^_^

la spécification est 2.5.17 RKNumber page 896 de la doccumentation [MS-XLS].pdf
j'ai éssayé bien des sollutions et je n'y arrive pas...
voici mon code :

Public Function Read_RKNUMBER(Ptr As cPointeur, Optional pos As Long = -1) As Double
Dim DW As DWORD: DW = Read_DWORD(Ptr, pos)
'récupérer les flags
Dim A As Boolean: A = CBool(DW.bytes(1) And 2 ^ 3)
Dim B As Boolean: B = CBool(DW.bytes(1) And 2 ^ 2)
'passer les deux flags à 0
DW.bytes(1) = DW.bytes(1) And &HFC '0b 1111_1100

Dim tmpD As Double
Dim tmpL As Long

If (B = False) Then
'IEEE754 64bits double précision
'forcer les 2 bits A et B à 0
DW.bytes(4) = DW.bytes(4) And &H3F '0011 1111
'passer en double
CopyMemory tmpD, DW.bytes(1), 4 If (A True) Then tmpD 100 * tmpD
Else
'signed integer
CopyMemory tmpL, DW, 4
'retenir le bit de signe
Dim négatif As Boolean: négatif = CBool(tmpL And &H80000000) 'the most significant bit
'passer le bit de signe à 0
tmpL = tmpL And &H7FFFFFFF
'décaler les bits vers la droite de 2 positions
tmpL = tmpL / 2 ^ 2
'replacer le bit de signe
If négatif Then tmpL = tmpL Or &H80000000 'the most significant bit

If (A = True) Then
tmpD = 100 * tmpL
Else
tmpD = tmpL
End If
End If
Read_RKNUMBER = tmpD
End Function

la céllule contient le chiffre "1"
je lis
DW.bytes(1)=0 '0x00
DW.bytes(1)=0 '0x00
DW.bytes(1)=240 '0xF0
DW.bytes(1)=63 '0x3F

une fois cette étape passée, il me restera plus que les formulas a décoder pour pouvoir lire les Worksheets des fichiers excels...
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
20 juil. 2010 à 14:00
J'ai mis la source à jour
on peut maintenant voir apparaître les records contenus par le Workbook stream
certain records sont d'ailleur notables :
- format
- XF
- boundSheet8
- Country
- SST
...

et surtout
BOF ; Index
qui n'est ni plus ni moins le début du substream concernant les sheets
HAHA !!! les données ne sont plus très loin... enfin si ^_^
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
20 juil. 2010 à 09:14
Comme a ton habitude tu as raison RENFIELD ^_^,
quand j'utilise le LenB j'ai bien la longueur de val alors que Len(Val) ne marche pas (enfin, manque des infos).

Me coucherais encore moins bête ce soir
http://blogs.codes-sources.com/renfield/archive/2009/07/16/len-vs-lenb-copymemory-structures-perso-types-etc.aspx
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
20 juil. 2010 à 01:13
Val n'est pas un pointeur...

on utilise LenB pour les structures, normallement.
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
20 juil. 2010 à 00:00
bon ben avec le vartype et un select case ca semble marcher
je lis un BOF record au début du stream Workbook et ca tombe bien parsque c'est ce que dit la spécification ^_^
j'update demain, enfin, tt a l'heur...
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
19 juil. 2010 à 22:57
a mon avis le len(val)=1 vient du fait que val est un pointeur
je viens de penser à l'astuce du copymemory

si en entrée de la fonction j'ai une variable length
du coup je sais combien de bytes je dois lire avec un tableau de byte c bon
et avec le copy memmory je transfère

mais au finish je ne suis pas capable d'utiliser le CopyMemory puisque Val est l'adresse du pointeur et non l'adresse de la variable source.

n'y a t'il pas moyen de récupérer l'adresse de la variable d'origine a partir du pointeur ?
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
19 juil. 2010 à 22:29
"pas de possibilité d'utiliser de "type" déclarés par moi même..."

si si

if typeName(val) = "TypePerso1" then
...
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
19 juil. 2010 à 22:15
et bien j'y ai penser mais du coup les variables à envoyer sont restreintes par leur type.
pas de possibilité d'utiliser de "type" déclarés par moi même...
Enfin, je vais voir si ca bloque pas c'est ce que je vais utiliser...
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
19 juil. 2010 à 21:51
tu peux peut etre tester le vartpe de val :

vartype(val) = vbInteger, etc.
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
19 juil. 2010 à 20:34
arf je suis embêté par la fonction

'/!\ on suppose qu'une donnée ne peut pas être a cheval sur différents secteurs'
'sinon il faudra rajouter un traitement avec du copy memmory et du len(Val)
Public Sub Read(val As Variant, Optional Pos As Long = -1)
If (Pos > 0) Then p_position = Pos
If Not Me.EOS Then
Dim crt_cur As Long
crt_cur = p_position Mod p_sec_len 'reste de la division entière pour connaitre l'offset dans le secteur courrant
Dim crt_sec As Long
crt_sec = (p_position - crt_cur) / p_sec_len 'forcer division entière
crt_sec = crt_sec + 1 'pour se placer dans le tableau FATs

Dim offset As Long
offset = Address(FATs(crt_sec)) + crt_cur

Get #canal, offset, val

p_position = p_position + Len(val) 'se placer sur la prochaine donnée
Else
'on ne peut pas lire
End If
End Sub

ca ne marche pas comme je le veux. a savoir, que si j'apelle la fonction en mettant un int dans le Val, je me retrouve quand même avec un Len(Val) = 1
et il se trouve que ca casse l'interret de la chose.
Une idée comment implémenter ca pour que ca marche ?
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
19 juil. 2010 à 16:14
Cela ne t'avait pas semblé bizarre qu'il n'y avait aucune source du genre sur VBFrance, alors que des millions de personnes utilisent Excel ? Moralité : ta source serait vraiment très utile, c'est sûr (2 exemples : programmation coté serveur où Excel n'est pas forcément installé, et lecture rapide d'un classeur Excel de façon fiable, pas comme en ODBC), mais c'est du boulot : une bonne idée serait de partir de la source en C# et de faire une version en VB.Net (je vais la tester dès que possible, faut que je réinstalle C# sur mon poste).
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
19 juil. 2010 à 15:24
mouahaha la blague ^_^ les données sont contenues dans des records dont chacun a une constitution propre.
Et il nen n'éxiste pas moins de 354 différents :)
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
19 juil. 2010 à 11:58
merci ^_^
malheureusement je ne peu pas utliser les noms seek et eof car ils appartiennent aux mots réservés de VB6

j'ai donc renommé en position et EOS (end of stream)
j'ai mis a jour le zip. Je be suis pas certaint que la méthode soit très propre mais j'aime l'idée de l'encapsulation.
je vais maintenant m'attaquer aux données d'Excel à proprement parler.

les critiques sont les bienvenues ^^
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
19 juil. 2010 à 10:11
Seek
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
19 juil. 2010 à 10:03
Bonjour,
Dans un premier temps je compte juste me mettre en lecture seule avec une lecture en mode cellule d'excel. Je pense pouvoir récupérer la valeur, la formule et le format d'une cellule. (et je vai faire ce qu'il faut pour)

Je suis en trein de mettre en place un système de lecture dans le fichier en choisissant un stream( ce système de lecture permettrai de lire linéairement sans se préocuper des secteurs et du saut de l'un à l'autre.)

Il me manque cependant le nom de l'instruction qui permet de se placer à un endroit précis d'un fichier. Je sais que cette commande existe mais je n'arrive pas a remettre la main dessus.
Si une perssone pouvait me donner son nom ^_^
merci
zoosil Messages postés 9 Date d'inscription lundi 26 mai 2003 Statut Membre Dernière intervention 12 juillet 2010
19 juil. 2010 à 09:19
Bon !

On attend la suite ...
nasserovski Messages postés 5 Date d'inscription jeudi 11 mai 2006 Statut Membre Dernière intervention 11 avril 2011
19 juil. 2010 à 09:03
Comme a dit EBArtSoft, ca sera plus complet si on peut lire les cellules du genre ReadValue comme la WriteValue dans Excel BIFF.
A part ca tu as fait du bon travail.
Flocreate Messages postés 300 Date d'inscription lundi 17 juillet 2006 Statut Membre Dernière intervention 27 mai 2012 3
17 juil. 2010 à 23:59
merci pour votre soutient, je vais poursuivre le travail des lundi. ^_^
PATRICE99 , oui je sais bien que bien des softs existent mais ce qui m'importe avant tout, c'est de le faire par moi même tant que cela demande une certaine démarche d'apprentissage ^^

et au passage, merci d'éviter le "Convertir un fichier Excel en fichiers Csv" ca me donne de l'urticaire ^_^
cs_Patrice99 Messages postés 1221 Date d'inscription jeudi 23 août 2001 Statut Membre Dernière intervention 9 septembre 2018
17 juil. 2010 à 10:03
Voir aussi :
Xl2Csv : Convertir un fichier Excel en fichiers Csv (ou en 1 fichier txt)
www.vbfrance.com/code.aspx?ID=44827

Excel to SQL without JET or OLE - Kelvin Armstrong
Import an Excel ".xls" into SQL without the use of JET or OLE
www.codeproject.com/KB/cs/ExcelToDB.aspx
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
16 juil. 2010 à 18:29
me rapelle un boulot que j'ai fait il y a presque dix ans...

permettait en php de generer du xls sous linux.

bon boulot, je plussoies EBArtSoft
cs_EBArtSoft Messages postés 4525 Date d'inscription dimanche 29 septembre 2002 Statut Modérateur Dernière intervention 22 avril 2019 9
16 juil. 2010 à 16:23
Ce serait top de pouvoir accéder directement au contenu des cellules sous forme en appelant des objets ex: MonExcel.Cells(x,y).value.

Cool, continues ton comme ça.
Rejoignez-nous