OVH Cloud OVH Cloud

Repérage d'un sous-flux de feuille de calcul

14 réponses
Avatar
Jean Bonneau
Bonsoir !

Je voudrais trouver l'offset d'une feuille de calcul dans un fichier BIFF8. Pour
l'instant je sais juste comment positionner un IStream sur le flux "Workbook" du
compound file, mais après je ne sais pas trop comment boucler sur les
enregistrements de ce flux pour repérer les BUNDLESHEET. Le SDK d'Excel ne donne
aucun exemple de code.

J'ai posé la question sur 36 forums sans trouver de réponse alors j'essaie ici
en espérant sans beaucoup d'espoir qu'un expert aura la solution...

Merci...

Jean

4 réponses

1 2
Avatar
Paul V.
Salut JPS.

Globalement je suis d'avvord avec ta fonction mais je voudrais quand même y
mettre mon grain de sel, question de montrer que le V de mon nom n'est pas
usurpé.

Donc je te signale que si tu remplace :

unsigned short grbit;

de départ par

Signed short grbit
//copyright Paul V pour que les choses soient claires et rendre à Paul V ce
qui est à Paul V

tu peux gagner une phase importante de ton processus.

Je sais que tu a tout de suite compris le pourquoi mais pour les nombreux
débutants de cette liste, je précise que dans ce cas, au moment du start du
processus, tu ne dois plus lire le descripteur

pStream -> Read(Record, 4, &pcbRead);

puisque il est checké intrinsèquement dans son intégrité au niveau primaire,
ou, à défaut , il ne renvoie que des informations chéckées par différences
réferentielles.

L'avantage est énorme puisque si, dans la phase finale ou tu écris

// on met la longueur de INDEX dans la variable IndexLen
pStream -> Read(IndexLen, 2, NULL);


si, je précisais donc, tu dépasse la longueur de la variable dans IndexLen,
tu établis un nouveau record sans aucune erreur possible.

Et tout le monde sait que si tu dépasse (on aurais pu dire , si tu bats un
record) *et que ton short (grbit) est signé, tu touche fatalement bien plus
de pognon que si tu as un short de chez prisunic non signé.

Je croyais intéressant d'attirer ton attention sur ce point quand même
essentiel.

Ne me remercie pas, c'est fait avec grand plaisir

Paul V
* Ton processus est génial pour un record de longueur et peut être adapté à
la hauteur, au sprint et à l'endurance mais je crois que cela ne marchera
pas pour la perche que tu nous a tendu ;-)


"jps" a écrit dans le message de news:

bonsoir jean,
bouhhhhhhh, si tu savais comme j'ai pu moi-même déjà beaucoup galéré pour
comprendre comment naviguer dans les sous-flux mais bon, c'est bien parce
que c'est toi et que si tu es venu sur ce forum, c'est pour y trouver de
l'aide...
je te livre donc un bout de code que j'ai pondu il y a quelques mois et
qui,
j'espère,
pourra t'aider.
cette fonction cherche le sous-flux de la feuille "sheetname" dans le book
stream "pStream" et renvoie true (prononcez "trou")le cas échéant. si la
feuille a été trouvée, l'offset de l'enregistrement INDEX est mis dans la
variable IndexLen.
tu ne manqueras pas de noter que j'ai ajouté des commentaires pour que tu
capich bien la démarche.
si tu as des problèmes, klaxonne, on boit un coup, on se fait une bouffe
et
on en reparle.


or donc, voici la fonction :

bool SearchSheet(const char *sheetname, IStream* &pStream,
unsigned short* IndexLen)
// (c) jps, mpfe
{

unsigned short Record[2];
unsigned short lbPlyPos;
unsigned short grbit;
unsigned short cch;
char* rgch;

unsigned short BOFLen;

bool SheetFound;

ULARGE_INTEGER Pos;
LARGE_INTEGER NewPos;
unsigned long pcbRead;

for(;;)
{
// on lit le descripteur et la taille du BIFF record
pStream -> Read(Record, 4, &pcbRead);
if(pcbRead < 4) return false; // erreur => fin du Book Stream

pStream -> Seek(ToLargeInt(0), STREAM_SEEK_CUR, &Pos);

if(Record[0] == 0x85) // c'est un BOUNDSHEET
{
// position du BOF Record de la feuille
pStream -> Read(&lbPlyPos, 4, NULL);
// attention aux modifs éventuelles avec BIFF7...
pStream -> Read(&grbit, 2, NULL);

// est-ce bien une feuille de calcul ?
if(grbit < 2)
{
pStream -> Read(&cch, 2, NULL);
// Nom de la feuille = bonne longueur ?
if((size_t)cch == strlen(sheetname))
{
rgch = (char*)malloc(cch);
pStream -> Read(rgch, cch,NULL);
SheetFound = memicmp(rgch, sheetname, cch) == 0;
free(rgch);
// si feuille trouvée, SheetFound = True
if(SheetFound)
{
// on déplace pStream vers le BOF Record de la feuille
NewPos.QuadPart = lbPlyPos + 2;
pStream -> Seek(NewPos, STREAM_SEEK_SET, NULL);

// on déplace pStream vers le INDEX Record
pStream -> Read(&BOFLen, 2, NULL);
NewPos.QuadPart = BOFLen + 2;
pStream -> Seek(NewPos, STREAM_SEEK_CUR, NULL);

// on met la longueur de INDEX dans la variable IndexLen
pStream -> Read(IndexLen, 2, NULL);
NewPos.QuadPart = 4;
pStream -> Seek(NewPos, STREAM_SEEK_CUR, NULL);
return true;
}
}
}
}
NewPos.QuadPart = (unsigned __int64)Record[1] + Pos.QuadPart;
pStream -> Seek(NewPos, STREAM_SEEK_SET, NULL);
}
}

