Comment intercepter le contenu d'une cellule modifiée dans 4D ViewPro

4D view pro v17 R4
Je change le contenu d’une cellule et j’aimerais que 4D soit avisé du changement de contenu afin, p.e. de stocker cette valeur particulière dans un champ.

Avec l’ancienne version on avait la possibilité d’appeler une méthode par PV APPELER SUR EVENEMENT. Ça n’existe pas avec la nouvelle version et l’événement Sur données modifiées ne fonctionne pas non plus. De fait, changer le contenu d’une cellule n’appelle aucun événement.

Quelqu’un a une idée comment faire?

J’ai creusé un peu et j’ai trouvé une façon de faire, pas très élégante mais qui fonctionne.

  1. A la fin de la construction de ma zone par programmation je copie dans une variable process objet le contenu de ma variable objet devant être convertie en View Pro:

maVarObjetCopie:=ob Copier(maVarObjetOriginale)

  1. Sur événement formulaire Sur Libération, je compare le contenu de l’objet original avec le contenu de l’objet courant. P.e. j’écris
    Si (json stringify (maVarObjetCopie)#json stringify(maVarObjetOriginale)
    Exécuter du code
    Fin de si

Le désavantage de cette méthode est qu’il faut attendre la sortie du formulaire avant de savoir ce qui a été modifié, au lieu de l’être immédiatement avec une méthode d’appel sur événement.

Bonjour,

le binding d’événements n’est pas encore implémenté avec des commandes 4D.
mais il est possible de le faire à la mano pour le moment (de mémoire) :

Danla méthode de la zone :

<code 4D>
If (Form event=On VP Ready)

$Txt_js:="var spread = GC.Spread.Sheets.findControl(document.getElementById('spreadSheet'));"\
+"spread.bind(GC.Spread.Sheets.Events.CellChanged, function (sender, args) {\r"\
+"    $4d.vp_GEST_EVENTS(sender,args,function(result){});\r"\
+"});"

$Boo_OK:=WA Evaluate JavaScript(*;"NomDeLaZone";$Txt_js;Is boolean)

End if

</code 4D>

avec la méthode vp_GEST_EVENTS :

<code 4D>
$Obj_sender:=$1
$Obj_args:=$2

If (OB Is defined($Obj_sender))
Case of
: ($Obj_sender.type=“CellChanged”)

		  //le code ici
		
End case 

End if
</code 4D>

voici à ma connaissance les événements que l’on peut gérer :

[
“ActiveSheetChanged”,
“ActiveSheetChanging”,
“ButtonClicked”,
“CellChanged”,
“CellClick”,
“CellDoubleClick”,
“ClipboardChanged”,
“ClipboardChanging”,
“ClipboardPasted”,
“ClipboardPasting”,
“ColumnChanged”,
“ColumnWidthChanged”,
“ColumnWidthChanging”,
“CommentChanged”,
“CommentRemoved”,
“CommentRemoving”,
“DragDropBlock”,
“DragDropBlockCompleted”,
“DragFillBlock”,
“DragFillBlockCompleted”,
“EditChange”,
“EditEnded”,
“EditEnding”,
“EditorStatusChanged”,
“EditStarting”,
“EnterCell”,
“FloatingObjectChanged”,
“FloatingObjectLoaded”,
“FloatingObjectRemoved”,
“FloatingObjectRemoving”,
“FloatingObjectSelectionChanged”,
“InvalidOperation”,
“LeaveCell”,
“LeftColumnChanged”,
“PictureChanged”,
“PictureSelectionChanged”,
“RangeChanged”,
“RangeFiltered”,
“RangeFiltering”,
“RangeGroupStateChanged”,
“RangeGroupStateChanging”,
“RangeSorted”,
“RangeSorting”,
“RowChanged”,
“RowHeightChanged”,
“RowHeightChanging”,
“SelectionChanged”,
“SelectionChanging”,
“SheetNameChanged”,
“SheetNameChanging”,
“SheetTabClick”,
“SheetTabDoubleClick”,
“SlicerChanged”,
“SparklineChanged”,
“TableFiltered”,
“TableFiltering”,
“TopRowChanged”,
“TouchToolStripOpening”,
“UserFormulaEntered”,
“UserZooming”,
“ValidationError”,
“ValueChanged”
]

Vincent, pour le nul en Javascript, je veux juste te dire que $Boo_OK = faux. Il y a probablement des paramètres à adapter dans $Txt_js que je ne comprends pas.

:oops:
Ils ont du changer quelque chose.
Je regarde lundi

Bon, il y a bien eût une modification.
Un petit exemple https://forums.4d.com/4DBB_Main/x_User/3930/files/29108907.zipici>

C’est un moyen de le faire en attendant les commandes qui sont en cours de développement…

…et ça marche superbement. Merci encore Vincent!

en fait j’ai crié victoire trop tôt. Dans ma zone VP, contrairement à toi, j’ai déjà des données:

<code 4D>
C_TEXTE($Txt_js)
C_BOOLÉEN($Boo_OK)

	$Txt_js:="var spread = GC.Spread.Sheets.findControl(document.getElementById('ss'));"\
	+"var sheet = spread.getActiveSheet();"\
	+"sheet.bind(GC.Spread.Sheets.Events.CellChanged,"\
	+"function (sender, args) {$4d.PV_Gest_Events(sender,args,function(result){});});"
	
	$Boo_OK:=WA Évaluer JavaScript(*;OBJET Lire nom(Objet courant);$Txt_js;Est un booléen)  // Always False, don't worry ;-)
	
	Si (OB Est défini(vObjetDocument))
		VP IMPORT FROM OBJECT (OBJET Lire nom(Objet courant);vObjetDocument)  //pour montrer les résultats
	Fin de si 

</code 4D>

Le fait d’avoir utilisé VP IMPORT FROM OBJECT fait en sorte que ça ne fonctionne pas, même si je déplace ce code avant la méthode d’interception. Quand je dis “fonctionne pas” je veux dire que la méthode PV_Gest_Events (attention j’ai changé le nom par rapport à ton code originel) n’est jamais exécutée.

Dans ce cas de figure, je ferais :

<code 4D>
$area:=OBJECT Get name(Object current)

If(OB Is defined(vObjetDocument))

VP IMPORT FROM OBJECT($area;vObjetDocument)//Pour montrer les résultats

End if

CALL FORM(current form window;“INSTALL_EVENTS”;$area)
</code 4D>

avec la méthode INSTALL_EVENTS :
<code 4D>
C_TEXT($1)
C_BOOLEAN($Boo_OK)
C_TEXT($Txt_js)

$Txt_js:=“var spread = GC.Spread.Sheets.findControl(document.getElementById(‘ss’));”
+“var sheet = spread.getActiveSheet();”
+“sheet.bind(GC.Spread.Sheets.Events.CellChanged,”
+“function (sender, args) {$4d.PV_Gest_Events(sender,args,function(result){});});”

$Boo_OK:=WA Evaluate JavaScript(*;$1;$Txt_js;Is boolean)//Always False, don’t worry;-)
</code 4D>

Chic, ça marche! Merci d’avoir pris le temps Vincent.

Vincent, une dernière question (j’espère): si je voulais ajouter l’événement CellClick en plus de CellChanged, ton code javascript serait quoi?

<code 4D>
$Txt_js:=“var spread = GC.Spread.Sheets.findControl(document.getElementById(‘ss’));”
+“var sheet = spread.getActiveSheet();”
+“sheet.bind(GC.Spread.Sheets.Events.CellChanged,”
+“function (sender, args) {$4d.PV_Gest_Events(sender,args,function(result){});});”
+“sheet.bind(GC.Spread.Sheets.Events.CellClick,”
+“function (sender, args) {$4d.PV_Gest_Events(sender,args,function(result){});});”
</code 4D>

Merci Vincent. “For the record”, il manque un \ à la fin de la ligne 4 et une virgule juste après CellClick à la ligne 5. Ça fonctionne de cette façon.

Des dangers du copier-coller directement dans le forum :oops:

one cool feature in the current method editor is that if you type

“”

in the editor,
and put the cursor inside the quotes,
and paste a piece of code (JS, for example),
the necessary anti-slashes are automatically inserted.

one think to pay attention,

https://www.grapecity.com/en/forums/spread-sheets/spreadjs---no-events-fire-

CellChanged is not fired when a cell is cleared with delete key.

Thanks for bringing that up Keisuke. Looks like a serious drawback to me. Any possible workaround?

According to https://help.grapecity.com/spread/SpreadSheets12/webframe.html#SpreadJS~GC.Spread.Sheets.Events.htmldocumentation>, you can try with ‘EditChange’ or ‘EditEnded’ or ‘EditEnding’ depending of your needs

I might be wrong, but it looks like EditChange, etc. events will not fire

because the cell does not switch to edit mode when you select a cell and press the delete key.

that is why the StackOverflow post suggests trapping key events.