Thomas W Posted February 1, 2023 Share Posted February 1, 2023 Hi everyone, I was looking for a way to update the symbols of one (or more) file with respect to another file which contains the updated symbols of the same name. After getting stuck on ImportResToCurFileN I came up with something that seems to work and should work for other objects besides symbols as well. Principle of operation: - create 1 list of the desired object type in each file. - compare the 2 lists and when 2 symbol names are identical propose to replace, rename or do nothing. Below is the script that works in my case: Bonjour à tous, Je cherchais le moyen de mettre à jour les symboles d'un (ou plusieurs) fichier par rapport à un autre fichier qui contient les symboles à jours du même nom. Après avoir bloqué sur ImportResToCurFileN je suis arrivé à quelque chose qui semble fonctionner et qui devrait aussi fonctionner pour d'autres objets que les symboles. Principe du fonctionnement : - créer 1 liste du type d'objet souhaité dans chaque fichier. - comparer les 2 listes et lorsque 2 noms de symboles sont identiques proposer de remplacer, renommer ou ne rien faire. Ci-dessous le script qui fonctionne dans mon cas : PROCEDURE Compar2DifferentLists; {$DEBUG} CONST ObjectType=16; { Symbol Definition } CR=Chr(13); fullPath='Chemin du fichier.vwx qui contient les symboles à jour'; VAR I1, I2, NumItems1, NumItems2, CheckedSymbols: INTEGER; rowStart, rowEnd, columnStart, columnEnd: INTEGER; ListID1, ListID2: LONGINT; S1, S2: STRING; SymNameLocal, SymNameMaster: DYNARRAY OF STRING; h1, h2: HANDLE; FUNCTION Execute(h1: HANDLE): BOOLEAN; BEGIN IF (h1<>NIL) & (CheckedSymbols<=NumItems1) THEN BEGIN S1:= SymNameLocal[CheckedSymbols]; FOR I2:=1 TO NumItems2 DO IF S1= GetNameFromResourceList(ListID2, I2) THEN BEGIN S2:= GetNameFromResourceList(ListID2, I2); AlrtDialog(Concat('SymNameLocal', '[', CheckedSymbols, ']', ': ', S1, CR, 'SymNameMaster qui a le même nom est celui avec l''Index', '[', I2, ']', ' de la ListID2: ', ListID2, CR, 'Soit SymNameMaster', '[', I2,']', ': ', (S2))); h2:= ImportResourceToCurrentFile(ListID2, I2); END; CheckedSymbols:= CheckedSymbols+1; END; END; BEGIN ListID1:= BuildResourceList(ObjectType, 0, '', NumItems1); ListID2:= BuildResourceListN(ObjectType, fullPath, NumItems2); ALLOCATE SymNameLocal[1..NumItems1]; CheckedSymbols:=1; FOR I1:=1 TO NumItems1 DO SymNameLocal[I1]:= GetActualNameFromResourceList(ListID1, I1); SortArray(SymNameLocal, 1, NumItems1); GetArrayDimensions(SymNameLocal, rowStart, rowEnd, columnStart, columnEnd); AlrtDialog(Concat('SymNameLocal n°1: ', SymNameLocal[1], CR, 'Dernier SymNameLocal n°', NumItems1, ': ', SymNameLocal[NumItems1])); ALLOCATE SymNameMaster[1..NumItems2]; FOR I2:=1 TO NumItems2 DO SymNameMaster[I2]:= GetActualNameFromResourceList(ListID2, I2); SortArray(SymNameMaster, 1, NumItems2); GetArrayDimensions(SymNameMaster, rowStart, rowEnd, columnStart, columnEnd); AlrtDialog(Concat('SymNameMaster n°1: ', SymNameMaster[1], CR, 'Dernier SymNameMaster n°', NumItems2, ': ', SymNameMaster[NumItems2])); ForEachObjectInList(Execute, 0, 2, FSymDef); END; Run(Compar2DifferentLists); Your remarks will be welcome and I had trouble with the beginning of the Function Execute script because I was trying to make it work with WHILE rather than with IF, could we replace "IF (h1 < >NIL) & (CheckedSymbols<=NumItems1) THEN BEGIN" with a WHILE? Thank you for the previous exchanges which allowed me to move forward. Below 2 screenshots of the result : and after the script Have a good day, Thomas Vos remarques seront bien venus et j'avais du mal avec le début du script de la Function Execute parce que je cherchais à le faire fonctionner avec WHILE plutôt que avec IF, est ce que dans ce ca là on pourrait remplacer "IF (h1<>NIL) & (CheckedSymbols<=NumItems1) THEN BEGIN" par une boucle WHILE? Merci pour les échanges précédents qui m'ont permis d'avancer. Bonne journée, Thomas Quote Link to comment
Pat Stanford Posted February 1, 2023 Share Posted February 1, 2023 Execute will be called once for each symbol definition in the file. I don't see why you would want to use a WHILE instead of an IF. Actually I don't think you even need the IF. If you trust the ForEachItemInList procedure, then you know that it will not pass a NIL handle. And if you trust the BuildResourceList function then you know that it is returning all of the symbol definitions in the file. So there should be no way for Execute to get called more times than the number of items returned in I1. But extra error checking has a low cost, even when called on every symbol in the file. Quote Link to comment
Thomas W Posted February 2, 2023 Author Share Posted February 2, 2023 Hello Pat and thank you for your answer, ForEachObjectInList shouldn't return a NIL handle, that's ok. For the IF I'm not sure I can do without it in this case, in any case I wouldn't know how. If I don't put an IF CheckedSymbols<=NumItems1 condition I get an Error on line=20: EXECUTE CHECKEDSYMBOLS - Index outside array limits because of CheckedSymbols:= CheckedSymbols+1. Thanks and have a good day, Bonjour Pat et merci pour ta réponse, ForEachObjectInList ne devrait pas renvoyer de handle NIL, ça c'est ok. Pour le IF je ne suis pas sûr de pouvoir m'en passer dans ce cas, en tous cas je ne saurais pas comment. Si je ne mets pas de condition IF CheckedSymbols<=NumItems1 j'ai une Error on line=20: EXECUTE CHECKEDSYMBOLS - Index outside array limits à cause de CheckedSymbols:= CheckedSymbols+1. Bonne journée, Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.