HTH
jps



"Jean Bonneau" a écrit dans le message de
news:u$

Bonsoir !

Je voudrais trouver l'offset d'une feuille de calcul dans un fichier
BIFF8. Pour

l'instant je sais juste comment positionner un IStream sur le flux
"Workbook" du

compound file, mais après je ne sais pas trop comment boucler sur les
enregistrements de ce flux pour repérer les BUNDLESHEET. Le SDK d'Excel
ne
donne

aucun exemple de code.

J'ai posé la question sur 36 forums sans trouver de réponse alors
j'essaie
ici

en espérant sans beaucoup d'espoir qu'un expert aura la solution...

Merci...

Jean





Avatar
Paul V.
Je vois que tu essaye de recréer, à l'aide de Jean, la bande à bonneau sur
ce forum.
Je t'ai toujours soutenu mais je refuse de te suivre dans ton délire
anarchiste.

A+

Paul V, dit la science.

"jps" a écrit dans le message de news:

bonjour jean
j'avais l'espoir que quelque "poste de nuit" prît le relais pour répondre
à
ton complément d'information mais que nenni ; j'en conclus que quand il
s'agit de se gausser des uns et des autres (et surtout de moi), tu as
toute
une panoplie de mauvaises langues qui s'expriment mais quand il s'agit de
répondre sérieusement à une question certes pas facile, je te l'accorde
(mais on en a vu ici de plus ardues et en disant cela, je pense à celles
auxquelles michel P apporte une solution), de répondre, disais-je, à une
question et surtout à un complément de question (car sans réponse à
celui-ci, c'est tout un projet qui part en brioche), eh bien, tu as beau
faire un 360° sur toi-même, tu ne vois personne....
ce qui me fait le plus râler, c'est que nous avons vécu une époque ici
(mais
tu ne devais pas être sur le forum à l'époque, jean) où un charlot à
pseudonyme variable poser des questions à la c... et toute une pléthore de
contribuables et non des moindres se précipitaient, que dis-je, se
battaient
pour répondre...enfin, je ne veux pas remuer la fange, ça me donnerait des
nausées...
ceci dit, j'essaie, comme promis hier soir, de compléter ma réponse

"Jean Bonneau" a écrit dans le message de
news:

C'est remoi.

J'aurais deux précisions à te demander :


// on lit le descripteur et la taille du BIFF record
pStream -> Read(Record, 4, &pcbRead);
if(pcbRead < 4) return false; // erreur => fin du Book Stream


Ca ne serait pas plus simple de tester le code de retour de pStream ->
Read ?


if (pStream -> Read(Record, 4, &pcbRead) != S_OK) return false;


non point, jean ; comme je commençais à l'entrevoir hier soir, si tu lis
attentivement les spécifications de IStream::Read, tu apprendras que :

"The actual number of bytes read can be fewer than the number of bytes
requested
if an error occurs or if the end of the stream is reached during the read
operation. The OLE-provided implementation of IStream returns S_OK if the
end of
the stream was reached during the read. (This is the same as the "end of
file"
behavior found in the MS-DOS FAT file system."

je me suis fait avoir une fois, et un jps averti vaut 100 LL.



// attention aux modifs éventuelles avec BIFF7...


Quelles sont ces modifications ?


j'aurais dû te le le préciser tout de suite, excuse-moi :

cch est sur 1 octet au lieu de 2, donc en BIFF7 :

pStream -> Read(&cch, 1, NULL);

tu peux obtenir la version du classeur par le membre "vers" du BOF record
(offset 4), mais ça je pense que tu le sais déjà (sinon, reklaxonne et on
reboit un coup, on se refait une bouffe et on en rereparle).

sur ce, j'entends sonner 8 heures, je me sauve

HTH


TH à la puissance 10, jps. :-)


et toi, TH achement sympa dans tes appréciations...

Jean
jps






Avatar
GD
Heu Isabelle ;o)))
../..
à une époque ici (mais tu devais déja ;o))) être sur le forum à l'époque
Isabelle...)
où un charlot à pseudonyme variable posait des questions à la c...
et toute une pléthore de contribuables et non des moindres se précipitaient,
que dis-je, se battaient pour répondre...
../..
il m'est avis que ce jambonneau c'est de l'AOC Charlot 1ére génération !!!!!

manque que Geo, Christian (@(none), Sabre des neiges, Charles etc...
;o)))

isabelle wrote:
hé ! ça fait du bien un séjour à la goële, ça te remet un homme
sul'piton, bravo jean paul comme tu réagi bien dans l'adversité ;-)
isabelle


Avatar
isabelle
:-)))))))))))
oui GD ok, ce n'est pas jean paul 3 mais bien jean paul 50 pour ne pas
dire jean paul 50 50 ;-)

isabelle

Heu Isabelle ;o)))
../..
à une époque ici (mais tu devais déja ;o))) être sur le forum à l'époque
Isabelle...)
où un charlot à pseudonyme variable posait des questions à la c...
et toute une pléthore de contribuables et non des moindres se précipitaient,
que dis-je, se battaient pour répondre...
../..
il m'est avis que ce jambonneau c'est de l'AOC Charlot 1ére génération !!!!!

manque que Geo, Christian (@(none), Sabre des neiges, Charles etc...
;o)))

isabelle wrote:

hé ! ça fait du bien un séjour à la goële, ça te remet un homme
sul'piton, bravo jean paul comme tu réagi bien dans l'adversité ;-)
isabelle







1 2