Macros

From The Document Foundation Wiki
< Macros‎ | Calc
Jump to: navigation, search

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 :