macoovacany Posted May 21, 2009 Share Posted May 21, 2009 Before I go ahead and put the following features on the VS wish list, I'd like to check that they are definitely not possible in VS: 1) Functions as first class objects. So I can have and array of functions can call the specific function I need by looking up into an array. At the moment I use a function with a case statement to act the same. (Ugly, but it works.) 2) Expression matching or regular expression matching in criteria. e.g. length(C=Wall[\wa-zA-z0-9]*))l count(L='Battens'& C='TH4055'& hLength<600); 3) Passing criteria in and out of procedures or functions, to generate them at run time. 4) Calling a plug-in command from another plug-in. NOT $include, and not DoMenuTextByName. I'd be grateful for any comments, particularly of the "VS already does this" variety. Timbo Apologies for any syntax errors. Quote Link to comment
Dieter @ DWorks Posted May 21, 2009 Share Posted May 21, 2009 Number 3 should be possible. Criterea are just text. So when you use own functions to pass through criterea, use for example 'C=Wall' as a parameter to your own function and in that function give it to a criterea function. I do this all the time and it works. Quote Link to comment
JBenghiat Posted May 21, 2009 Share Posted May 21, 2009 #4) Can you give an example of what you are trying to do? DoMenuTextByName often works well -- it's far less kludgey than you may think. As a general note, VS is based heavily on Pascal and is also not a high development priority. You may find that you have to wait a bit, even if your requests eventually get implemented. You may want to also post some specific "How do I..." questions. I noticed that a lot of your requests involve criteria. Personally, I've found that I used a lot of criteria-based functions when I started scripting, but as my code became more sophisticated I used them less and less. You may find that there are other ways of doing what you want that avoid criterium. -Josh Quote Link to comment
Miguel Barrera Posted May 21, 2009 Share Posted May 21, 2009 #1 - As was stated before, VS is based on the pascal language and do not believe you can have functions as Array parameters. #2 & 3 If you want to have more specific criteria, it is doable with ForEachObject as in the following: PROCEDURE Test; VAR gTotObj1,gTotObj2: INTEGER; FUNCTION CountObjs(layName,className: STRING; maxLng: REAL): INTEGER; VAR totObj: INTEGER; PROCEDURE ProcessObj(objHdl: HANDLE); VAR objLng: REAL; BEGIN objLng:= HLength(objHdl); IF objLng < maxLng THEN totObj:= totObj + 1; END; BEGIN totObj:= 0; ForEachObject(ProcessObj,((L=layName) & (C=className))); CountObjs:= totObj; END; BEGIN gTotObj1:= CountObjs('Battens','TH4050',400); gTotObj2:= CountObjs('Battens','TH4055',600); END; Run(Test); #4 - You need to explain this one because I do not understand what you are expecting. DoMenuTextByName works for menu commands and ResetObject works for plugin objects. Quote Link to comment
macoovacany Posted May 22, 2009 Author Share Posted May 22, 2009 RE criteria: All the times I've had to use the criteria it has been of the form (C=?Edged?) ;{Note the C= isn't a part of the string } I didn't think that 'C=Wall' would work. I'll try it shortly. Re foreach: Yeah that's a pattern I use a lot. Either the ForEachObject or ForEachObjectInLayer function. Re running plugins It would be good to have a 'main' plugin which can then customize when to run other plugins. Including a lot source text seems... ugly. It would cut down on the number of menu items that would clutter the menu system, especially if the sub plugin would only be run as part of a batch. Does the DoMenuTextByName function have to ahve the plugin as part of the menu user visible menu Re ResetObject ??? The API reference seems a bit vague as to how this would work with regard to #4. Miguel: My code for this case is almost exactly the same, except I'm using foreachobjectinlayer. Cheers for your replies. Timbo Quote Link to comment
Dieter @ DWorks Posted May 22, 2009 Share Posted May 22, 2009 (edited) RE criteria: All the times I've had to use the criteria it has been of the form (C=?Edged?) ;{Note the C= isn't a part of the string } I didn't think that 'C=Wall' would work. I'll try it shortly. It does works, I do this. Criterea are just strings. Edited May 22, 2009 by DWorks Quote Link to comment
Pat Stanford Posted May 22, 2009 Share Posted May 22, 2009 RE criteria: All the times I've had to use the criteria it has been of the form (C=?Edged?) ;{Note the C= isn't a part of the string } I didn't think that 'C=Wall' would work. I'll try it shortly. You may know this already, but this is important if you are using criteria in scripts so I am including it here. You can't use a form like Var Variable:String; ... Variable:='None'; CriteriaArea((C=Variable)); but you can use Variable='C=None'; CriteriaArea((Variable)); You can even use the Concat command to build complicated criteria strings. Quote Link to comment
JBenghiat Posted May 22, 2009 Share Posted May 22, 2009 Re running plug-ins Just to clarify, by "plug-in" do you mean plug-in menus, or do you mean objects and tools as well. VS can run sub-procedures, which seems to be what you need. If the procedure is used be more than one plug-in menu, put it in an include so it can be shared. What do you mean by "Including a lot of source text seems... ugly"? -Josh Quote Link to comment
Miguel Barrera Posted May 22, 2009 Share Posted May 22, 2009 You can't use a form like Var Variable:String; ... Variable:='None'; CriteriaArea((C=Variable)); Pat, I do this all the time. The C for class is not a string. I have not used this in a while but the following also worked for records: recName,fieldName: STRING; (recName.fieldname < 100') Quote Link to comment
Pat Stanford Posted May 22, 2009 Share Posted May 22, 2009 Not what I am seeing here. Create a drawing with a known number of objects in the None class and run this script: Procedure Test; Var S1,S2:String; Begin S1:='None'; S2:='C=None'; Message(Count(C=S1),' ** ',Count(S2)); End; Run(Test); On VW2009 SP2 Mac, I get zero listed for the S1 case and the correct number listed for the S2 case. What are you doing differently? Quote Link to comment
Miguel Barrera Posted May 23, 2009 Share Posted May 23, 2009 The following is straight from the VS Language Guide Search Criteria Format Syntax Search criteria in VectorScript are composed of two parts: the search attribute type specifier and the search value. The search attribute specifier indicates which attribute will be used to filter objects in the document; the search value specifies the value to be found and matched by the search operation. For example, the search criteria term: (C=?Edged?) indicates that a search should be performed for any objects whose class is Edged. In the criteria term, the C attribute type indicates that the search should be performed on the class attribute of objects in the document. The search value Edged indicates what class will be a match in the search operation. Unless this was changed in VW 2009, it has worked for me since the addition of records until 2008 which is what I currently have. Could this be a bug in 2009? If so, it would be another reason not to upgrade because all the programs I have developed use this format. Quote Link to comment
Pat Stanford Posted May 23, 2009 Share Posted May 23, 2009 I have never been able to use a search string of SomeCriteria=Variable Julian gave me the secret of putting the criteria and equals inside the string back in 2005, so I know it has not worked for me for at least that long. Did you try the script I sent in 2008? Quote Link to comment
_c_ Posted May 23, 2009 Share Posted May 23, 2009 This works this way since VW11 at least. Don't worry Miguel, it is still as you always had it. You never could put the variable straight off mixing it with the dedicated criteria calls: the variable S1b works in "Count". Procedure Test; Var S1, S1b, S2:String; Begin S1:= 'None'; S1b := Concat('C=', S1); S2:='C=None'; Message(Count(C=S1),' ** ', Count(S1b),' ** ',Count(S2)); End; Run(Test); Quote Link to comment
_c_ Posted May 23, 2009 Share Posted May 23, 2009 #4) I've found that I used a lot of criteria-based functions when I started scripting, but as my code became more sophisticated I used them less and less Josh, this is weird. The more I script (since 1992) the more I find criteria sophisticated. I turned lots of my library of subroutines into criteria parsing calls, because their flexibility is amazing. And often they avoid loops. orso Quote Link to comment
Miguel Barrera Posted May 23, 2009 Share Posted May 23, 2009 Pat, I ran your script and as you said, the first count returned 0. However, I changed the variable names to cls1 and cls2 and the code executed correctly. Procedure Test; Var cls1,cls2:String; Begin cls1:='None'; cls2:='C=None'; Message(Count(C=cls1),' ** ',Count(cls2)); End; Run(Test); It seems that the variable name has to be 4 characters or longer for the code to work. Quote Link to comment
_c_ Posted May 23, 2009 Share Posted May 23, 2009 Right! How weird. c2:=Concat('C=None'); { works even with short var name } c1:= concat('Dimension'); But testing further I find that hard-coding a name is not reliable. For example: Concat('C=None') Try this with some objects classed either "None" or "Dimension". The result for c2 and c4 is simply weird. While the result for c1 and c3 is correct. Procedure Test; Var c1, c2, c3, c4 :String; Begin c1:= Concat('None'); c2:= Concat('C=None'); c3:= Concat('Dimension'); c4:= Concat('C=Dimension'); Message(Count(C=c1),' ** ', Count(c2), '**', Count(C=c3),' ** ', Count(c4)); End; Run(Test); But remains the fact that this below will always work without failure or weird behavior, and probably this how we need to work, since most of the time the name only will be in a variable and one builds the criteria string accordingly: sn := 'None'; s := Concat('C=', chr(39), sn, Chr(39)); Quote Link to comment
Pat Stanford Posted May 23, 2009 Share Posted May 23, 2009 Miguel, Orso, Interesting that the rules of VS are still obtuse enough that even those of us who who have been doing this a long time still don't understand them. Interesting that we were all right for the examples we provided. So, do you think the short variable name not working is a bug we should submit? I am also fond of the CHR(39) method of assembling strings for this type of strings. Quote Link to comment
Miguel Barrera Posted May 23, 2009 Share Posted May 23, 2009 Yes, I believe it is a bug since it is not giving us the result expected if we follow the language guide. Using a single string for the criteria should also be documented in the guide. Although I have not needed this functionality, it is nice to know that you can build the criteria as a single string also. Quote Link to comment
_c_ Posted May 23, 2009 Share Posted May 23, 2009 Miguel, Orso, So, do you think the short variable name not working is a bug we should submit? Miguel perhaps should submit (he's the clever discoverer!), but I don't think that after all these years that will be fixed on the spot. If Miguel doesn't have time/wish to submit, I can do it remarking that he found the issue. Whereby I don't know if it is really a bug. Perhaps the bug is that 1- documentation should be more clear 2- an error/warning should be raised upon syntactically invalid criteria also in this case (like when you miss a braket or so). orso Quote Link to comment
_c_ Posted May 23, 2009 Share Posted May 23, 2009 I am also fond of the CHR(39) method of assembling strings for this type of strings. (you both Pat and Miguel perfectly know why) New users: always wrap names to be inserted in criteria in "Apostrophe". Exactly as you would do in worksheets criteria. If your variable contains a name with spaces, the criteria will be simply invalid. In doubt, always wrap. The name "none" wouldn't need it but the name "none 2" would. Quote Link to comment
macoovacany Posted May 25, 2009 Author Share Posted May 25, 2009 > Just to clarify, by "plug-in" do you mean plug-in menus, or do you mean objects and tools as well. Most of my plugins are commands similar to: "count the length of classes that have "some-text" in their name, and print the result to layer X using class Y. or "find the text in layer X and parse it to get some numbers. Count the numbers and print to layer Y" or "find the lines in layer X that don't meet spacing requirements and outline them". etc At the moment there are about a dozen of these plugins, and including all their source code into one command plugin seems ugly. All the commands don't require any inputs, so it's just "GO!" for each. I'd like to have a command like RunPlugin('Plugin1'); RunPlugin('Plugin2'); RunPlugin('Plugin3'); RunPlugin('Plugin4'); RunPlugin('Plugin5'); Timbo Quote Link to comment
JBenghiat Posted May 25, 2009 Share Posted May 25, 2009 Timbo, I think what you're looking for is using includes to define sub-procedures. Each command would be in its own text file: PROCEDURE Plugin1; CONST {your constants} VAR {your vars} BEGIN {your calls} END; Your calling procedure for your menu item would look like: PROCEDURE Main; CONST {your main constants} VAR {your main vars} {$INCLUDE path_and_Plugin1_filename} {$INCLUDE path_and_Plugin2_filename} {etc...} BEGIN Plugin1; Plugin2; {etc} END; Run(Main); Hope this makes sense. -Josh Quote Link to comment
MullinRJ Posted May 25, 2009 Share Posted May 25, 2009 To the best of my knowledge, you cannot call custom Menu Commands from within another Menu Command or Plug-In object. If you find a way to do so, please post it. Raymond Quote Link to comment
_c_ Posted May 26, 2009 Share Posted May 26, 2009 (edited) In commands you have the workaround to call other dialogs from a dialog. Execute them and do something else upon quitting of the second (or later) dialog. The simplest solution is to use includes (I just saw that Josh told you the same). Remember that your scripts are now to be treated as subroutines, so remove the call "Run" at the end of each singular script: PROCEDURE ChainMe; {$INCLUDE path/to/routine/RunPlugin2} {$INCLUDE path/to/routine/RunPlugin3} {$INCLUDE path/to/routine/RunPlugin4} {$INCLUDE path/to/routine/RunPlugin5} BEGIN RunPlugin2; RunPlugin3; RunPlugin4; RunPlugin5; END; Run(ChainMe); orso Edited May 26, 2009 by _c_ Quote Link to comment
MullinRJ Posted May 26, 2009 Share Posted May 26, 2009 Timbo, ???If you want a script to be both stand-alone and callable from a larger script you will need a library (folder) of script parts that you can assemble with $INCLUDE statements in other files. For example: ???PROCEDURE SetLW6; ???PROCEDURE SetFillBlue: ???PROCEDURE SetOutline; ???PROCEDURE SelectAllRects; might be routines you want to call individually or from another script. In your library, split the small routines into two pieces; one that has the procedure definition in one file; and the other that has two lines, an $INCLUDE and a RUN(); File "SetLW6.px": ???PROCEDURE SetLW6; ???BEGIN ??????PenSize(6); ???END; File "RunSetLW6": ???{$INCLUDE \YourLibrary\SetLW6.px } ???Run(SetLW6); ???File "RunSetLW6" is the file you would use to make a Menu Command PIO for the stand-alone execution of "SetLW6". ???In a larger script you can access the procedures in your library by adding several $INCLUDE files then calling the included procedures. File BIG_SCRIPT_1: ???PROCEDURE BIG_SCRIPT_1; ??????{$INCLUDE \YourLibrary\SetLW6.px } ??????{$INCLUDE \YourLibrary\SetFillBlue.px } ??????{$INCLUDE \YourLibrary\SelectAllRects.px } ???BEGIN ??????{ Your code here } ??????SetLW6; ??????SetFillBlue; ??????{ Draw something here } ??????DSelectAll; ??????SelectAllRects; ??????{ More of your code here } ???END; ???Run(BIG_SCRIPT_1); ???If you want to call BIG_SCRIPT_1 from other scripts, then split it in two pieces as shown above. With this setup, you can make changes to any of your files and they will be reflected in all procedures that use them. ???One last caveat, always have at least one blank line at the end of each $INCLUDE file. Without it you will get compiler errors. HTH, Raymond 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.