[Calc] Test d'existence des feuilles et création éventuelle

Discussions et questions sur tout ce qui concerne la programmation tous langages et tous modules confondus.

Modérateur : Vilains modOOs

Règles du forum
:alerte: Balisage obligatoire dans cette section !
Aidez-nous à vous aider au mieux en balisant correctement votre question : reportez-vous sur les règles de cette section avant de poster !
Avatar de l’utilisateur
Pyanepsion
Membre hOOnoraire
Membre hOOnoraire
Messages : 191
Inscription : 11 mars 2006 07:53

[Calc] Test d'existence des feuilles et création éventuelle

Message par Pyanepsion »

J'ai un dossier Calc devant posséder les 8 feuilles suivantes :
Filtres, Tendance, Rentabilité, Seuil, Frais, Carnet, Historique, Résumé.

Je voudrais tester l'existence de ces feuilles et si elles n'existent plus, les remplacer par des feuilles vierges du nom correspondant.

Peut-on utiliser des For Next, et dans ce cas comment faire? Quel est la méthode la plus adaptée?
Window XP. Excel 2000. Works suite 2003. Open Office. Java Sun. Maxthon. Le tout mis à jour sur les nouvelles versions françaises dès qu'elles sont disponibles.
jeromeC
Membre OOrganisé
Membre OOrganisé
Messages : 50
Inscription : 24 mars 2006 22:19
Localisation : France - Nantes

Message par jeromeC »

Salut, il y a plusieurs moyens pour répondre à ta question. Je te propose ici une solution parmi d'autres :

Création d'une fonction nommée Macro qui permet de chercher une feuille (1er paramètre) et éventullement de créer une nouvelle feuille avec ce nom (2e paramètre True ou False pour indiquer si on veut créer une feuille et 3e paramètre la position de création de la nouvelle feuille.

Code : Tout sélectionner

public function Macro(ByVal sRechercheFeuille as string, optional bCreation as boolean, optional lPosition as long) as boolean

dim tListSheets as variant
dim bFeuillePresente as boolean
dim oSheet as object


if ismissing(bCreation) then
	bCreation=false
else
	if ismissing (lPosition) then
		msgbox "le paramètre de position est manquant"
		exit function
	end if
end if

tListSheets=ThisComponent.sheets.createEnumeration
bFeuillePresente=false

do while tListSheets.hasMoreElements
	oSheet=tListSheets.nextElement
	if oSheet.name=sRechercheFeuille  then
		bFeuillePresente=true
		Macro=bFeuillePresente
		exit do
	end if
loop

if not bFeuillePresente then
	Macro=bFeuillePresente
	if bCreation then
		ThisComponent.sheets.insertNewByName(sRechercheFeuille, cint(lPosition))
	end if
end if

end function

dans cette procédure, on utilise la fonction Macro avec 2 exemples

Code : Tout sélectionner

sub Test
Macro("Feuille1")   'Renvoie True si la feuille Feuille1 est trouvée False sinon et ne créé rien.
Macro("AInsérer",True,0) 'Renvoie Faux si la feuille AInsérer n'est pas trouvée et la créé en 1ere position (0), sinon renvoie True et ne créé rien.
end sub
J'espère avoir été assez clair.

Comme tu le mentionnais, on peux utiliser aussi des boucles For...Next au lieu des collections d'objets dans cette fonction.
Ce serait un truc du genre :

Code : Tout sélectionner

for i=0 to ThisComponent.sheets.count-1
if not ThisComponent.sheets.hasByName("Feuille1") then
ThisComponent.sheets.insertNewByName("Feuille1",0)
end if
next
Moi, je préfère utiliser les collections d'objets, à voir ce que tu préfères...

Jérôme.
Windows XP SP2 + Ooo 2.0.2 (US)
Avatar de l’utilisateur
Pyanepsion
Membre hOOnoraire
Membre hOOnoraire
Messages : 191
Inscription : 11 mars 2006 07:53

Message par Pyanepsion »

Merci JeromeC pour ta réponse. Elle me permet d'envisager d'autres voies assez intéressantes.

Le problème que je vois avec les For Next est que les 8 feuilles ont un nom prédéfini. En GFA j'aurais créé un tableau de texte NomFeuille$ et affecté à chacun de ses éléments le nom de la feuille correspondante. La boucle for next permettrait un gain de vitesse sans compter l'élégance du code.

Code : Tout sélectionner

