Macros

    From The Document Foundation Wiki
    < Macros‎ | Calc


    Comment définir la cellule liée à un contrôle de formulaire ?

    Contexte

    On a dessiné des contrôles (zones de texte, champs formatés, zones de liste, compteurs, case à cocher, etc.) ancrés à des cellules. L'objet de la procédure présentée ici est de définir automatiquement la cellule à laquelle est ancré le contrôle comme étant la cellule liée.

    • Pour faciliter le traitement la procédure travaille sur la sélection courante[1].
    • Le formulaire doit donc être en mode "ébauche" (mode dans lequel on peut sélectionner les contrôles).


    Il est intéressant de pouvoir "piloter" par programme cette propriété car, lors de copie (de feuille ou de contrôle) ces références ne sont pas adaptées et les contrôles copiés continuent de "pointer" vers la cellule liée du contrôle source de la copie.

    Réalisation

    La cellule liée se définit via le service CellValueBinding[2], instancié au niveau document.


    Le service est initialisé avec une structure de type com.sun.star.beans.NamedValue pour lequel :

    • La propriété .Name aura la valeur BoundCell.
    • La valeur sera l'objet adresse de la cellule à lier (doit être un objet de typeCellAddress).


    La procédure travaillant sur la sélection courante il est nécessaire (prudent) de tester cette dernière pour vérifier le type des objets sélectionnés.

    On teste l'ancrage du contrôle (qui doit être uniquement cellule) via le service com.sun.star.sheet.SheetCell.

    On teste que le contrôle est de ceux qui peuvent être "liés" (les boutons, par exemple, n'offrent pas cette possibilité) via les services BindableControlModel et BindableIntegerValueRange.

    sub LierCelluleAncre
    dim LibOClasseur as object
    dim LibOCVB as object
    dim LibOSel as variant
    dim LibONb as integer
    dim LibONamedValue as new com.sun.star.beans.NamedValue 
    
    LibOClasseur = thiscomponent
    LibOSel = LibOClasseur.currentselection
    LibONamedValue.Name  = "BoundCell" 
    
    if LibOSel.supportsService("com.sun.star.drawing.ShapeCollection") then
    	for LibONb = 0 to LibOSel.count - 1
    		with LibOSel(LibONb)
    			if .supportsService("com.sun.star.drawing.ControlShape") then
    				if .anchor.supportsService("com.sun.star.sheet.SheetCell") then
    					if .control.supportsService("com.sun.star.form.binding.BindableControlModel") or _
    						.control.supportsService("com.sun.star.form.binding.BindableIntegerValueRange") then
    						LibOCVB = LibOClasseur.createInstance("com.sun.star.table.CellValueBinding") 
    						LibONamedValue.Value = .anchor.cellAddress
    						LibOCVB.Initialize(Array(LibONamedValue)) 
    						.control.setValueBinding(LibOCVB)
    					end if
    				end if
    			end if
    		end with
    	next LibONb
    	LibOClasseur.setModified(true)
    	msgbox "Terminé"
    else
    	msgbox "La macro ne fonctionne que pour des contrôles"
    end if
    
    end sub


    Notes :