[Résolu][Calc] Vérifier des données dans une plage nommée

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 !
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

[Résolu][Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

Bonjour,
Avant de joindre un exemple, j'explique ce que je n'arrive pas à faire.
Dans un classeur, j'ai des onglets pour les mois et un onglet pour des codes. Dans cet onglet "Codes", pour chaque colonne correspond une plage de base de données qui sont nommées "vert", "bleu", "jaune", etc.
J'ai défini la plage "vert" de A2 à A20, la plage "bleu" de B2 à B20, la plage "jaune" de C2 à C20, et ainsi de suite
Chaque plage a des codes qui ne sont pas fixes et peuvent dont être simplement ajoutés ou supprimés.
Dans un onglet mensuel, lorsque je rentre un code dans une cellule, la case se colore en fonction du code mais comme il y a plus de 3 conditions, je dois passer par une macro qui donne :

Code : Tout sélectionner

    REM  *****  BASIC  *****
    Option Explicit

    global oDoc as Object
    global oListener as Object
    
    Sub o_ListenersAdd
    'Print "C'est parti", spc(1)
       oDoc= thisComponent
       oListener = CreateUnoListener( "o_", "com.sun.star.util.XModifyListener" )   
       oDoc.AddModifyListener(oListener)
    End Sub

    Sub o_ListenersRemove
       oDoc.RemoveModifyListener(oListener)
    End Sub

    Sub o_Modified(oEvent)
       'MsgBox "Modif..."
       dim oEnCours as object
       dim oSheet as Object
       dim oDocument as Object
       oEnCours = thiscomponent.currentSelection
       oDocument = ThisComponent
       oSheet = oDocument.getCurrentController().getActiveSheet()
       if oSheet.getName<>("Codes") then
       if oEnCours.supportsService("com.sun.star.sheet.SheetCell") then 'Ne travaille que si la sélection en cours est une cellule
          select case UCase(oEnCours.string)         'Test selon la chaine contenue dans la cellule en cours
          case "MO","BS","SBS","BHS"
			 coloriage("Vert")	'Voir routine ci-dessous
		  case "X"
		     coloriage("BleuCroix")	 
          case "CA","CF","CET","RTT","RTC","ARTT","RPS","TC","HS","HP","ASA","GEM","PAT","MIL","PACS"
			 coloriage("Bleu")
          case "I","ART13","ART14","BON","STG","RCS","RLS","RL","RC","MO30","BS30","SBS30","MAT","NAI","PEC","CNV","TTP","SPO","TGI","VME","DON"
			 coloriage("Jaune")
		  case "R1","R2","R3","R4","R5"
		     coloriage("R1R2")	 
		  case "DA","POSTE","UTJ","TN","TK","SPORT","TVOFF"
		  	 coloriage("Doléance")
		  case "APP"
		  	 coloriage("APP")	 	 
          case "*","MUT"
			 coloriage("Nouvmut")
          case else                                       'Les autres couleurs sont à compléter.
             if oEnCours.CellStyle <> "Vide" then
                oEnCours.CellStyle="Vide"                     'Le test "Else" sert pour les autres cas => réapplique le style Vide
             end if
          end select
         
       end if
       end if
    end sub

    Sub o_Disposing
End Sub

Sub coloriage(couleur as String)
dim oEnCours as object
oEnCours = thiscomponent.currentSelection
If  oEnCours.CellStyle <> couleur then
	oEnCours.CellStyle=couleur
end if
If  oEnCours.string <> UCase(oEnCours.string) Then
	oEnCours.SetString(UCase(oEnCours.string))
EndIf
End Sub
Etant donné que ces codes sont évolutifs, j'aimerais pouvoir simplement gérer ces codes dans les listes de données de l'onglet "Codes" et de ne plus les modifier dans la macro, surtout que cela serait bien plus simple pour les autres utilisateurs qui ne touchent pas aux macros.
Cela reviendrait à faire en sorte qu'au lieu d'avoir

Code : Tout sélectionner

case "MO","BS","SBS","BHS" coloriage ("vert")
ça ferait

Code : Tout sélectionner

 case plage nommée "vert" coloriage ("vert")
Je pensais que faire

Code : Tout sélectionner

case oDocument.NamedRange("vert")
permettrait ça, mais ça ne marche pas.

Merci de votre aide
Dernière modification par Bosluc le 29 nov. 2013 16:44, modifié 4 fois.
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26122
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Vérifier des données dans une plage nommée

Message par Dude »

Bosluc a écrit :la case se colore en fonction du code mais comme il y a plus de 3 conditions, je dois passer par une macro
Non, on peut contourner la restriction des trois conditions.
Sujet moult fois abordé en section Calc :
https://forum.openoffice.org/fr/forum/v ... conditions
https://forum.openoffice.org/fr/forum/v ... conditions
https://forum.openoffice.org/fr/forum/v ... conditions
etc
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

Faut que je vois au boulot car il me semble que les postes sont encore en openoffice 3.3, donc ça ne marcherait pas.
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
Bidouille
RespOOnsable forum
RespOOnsable forum
Messages : 12768
Inscription : 08 nov. 2005 16:23
Localisation : Brest, France

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bidouille »

Vous avez ouvert une 2e question en lien avec le présent problème.
Ne pensez vous pas qu'en donner le lien permettrait à d'autres de suivre la solution ?

Suite du fil ici : https://forum.openoffice.org/fr/forum/v ... =4&t=40975

Merci d'ajouter [Résolu] au début du titre de votre 1er message sans oublier de cocher la case de l'icône de sujet (le V vert).
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

Bon, ben contrairement à ce que je croyais, il reste 2 postes en OpenOffice 3.3, et donc non compatibles avec les MFC multiples, ce qui fait que ma macro redevient d'actualité et je rouvre le sujet si ça ne dérange pas. (Désolé Mr Bidouille, mais je ne le fais pas exprès.)

J'ai essayé avec getcellByrange, getCellByName, ainsi que d'autres commandes, mais ça ne prend pas et je me retrouve tout le temps avec des erreurs basic.
Je ne sais pas si c'est mieux d'utiliser des "if" ou bien des "case" étant donné qu'il faut vérifier si le contenu de la cellule correspond à un code d'une plage nommée pour appliquer le style.
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

Je joins le fichier ainsi que le code où j'ai modifié les "case" par des "if" mais la commande "getElementNames()" n'est pas reconnue.

Code : Tout sélectionner

    Sub o_Modified(oEvent)
       dim oEnCours as object
       dim oSheet as Object
       dim oDocument as Object
       dim oRanges    'les listes de données nommées
       
       oDocument = ThisComponent
       oRanges = ThisComponent.NamedRanges
       oEnCours = thiscomponent.currentSelection
       oSheet = oDocument.getCurrentController().getActiveSheet()
       
       if oSheet.getName<>("Codes") then 'Ne travaille que si la feuille est différente de "Codes"
        if oEnCours.supportsService("com.sun.star.sheet.SheetCell") then 'Ne travaille que si la sélection en cours est une cellule
         if UCase(oEnCours.string) = oRanges.getByName("jours").getElementNames() then 'Passage en maj et vérif des données de la plage
			 coloriage("Vert")	'Voir routine ci-dessous
		  if oEnCours.CellStyle <> "Vide" then
             oEnCours.CellStyle="Vide"  'Le test "Else" sert pour les autres cas => réapplique le style Vide
          end if
         end if
         
        end if
       end if
    end sub
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26122
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Vérifier des données dans une plage nommée

Message par Dude »

Salut,
Bosluc a écrit :mais la commande "getElementNames()" n'est pas reconnue.
Si tu avais utilisé XRay, tu aurais vu que cette méthode n'existe pas sur l'objet ScNamedRangesObj auquel tu accèdes.
Que cherches-tu à obtenir ? Les références des cellules de la plage ?
Dans ce cas, c'est getContent que tu dois prendre.
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

J'ai installé Xray comme indiqué dans le tutoriel, et il ne se passe rien quant au panneau d'affichage des informations qui doit se lancer.
J'ai remplacé "getElementNames()" par "getContent, mais il ne se passe rien.
La macro ne plante plus mais quand je rentre un code correspondant à ce qui est dans la plage nommée "jours", la cellule correspondant ne se colorie pas et ne passe pas le code en majuscules.
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26122
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Vérifier des données dans une plage nommée

Message par Dude »

Bosluc a écrit :J'ai installé Xray comme indiqué dans le tutoriel, et il ne se passe rien quant au panneau d'affichage des informations qui doit se lancer.
C'est-à-dire ? Pour inspecter un objet, il faut le déclarer dans ton code :

Code : Tout sélectionner

xray tonObjet
Bosluc a écrit :J'ai remplacé "getElementNames()" par "getContent, mais il ne se passe rien.
Ouh là, tu as essayé la baguette magique, l'amulette ou la danse vaudou ?
Sans rire, as-tu au moins posé un témoin dans ton code pour voir ce que renvoyaient tes objets comme valeur ?

Code : Tout sélectionner

if UCase(oEnCours.string) = oRanges.getByName("jours").getElementNames() then
AMHA, tu ne peux pas logiquement comparer par une égalité une adresse de cellule avec une plage.
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

Dude a écrit :

Code : Tout sélectionner

if UCase(oEnCours.string) = oRanges.getByName("jours").getElementNames() then
AMHA, tu ne peux pas logiquement comparer par une égalité une adresse de cellule avec une plage.
Comment faire alors ?
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
luky-luke
InconditiOOnnel
InconditiOOnnel
Messages : 949
Inscription : 27 nov. 2010 00:17
Localisation : gâtine deux-sèvrienne

Re: [Calc] Vérifier des données dans une plage nommée

Message par luky-luke »

Bonsoir Bosluc,
Bosluc a écrit :Comment faire alors ?
Un simple descripteur de recherche sur la colonne A de la feuille Codes fait l'affaire.
Mais, je pense qu'il va y avoir comme un problème. :aie:
Ta macro se déclenche lorsque une modification de contenu à lieu dans la feuille Janvier 2014. Dans la macro qui se lance sur l’événement, tu change le contenu d'une cellule de la feuille Janvier 2014. Tu viens de lancer une boucle infini sur l’événement, attention à la fermeture brutal du fichier.

Je n'ai pas testé à la maison :lol:

Cordialement
Luke
Dernière modification par luky-luke le 26 nov. 2013 20:06, modifié 1 fois.
LibO 7.4.7.2 Raspberry pi et Libo 7.6.5.2 LinuxMint 22
Xray ne tient pas lieu de tout, mais une pratique sans Xray ne vaut pas grand chose
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

Je n'y arrive pas, qui peut m'aider s'il vous plait ?
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
luky-luke
InconditiOOnnel
InconditiOOnnel
Messages : 949
Inscription : 27 nov. 2010 00:17
Localisation : gâtine deux-sèvrienne

Re: [Calc] Vérifier des données dans une plage nommée

Message par luky-luke »

Bonsoir,

J'ai écris une bêtise dans mon message précédent. L'appel du listener au pire se fait trois fois et s'arrête. Une fois lors de la validation, une deuxième par le changement de couleur et une troisième pour le passage en majuscule du texte.

Et le fichier avec le descripteur de recherche. A tester :aie:
 Ajout : Pour vraiment répondre à la question, pour une plage de cellules qui porte le nom jours

Code : Tout sélectionner

Mazone = ThisComponent.sheets.getByName("Codes").getCellRangeByName("jours")
cherche = Mazone.CreateSearchDescriptor
 
Cordialement
Luke
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibO 7.4.7.2 Raspberry pi et Libo 7.6.5.2 LinuxMint 22
Xray ne tient pas lieu de tout, mais une pratique sans Xray ne vaut pas grand chose
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

lucky-luke, merci pour ce début.

J'ai passé l'après-midi à tester dans tous les sens et adapter la macro pour plusieurs zones nommées. Peut-être que j'aurais du commencer par là, mais je voulais être progressif.
Donc, la première chose est que dans ta version, la case se colorie dès qu'une lettre correspond à un code. Par exemple si je tape "m", alors ça passe en vert comme si c'était un code reconnu alors que ça devrait l'ignorer.
J'ai malgré tout essayé d'ajouter un cas avec une deuxième plage nommée "indispos" et dans ce cas si le code rentré correspond, alors la cellule passe en jaune en reprenant le même principe, mais là encore, je bloque.
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
Dude
IdOOle de la suite
IdOOle de la suite
Messages : 26122
Inscription : 03 mars 2006 07:45
Localisation : 127.0.0.1

Re: [Calc] Vérifier des données dans une plage nommée

Message par Dude »

Bosluc a écrit :la case se colorie dès qu'une lettre correspond à un code. Par exemple si je tape "m", alors ça passe en vert
Dans ce cas, arrête le listener qui se déclenche à chaque modification.
Utilise plutôt l'évènement de feuille "Contenu modifié".
Avatar de l’utilisateur
luky-luke
InconditiOOnnel
InconditiOOnnel
Messages : 949
Inscription : 27 nov. 2010 00:17
Localisation : gâtine deux-sèvrienne

Re: [Calc] Vérifier des données dans une plage nommée

Message par luky-luke »

Bonsoir,
Dude a écrit :Si tu avais utilisé XRay, tu aurais vu que cette méthode n'existe pas sur l'objet ScNamedRangesObj auquel tu accèdes.
Arrête de faire de la programmation au hasard. Tu t'épuises et moi aussi je m'épuise :lol:
Bosluc a écrit : Par exemple si je tape "m", alors ça passe en vert comme si c'était un code reconnu alors que ça devrait l'ignorer.

Code : Tout sélectionner

.SearchWords = True
Pour ne rechercher que des mots.

Qu'est que tu cherches ? La chaîne de caractère qui vient d'être saisie dans une cellule. Le descripteur de recherche fait son travail. Ensuite il faut utiliser ce qu'il vient de trouver.

Code : Tout sélectionner

Trouve.formulalocal
Renvoi la chaîne de caractère que tu cherche, il ne te reste plus qu'à différencier les cas et colorier l'arrière plan de la cellule modifiée.
Les plages nommées ne sont plus utilisée. Il faut créer une autre plage.

Code : Tout sélectionner

Sub o_Modified(oEvent)
dim oEnCours as object
dim oSheet as Object
dim oDocument as Object
dim oRanges    'les listes de données nommées
dim Mazone as Object, Cherche As Object, Trouve As Object, Cell As Object
dim Resultat As String
	oDocument = ThisComponent
	oRanges = ThisComponent.NamedRanges
	oEnCours = thiscomponent.currentSelection
	oSheet = oDocument.getCurrentController().getActiveSheet()
	Mazone = ThisComponent.sheets.getByName("Codes").getCellRangeByName("A1:B15")      
	If oSheet.getName <> ("Codes") Then 'Ne travaille que si la feuille est différente de "Codes"
		If oEnCours.supportsService("com.sun.star.sheet.SheetCell") Then 'Ne travaille que si la sélection en cours est une cellule
        	cherche = Mazone.CreateSearchDescriptor
        	With Cherche
        		.SearchString = oEnCours.string
        		.SearchWords = True
        	End with
        	Trouve = Mazone.FindFirst(Cherche)
        		If Not isnull(Trouve) Then
        		Resultat = Trouve.FormulaLocal
					select Case Resultat
        				case "MO"
							coloriage("Vert")	'Voir routine ci-dessous
						Case "BS"
							Coloriage("Vert")
						Case "SBS"
							Coloriage("Vert")
						Case "STG"
							Coloriage("Jaune")
						Case "CNV"
							Coloriage("Jaune")
						Case RLS
							Coloriage("Jaune")
					End select
				Else
					If oEnCours.CellStyle <> "Vide" Then
             			oEnCours.CellStyle="Vide"  'Le test "Else" sert pour les autres cas => réapplique le style Vide
          			End if
         		End if
        End if
	End if
End sub
Autre méthode, qui a le mérite de limiter le nombres cas à traiter.

Code : Tout sélectionner

Trouve.RangeAddress.EndColumn
Renvoi la colonne dans laquelle la chaîne de caractère à été trouvée.

Code : Tout sélectionner

Option Explicit

Sub o_Modified
dim oEnCours as object
dim oSheet as Object
dim oDocument as Object
dim Mazone as Object, Cherche As Object, Trouve As Object, Cell As Object
dim Resultat As String
	oDocument = ThisComponent
	oEnCours = oDocument.currentSelection
	oSheet = oDocument.getCurrentController().getActiveSheet()
	Mazone = oDocument.sheets.getByName("Codes").getCellRangeByName("A1:B15")	    
	If oSheet.getName <> ("Codes") Then 'Ne travaille que si la feuille est différente de "Codes"	
		If oEnCours.supportsService("com.sun.star.sheet.SheetCell") Then 'Ne travaille que si la sélection en cours est une cellule		
        	cherche = Mazone.CreateSearchDescriptor
        	With Cherche
        		.SearchString = oEnCours.string
        		.SearchWords = True
        	End with
        	Trouve = Mazone.FindFirst(Cherche)
        		If Not isnull(Trouve) Then
        			Resultat = Trouve.RangeAddress.EndColumn
					select Case Resultat
        				case "0"
        					oEnCours.CellStyle = "Vert"
							oEnCours.SetString(UCase(oEnCours.string))
						Case "1"
							oEnCours.CellStyle = "Jaune"
							oEnCours.SetString(UCase(oEnCours.string))
					End select
				Else
             		oEnCours.CellStyle="Vide"  'Le test "Else" sert pour les autres cas => réapplique le style Vide
         		End if
        End if
	End if
End sub
J'ai supprimé le listener et affecté la macro à l’événement feuille, contenu modifié
Cordialement
Luke
Vous ne pouvez pas consulter les pièces jointes insérées à ce message.
LibO 7.4.7.2 Raspberry pi et Libo 7.6.5.2 LinuxMint 22
Xray ne tient pas lieu de tout, mais une pratique sans Xray ne vaut pas grand chose
Bosluc
Membre hOOnoraire
Membre hOOnoraire
Messages : 181
Inscription : 25 févr. 2009 09:21

Re: [Calc] Vérifier des données dans une plage nommée

Message par Bosluc »

Bonsoir Lucky-luke,

La 2ème méthode est la meilleure solution, car en définissant une plage assez large, cela permet de changer, ajouter ou modifier les codes à volonté par les autres utilisateurs sans avoir à aller dans une macro.
J'ai enfin pu adapter et multiplier avec d'autres colonnes sans difficultés cette fois.
Par contre, je sors un peu du fil de la question, mais quand je copie la feuille pour créer les autres mois, l'évènement feuille, contenu modifié ne reste pas associé à la nouvelle feuille créée et ça, c'est trop compliqué à faire manipuler à mes collègues. En gros, quand j'aurais finalisé mon tableau, je n'aurais pas le droit au bug :aie:
Quelle est la meilleure solution dans ce cas pour qu'ils n'aient pas à se prendre la tête et ensuite m’appeler (genre, ça a planté, ton tableau c'est de la m**** :fou: ) alors que tu m'a déjà fait un truc génial !
LibreOffice 5.0.1 sur Windows 10 x64 Edition familiale à la maison.
LibreOffice 4.4.5 sur Windows 7 Entreprise.
Avatar de l’utilisateur
luky-luke
InconditiOOnnel
InconditiOOnnel
Messages : 949
Inscription : 27 nov. 2010 00:17
Localisation : gâtine deux-sèvrienne

Re: [Calc] Vérifier des données dans une plage nommée

Message par luky-luke »

Bonsoir Bosluc,
Bosluc a écrit :je sors un peu du fil de la question
Tu connais les règles du forum. Je t'invite donc à ouvrir un autre fil, et cocher celui-ci comme [Résolu].

A bientôt...

Cordialement
Luke
LibO 7.4.7.2 Raspberry pi et Libo 7.6.5.2 LinuxMint 22
Xray ne tient pas lieu de tout, mais une pratique sans Xray ne vaut pas grand chose