FOR NumeroFeuille=0 TO ThisComponent.sheets.count-1
...Si lafeuille NumeroFeuille n'existe pas ALORS
......Créer la feuille NumeroFeuille avec le nom Nomfeuille$(NumeroFeuille)
...ENDIF
NEXT NumeroFeuille
J'ignore comment procéder avec le basic Open Office, et si cette méthode est alors la plus rapide?
Window XP. Excel 2000. Works suite 2003. Open Office. Java Sun. Maxthon. Le tout mis à jour sur les nouvelles versions françaises dès qu'elles sont disponibles.
jeromeC
Membre OOrganisé
Membre OOrganisé
Messages : 50
Inscription : 24 mars 2006 22:19
Localisation : France - Nantes

Message par jeromeC »

C'est vrai que pour ton cas, la fonction que je t'ai écrite dans le précédent mail n'est pas très adaptée. En fait, je l'utilise pour moi pour travailler dans des feuilles Calc. Ton problème étant assez simple, essaie le code suivant. Je ne l'ai pas testé mais normalement ça doit marcher :

on créé un tableau avec le nom de tes 8 feuilles et on parcourt chaque élément du tableau pour voir si la feuille existe et on la créé éventuellement en la mettant en 1ere position.

Code : Tout sélectionner

tArray= Array("Feuille1", "Feuille2", "Feuille3", ....., "Feuille8")

for lIndex=o to ubound(tArray)
  if not ThisComponent.sheets.hasByName(tArray(lIndex)) then
        ThisComponent.sheets.insertNewByName(tArray(lIndex),0)
   end if
next 
Windows XP SP2 + Ooo 2.0.2 (US)
Avatar de l’utilisateur
Pyanepsion
Membre hOOnoraire
Membre hOOnoraire
Messages : 191
Inscription : 11 mars 2006 07:53

Message par Pyanepsion »

Mon projet commence à prendre forme grâce à toi CJerome :P

Il y a certaines particularités qui m'étonnent un peu dans le basic de Open Office. Ouvre une feuille Calc. Crée une unique feuille nommée "Filtre". Mets y le code suivant :

Code : Tout sélectionner

REM  *****  BASIC  *****
option explicit
Sub Main
	Dim Document As Object
	Dim Feuilles() as Object
	Dim i as Integer
	Dim Message as string
	Dim Tableau()
	
	Document = ThisComponent
	Feuilles = Document.Sheets

	' Lecture des 7 pages de bases.
	Tableau = array("Rentabilité", "Seuil", "Frais", "Carnet", "Filtre", "Historique", "Résumé")
	' Test d'existences des 8 feuilles
	For i=0 to ubound(Tableau)
		if not Feuilles.hasByName(Tableau(i)) then
			Feuilles.insertNewByName(Tableau(i),i)
			Message = Tableau(i)+chr(13)+Message
		End if
	Next i
	Print Message
	' Fabrication des pages manquantes
	' Saisie manuelle de l'historique : colorisation selon la feuille de Filtre.
End Sub
1- Le tableau Tableau() peut être déclaré de n'importe quel type (as etc.), la fonction Array le considérera finalement comme un type Variant?

2-Comment faire pour ajouter des éléments au tableau Tableau() ?

3- Print se comporte bizarrement. Il affiche le dernier texte, puis l'avant dernier puis enfin tous les autres. Pourquoi?

4-Si je veux remplacer Tableau() par un tableau à 2 dimensions, comment faire pour qu'il comprenne d'une part la liste des 8 noms précités et en 2° liste associée les codes boolean Vrai et Faux?
Dit autrement :
Élément 1 : "Rentabilité", Faux
Élement 2 : "Seuil", Faux
Élement 3 : etc.
Window XP. Excel 2000. Works suite 2003. Open Office. Java Sun. Maxthon. Le tout mis à jour sur les nouvelles versions françaises dès qu'elles sont disponibles.
jeromeC
Membre OOrganisé
Membre OOrganisé
Messages : 50
Inscription : 24 mars 2006 22:19
Localisation : France - Nantes

Message par jeromeC »

Ami Trader bonjour,

j'ai la solution à tous tes problèmes : j'ai vu que tu avais mis un autre bug sur la gestion des styles dans des cellules. Je peux aussi t'apporter une solution.

Par contre, je n'ai pas trop le temps maintenant : ce soir, je t'indiquerai tout cela.

A+. Jerome.
Windows XP SP2 + Ooo 2.0.2 (US)
jeromeC
Membre OOrganisé
Membre OOrganisé
Messages : 50
Inscription : 24 mars 2006 22:19
Localisation : France - Nantes

Message par jeromeC »

Me revoila : voici ce que je te propose comme solution :

1- la fonction Array renvoie toujours un type Variant, donc ton tableau Tableau() sera de type Varaint.

2- Si tu veux ajouter des éléments, tu utilises ceci :

Code : Tout sélectionner

lIndex=ubound(tableau)
redim preserve tableau(lIndex+1)
tableau (lIndex+1)="Supplément"
l'instruction redim preserve redimensionne ton tableau d'une unité en conservant ce qu'il y a (l'instruction redim seule recréé ton tableau et rien n'est conservé).

3- 2 erreurs : c'est tout bête mais c'est le genre de truc qui te fait arracher les cheveux et quand tu te rends compte de la solution :twisted:
Donc, c'est normal qu'il te renvoie les feuilles à partir de la dernière : au lieu d'écrire

Code : Tout sélectionner

Message = Tableau(i)+chr(13)+Message
il faut écrire

Code : Tout sélectionner

Message = Message + chr(13) + Tableau(i)
Ensuite, avec la commande print, tu ne peux afficher qu'une suite de caractères, tu ne peux pas retourner à la ligne sinon il va t'afficher chaque valeur dans une boite.
Utilise MsgBox pour ça.
Avec Print, parfois, j'utilise la virgule comme séparateur.

Code : Tout sélectionner

Message = Message + « , » + Tableau(i)
print Message
4- Je te propose une solution pour le cas mentionné :
Pour que cet exemple marche, il y a 2 tableaux qui ont la même dimension et on en créé un nouveau qui rassemble les 2.
Ce n'est pas obligé d'avoir un 2e tableau, à toi d'adapter comme tu veux. Dans le 1er For...Next, tu peux remplacer l'instruction Tableau1(i) par la valeur que tu veux.

Code : Tout sélectionner

Tableau = array("Rentabilité", "Seuil", "Frais", "Carnet", "Filtre", "Historique", "Résumé")
Tableau1= array("Faux","Vrai","Faux","Faux","Vrai","Faux","Vrai")
   
redim TableauFinal(0)

for i=0 to ubound(Tableau)
	TableauFinal(i)=Array(Tableau(i),Tableau1(i))
   redim preserve TableauFinal(i+1)
next
   	
for i=0 to ubound(TableauFinal())-1
	oElem=TableauFinal(i)
	Message = Message + "(" + oElem(0) + "," + oElem(1) + ");"
next
   	
msgbox Message
Voila pour tout ça. Sinon, pour ton autre interrogation sur le style des cellules, je t'ai répondu dans ce message.

Jérôme.
Windows XP SP2 + Ooo 2.0.2 (US)
Avatar de l’utilisateur
Pyanepsion
Membre hOOnoraire
Membre hOOnoraire
Messages : 191
Inscription : 11 mars 2006 07:53

Message par Pyanepsion »

Merci une fois de plus CJerome pour toutes tes explications.

Pour Print l'inversion entre Message et Tableau(i) est volontaire. Puisque j'obtenais 3 boîtes Print j'ai testé pour voir ce qui se passait si Message ne commençait pas par un CHR(13). Je ne comprends pas la logique des 3 boîtes Print obtenues là où je n'en attendrais qu'une seule (ou bien autant de boîtes que de valeur affichée si le CHR(13) provoquait une fermeture de la boîte en cours !).

Où peut-on voir une vraie doc en français sur les macros dans Calc? Ce que j'ai trouvé est un bon début mais je n'arrive pas à trouver quelques choses d'exhaustif :
- Comment utiliser des Macros Basic dans OpenOffice.org?
- l'API OpenOffice.org (presque) sans peine.
- Guide des fonctions de Calc.
Window XP. Excel 2000. Works suite 2003. Open Office. Java Sun. Maxthon. Le tout mis à jour sur les nouvelles versions françaises dès qu'elles sont disponibles.
jeromeC
Membre OOrganisé
Membre OOrganisé
Messages : 50
Inscription : 24 mars 2006 22:19
Localisation : France - Nantes

Message par jeromeC »

J'ai posté un nouveau message pour tous les utilisateurs du forum sur un pdf français qui explique bien les éléments de programmation OpenOffice. Je te redonne l'Url : http://fr.openoffice.org/Documentation/ ... ndrew5.pdf

Pour le site de l'API, il y a bien le site http://api.openoffice.org/ mais c'est un peu une usine à gaz !! Pour trouver ce que tu cherches, bon courage...

pour le guide des fonctions de Calc, à part l'aide et les bouquins du commerce, je ne connais rien d'autre.

Jérôme.
Windows XP SP2 + Ooo 2.0.2 (US)