Sebastiaan Posted October 2, 2020 Share Posted October 2, 2020 Hi all, I am trying to make a database row based on Lighting devices and I want to set a criteria on the Channel field. In the lighting device record this is a text field. I want to set a filter to show only the lighting devices with a channel number between 1 and 100. But since it is a text field, the criteria field value '<=' and '>=' do not work. I tried to use a value function in the database formula but this does not work when I try it. Is it possible? Or am I doing it wrong? This is how I tried to use the value function in the formula: =DATABASE((NOTINDLVP & NOTINREFDLVP & (PON='Lighting Device') & (VALUE('Lighting Device'.'Channel')>='1') & (VALUE('Lighting Device'.'Channel')<='100'))) This way gives the desired result, but is a very long formula to edit: =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & (R IN ['Lighting Device']) & (('Lighting Device'.'Channel'='1') | ('Lighting Device'.'Channel'='2') | ('Lighting Device'.'Channel'='3') | ('Lighting Device'.'Channel'='4') | ('Lighting Device'.'Channel'='5') | ('Lighting Device'.'Channel'='6') | ('Lighting Device'.'Channel'='7') | ('Lighting Device'.'Channel'='8') | ('Lighting Device'.'Channel'='9') | ('Lighting Device'.'Channel'='10') | ('Lighting Device'.'Channel'='11') | ('Lighting Device'.'Channel'='12') | ('Lighting Device'.'Channel'='13') | ('Lighting Device'.'Channel'='14') | ('Lighting Device'.'Channel'='15') | ('Lighting Device'.'Channel'='16') | ('Lighting Device'.'Channel'='17') | ('Lighting Device'.'Channel'='18') | ('Lighting Device'.'Channel'='19') | ('Lighting Device'.'Channel'='20') | ('Lighting Device'.'Channel'='21') | ('Lighting Device'.'Channel'='22') | ('Lighting Device'.'Channel'='23') | ('Lighting Device'.'Channel'='24') | ('Lighting Device'.'Channel'='25') | ('Lighting Device'.'Channel'='26') | ('Lighting Device'.'Channel'='27') | ('Lighting Device'.'Channel'='28') | ('Lighting Device'.'Channel'='29') | ('Lighting Device'.'Channel'='30') | ('Lighting Device'.'Channel'='31') | ('Lighting Device'.'Channel'='32') | ('Lighting Device'.'Channel'='33') | ('Lighting Device'.'Channel'='34') | ('Lighting Device'.'Channel'='35') | ('Lighting Device'.'Channel'='36') | ('Lighting Device'.'Channel'='37') | ('Lighting Device'.'Channel'='38') | ('Lighting Device'.'Channel'='39') | ('Lighting Device'.'Channel'='40') | ('Lighting Device'.'Channel'='41') | ('Lighting Device'.'Channel'='42') | ('Lighting Device'.'Channel'='43') | ('Lighting Device'.'Channel'='44') | ('Lighting Device'.'Channel'='45') | ('Lighting Device'.'Channel'='46') | ('Lighting Device'.'Channel'='47') | ('Lighting Device'.'Channel'='48') | ('Lighting Device'.'Channel'='49') | ('Lighting Device'.'Channel'='50') | ('Lighting Device'.'Channel'='51') | ('Lighting Device'.'Channel'='52') | ('Lighting Device'.'Channel'='53') | ('Lighting Device'.'Channel'='54') | ('Lighting Device'.'Channel'='55') | ('Lighting Device'.'Channel'='56') | ('Lighting Device'.'Channel'='57') | ('Lighting Device'.'Channel'='58') | ('Lighting Device'.'Channel'='59') | ('Lighting Device'.'Channel'='60') | ('Lighting Device'.'Channel'='61') | ('Lighting Device'.'Channel'='62') | ('Lighting Device'.'Channel'='63') | ('Lighting Device'.'Channel'='64') | ('Lighting Device'.'Channel'='65') | ('Lighting Device'.'Channel'='66') | ('Lighting Device'.'Channel'='67') | ('Lighting Device'.'Channel'='68') | ('Lighting Device'.'Channel'='69') | ('Lighting Device'.'Channel'='70') | ('Lighting Device'.'Channel'='71') | ('Lighting Device'.'Channel'='72') | ('Lighting Device'.'Channel'='73') | ('Lighting Device'.'Channel'='74') | ('Lighting Device'.'Channel'='75') | ('Lighting Device'.'Channel'='76') | ('Lighting Device'.'Channel'='77') | ('Lighting Device'.'Channel'='78') | ('Lighting Device'.'Channel'='79') | ('Lighting Device'.'Channel'='80') | ('Lighting Device'.'Channel'='81') | ('Lighting Device'.'Channel'='82') | ('Lighting Device'.'Channel'='83') | ('Lighting Device'.'Channel'='84') | ('Lighting Device'.'Channel'='85') | ('Lighting Device'.'Channel'='86') | ('Lighting Device'.'Channel'='87') | ('Lighting Device'.'Channel'='88') | ('Lighting Device'.'Channel'='89') | ('Lighting Device'.'Channel'='90') | ('Lighting Device'.'Channel'='91') | ('Lighting Device'.'Channel'='92') | ('Lighting Device'.'Channel'='93') | ('Lighting Device'.'Channel'='94') | ('Lighting Device'.'Channel'='95') | ('Lighting Device'.'Channel'='96') | ('Lighting Device'.'Channel'='97') | ('Lighting Device'.'Channel'='98') | ('Lighting Device'.'Channel'='99') | ('Lighting Device'.'Channel'='100')))) Any thoughts? Quote Link to comment
Jonathan Pickup Posted October 2, 2020 Share Posted October 2, 2020 if the field is a text file, but you want a number, can you convert the text to a number? Quote Link to comment
Sebastiaan Posted October 2, 2020 Author Share Posted October 2, 2020 (edited) 23 minutes ago, Jonathan Pickup said: if the field is a text file, but you want a number, can you convert the text to a number? unfortunately it is not possible to change the channel field in lighting device record to number. This is somehow restricted. Edited October 2, 2020 by Sebastiaan Quote Link to comment
Pat Stanford Posted October 2, 2020 Share Posted October 2, 2020 What happens if you edit your original formula to use just 100 without the quote marks around it? The Value statement should give you a number and you have to compare a number to a number. Also, does Lighting Device.Channel ONLY contain the "number"? If there is anything other than characters 0-9 in the field, then the Value statement won't work. I THINK that even an extra space at the beginning or end will cause the Value to fail. Quote Link to comment
Sebastiaan Posted October 2, 2020 Author Share Posted October 2, 2020 5 minutes ago, Pat Stanford said: What happens if you edit your original formula to use just 100 without the quote marks around it? The Value statement should give you a number and you have to compare a number to a number. Also, does Lighting Device.Channel ONLY contain the "number"? If there is anything other than characters 0-9 in the field, then the Value statement won't work. I THINK that even an extra space at the beginning or end will cause the Value to fail. I tried the formula below and this does not work either: =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & (VALUE('Lighting Device'.'Channel')>=1) & (VALUE('Lighting Device'.'Channel')<=100))) When lighting devices do not yet have a channel number assigned then the field will be an empty string (''). Would that cause a value function to fail too? That would be the only exception to a number in the text field. I was already able to use the lengthy version in a script (with a variable in each of the 100 criteria and about 600 backslashes to escape the apostrophes ;-). So it works, but was curious if it could be shorter. Quote Link to comment
Pat Stanford Posted October 2, 2020 Share Posted October 2, 2020 Can you post a file with a few lights in it. I don't really have time to create a plot to play with, but I would be happy to play with the database criteria and see if we can make something work. Quote Link to comment
Sebastiaan Posted October 3, 2020 Author Share Posted October 3, 2020 (edited) 8 hours ago, Pat Stanford said: Can you post a file with a few lights in it. I don't really have time to create a plot to play with, but I would be happy to play with the database criteria and see if we can make something work. Hi Pat, Of course, attached is a file with 40 lighting devices. 20 of them have the channel field filled with numbers from 1 to 20. the other 20 have numbers in the channel field from 101 to 121. Very curious if this will work in a DB formula. DB Formula Value Fun.vwx Edited October 3, 2020 by Sebastiaan Quote Link to comment
MullinRJ Posted October 3, 2020 Share Posted October 3, 2020 @Sebastiaan , Like Pat, I don't have a file to test this, but if a LD does not yet have a channel then this might work. =DATABASE( (NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'<>'') & (VALUE('Lighting Device'.'Channel')>=1) & (VALUE('Lighting Device'.'Channel')<=100)) ) This expression checks for an empty channel string before it tests the values in the channel HTH, Raymond Quote Link to comment
Sebastiaan Posted October 3, 2020 Author Share Posted October 3, 2020 3 minutes ago, MullinRJ said: @Sebastiaan , Like Pat, I don't have a file to test this, but if a LD does not yet have a channel then this might work. =DATABASE( (NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'<>'') & (VALUE('Lighting Device'.'Channel')>=1) & (VALUE('Lighting Device'.'Channel')<=100)) ) This expression checks for an empty channel string before it tests the values in the channel HTH, Raymond Hi Raymond, The issue is that I think that the value function does not work as expected when used in a DB formula. So your proposed formula does not do the trick either. Thanks! Quote Link to comment
MullinRJ Posted October 3, 2020 Share Posted October 3, 2020 Hi @Sebastiaan , I'm seeing that. After too much trial and error, I've come to the same conclusion. Oddly, this works to show all 40 of the LDs'. =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'>'0'))) BUT, this does not work as expected: =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'>'1'))) It only shows LD's with channels 3-9, and 20. What I've noticed is that the DATABASE() engine is comparing strings, and not numerical values (as you'd like). Strings starting with "2xxx" through "9xxx" satisfy the equation, but strings "10" to "19" and "101" to "120" don't satisfy it because the first character in each string is a "1". You really need a VALUE() function, and that only appears to work in a worksheet cell, and not in a Database row. Sorry, I'm stumped. Raymond 2 Quote Link to comment
Sebastiaan Posted October 3, 2020 Author Share Posted October 3, 2020 (edited) 2 hours ago, MullinRJ said: Hi @Sebastiaan , I'm seeing that. After too much trial and error, I've come to the same conclusion. Oddly, this works to show all 40 of the LDs'. =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'>'0'))) BUT, this does not work as expected: =DATABASE((NOTINREFDLVP & NOTINDLVP & (PON='Lighting Device') & ('Lighting Device'.'Channel'>'1'))) It only shows LD's with channels 3-9, and 20. What I've noticed is that the DATABASE() engine is comparing strings, and not numerical values (as you'd like). Strings starting with "2xxx" through "9xxx" satisfy the equation, but strings "10" to "19" and "101" to "120" don't satisfy it because the first character in each string is a "1". You really need a VALUE() function, and that only appears to work in a worksheet cell, and not in a Database row. Sorry, I'm stumped. Raymond Yes I was guessing that too. It also kinda makes sense when you think of it. There is no cell to represent as value. The function does not change the original database and would have to create a new list of the fields as number values which obviously it doesn’t. I already have the workaround so it is what it is. At least I now know it’s not just me. thank you! Edited October 3, 2020 by Sebastiaan Quote Link to comment
Pat Stanford Posted October 3, 2020 Share Posted October 3, 2020 Yep, it looks like you can't use a Value command in a database formula. What might make your work around easier is to use Question Marks (?) as wildcards for a single character. =DATABASE((('Lighting Device'.'Channel'<='1?')) will return all of the object that have only two characters and start with the number 1. 1?? will return all of the channels with three characters that start with the number 1. So instead of having to do ORs for 1 to 99 you could just do ORs for 1?, 2?, .... 9?. At least a little easier. VW2020 also added a new function called Database By Script that could be useful here. Let me see if I can make that work and I will post it. Quote Link to comment
Sebastiaan Posted October 4, 2020 Author Share Posted October 4, 2020 11 hours ago, Pat Stanford said: Yep, it looks like you can't use a Value command in a database formula. What might make your work around easier is to use Question Marks (?) as wildcards for a single character. =DATABASE((('Lighting Device'.'Channel'<='1?')) will return all of the object that have only two characters and start with the number 1. 1?? will return all of the channels with three characters that start with the number 1. So instead of having to do ORs for 1 to 99 you could just do ORs for 1?, 2?, .... 9?. At least a little easier. VW2020 also added a new function called Database By Script that could be useful here. Let me see if I can make that work and I will post it. Good idea to use the wildcards. That might make it shorter indeed. I will look into that. I do want 100 to belong to the 1 -> 100 range, but that shouldn't be too hard to fit in. I was trying to find some information on the database by script function and did not see much information about in. But I am curious what it is. Quote Link to comment
Sam Jones Posted October 4, 2020 Share Posted October 4, 2020 2 hours ago, Sebastiaan said: information on the database by script function Database by script function? Where? Quote Link to comment
Sebastiaan Posted October 4, 2020 Author Share Posted October 4, 2020 1 hour ago, Sam Jones said: Database by script function? Where? I’m curious what Pat meant with that too! Quote Link to comment
Sam Jones Posted October 4, 2020 Share Posted October 4, 2020 I just discovered it as a Worksheet function, not a VS function. In VW Help, search for "Databasebyscript". I am just investigating that documentation now. Good Luck to both of us. 1 Quote Link to comment
Sebastiaan Posted October 4, 2020 Author Share Posted October 4, 2020 5 minutes ago, Sam Jones said: I just discovered it as a Worksheet function, not a VS function. In VW Help, search for "Databasebyscript". I am just investigating that documentation now. Good Luck to both of us. Interesting! Although as I’ve only just plunged into the the world of scripting in VW, I might need some more practice until I attempt that! Quote Link to comment
MullinRJ Posted October 4, 2020 Share Posted October 4, 2020 Gentlemen, Please check out this page in the VW Help. It's the only place I know that lists the WS Functions. https://app-help.vectorworks.net/2021/eng/index.htm#t=VW2021_Guide%2FWorksheets%2FWorksheet_functions.htm%23XREF_16089_Worksheet_Functions Raymond Quote Link to comment
Pat Stanford Posted October 4, 2020 Share Posted October 4, 2020 I am working on a demo right now, but think I have found a bug. More details later today. Quote Link to comment
Pat Stanford Posted October 4, 2020 Share Posted October 4, 2020 Update. I THINK there is a bug and I have submitted it as such. Basically the idea behind DatabaseByScript is that you run a script and in that script you do whatever you want to determine what objects you want displayed in the database. You are not limited to the standard criteria. They can even be different types of objects. This functionality was originally added in VW2020 to allow Landmark users to generate a schedule that would display the Landscape Area name before the list of plants that are in that area. In VW2020 a Vectorscript command WSScript_AddHandle was added. Your DatabaseByScript script would figure out what objects to include and what order to include them in and then you would pass the handle to each object to the WSScript_AddHandle(YourHandle) and the database was created. Recalculate the worksheet and the script would run again. In VW2021, in addition to the AddHandle a new function WSScript_AddHandleId that lets you add an ID (that I don't know what it is used for) to the returned value also. But in the initial release (and the Beta of SP2), if you use AddHandle, or AddHandleId with an incrementing ID, only about 1/2 the desired items are returned. The workaround is to use WSScript_AddHandleId with a fixed ID. The script has been parameterized to let the user specify the Record name, the Field name, the minimum value to return and the maximum value to return. The Field should contain a string representation of an integer. The only error checking the script does it to make sure the Field for each object contains a valid number. If the field contains a valid number then it converts the string to an integer and checks if it is in the range of the min and max (inclusive). Any items that meet the range are returned in the database. Once you get the database sub-items defined you can use all of the standard worksheet functions to display information about the objects, Record.Field combinations, SUMmarize item and Sum Values. There appears to be another bug I have not had time to fully research yet, but it looks like the first item returned is not SUMmarizing even if the column you are SUMing on is the same as other rows. I have attached a sample file showing both Lighting Devices and also 5 rectangles with a custom record/field combination of PTS.MKS that I was using for testing. Here is the script. Copy everything inside the Code block and paste into a new blank script in VW named StringField_By_Range To enter the script convert a worksheet row to a database and accept whatever default criteria come up. Then right click on the database header row and choose Edit Database Formula. Enter the following to set a range of Lighting Device Channel numbers to display. =DATABASEBYSCRIPT('StringField_By_Range', 'Lighting Device', 'Channel', 4, 105) In the above, 4 is the Min channel to display and 105 is the Max channel. Change those two as you see fit. If you have other objects that have a numeric field stored as a string you can change the Record and Field names above to work with them. Procedure StringField_By_Range; {October 3, 2020} {©2020 Patrick Stanford pat@coviana.com} {Licensed under the GNU Lesser General Public License} {No Warranty Expressed of Implied. Use at your own risk.} {A sample script to show how to use the DatabaseByScript} {functionality in a worksheet to create your own objects when} {the standard criteria are not enough.} {This was originally developed to allow the generation of a} {subset of objects (Lighting Device) which had a field that was} {formatted as a sting, but the user was using as numeric data.} {The desire was to get a subset of the channels using a Min and Max} {value. Since the data was a string, a simple Greater Than or} {Less Than would not work.} {This script is run from the Database Formula Bar using a syntax of:} {=DatabaseByScript('StringField_By_Range', 'Lighting Device', 'Channel',} { Min Channel Number, Max Channel Number)} {where Min Channel Number and Max Channel Number are Integers} {Procedure Execute does the heavy lifting. It converts the string} {representation of the number to an Integer. It then compares that} {Integer to the passed Min and Max Values. If the Integer is in} {the range then it adds the object to the database.} {The main body of the code only gets the parameters that are} {passed to the script and uses the passed Record & Field} {as Criteria in the ForEachObject procedure. ForEachObject} {gets a Handle for each object that matches the criteria} {and passes the handle to that object to the Execute procedure.} {As written, the only criteria is that the object has the} {passed Record (TheRecord) attached. The criteria in the } {ForEachObject line can be changed as necessary to return} {only the correct objects.} {The only error checking in this script is that the data in} {the field passes as TheField actually converts to a valid} {number.} {Do not operate heavy machinery or drive an automobile} {while using this script. If use causes excessive itching or } {unexplainable hair loss, discontinue use immediately and see} {a programmer immediately.} Var CMax, CMin, CInteger: Integer; TheRecord, TheField: String; B1: Boolean; Procedure Execute(Hd1:Handle); {Converts the value in TheRecord.TheField combination to a number} {If it is a valid number then it compares the data to CMin and CMax} {If the value is in the desired range, then add the object specified} {by Hd1 to the database} Begin B1:=ValidNumStr(GetRField(Hd1,TheRecord,TheField), CInteger); {AlrtDialog(Concat(Hd1,' ',CInteger, ' ', B1,' ',CMin,' ',CMax,' ',CInteger>=CMin,' ',CInteger<=CMax)); } If (B1 & (CInteger >= CMin) & (CInteger <= CMax)) Then Begin WSScript_AddHandleID(Hd1,1); {As of VW2021 SP2Beta1, AddHandle and AddHandleId used with} {a variable ID only return a portion of the expected results} {Using a fixed ID of 1 appears to return the correct items.} { AlrtDialog(Concat(CInteger));} {AlrtDialog added for debugging} End; End; Begin {Get the parameters passed top the script} TheRecord:=WSScript_GetPrmStr(0); TheField:=WSScript_GetPrmStr(1); {Record and Field are separate parameters because "escaping" the} {quotes properly to pass as a single Record.Field pair} {makes the script call almost unreadable} CMin:=WSScript_GetPrmInt(2); CMax:=WSScript_GetPrmInt(3); {Change the criteria in the next line to identify only the} {objects that any chance of being in the database. Additional} {criteria like, Layer, Class, In Symbol Definition, etc. would} {be typical. If you use the criteria builder, you probably} {want to edit the generated criteria string to use the variables} {TheRecord and TheField rather than hardcoded Record and Field} {names. This will provide additional flexibility for future use} {if you need to change the Record and field. They will only have} {to be changed in the DatabaseByScript call instead of editing} {the script.} ForEachObject(Execute, ((R IN [TheRecord]))); End; Run(Stringfield_By_Range); Ask again where I have not been clear. Quote Link to comment
Sam Jones Posted October 4, 2020 Share Posted October 4, 2020 WOW ! Thank you for this Pat. I'm in the middle of crafting a large command and pref command for it, but I look forward to investigating this later on. Creating desired but complex worksheet databases has always been near the top of data collection desires. Expect to hear more questions down the road on this, but this is a fabulous start. Thanks again. PS, I hope the old worksheet engine is up to the task. Quote Link to comment
Sebastiaan Posted October 6, 2020 Author Share Posted October 6, 2020 On 10/4/2020 at 10:58 PM, Pat Stanford said: Update. I THINK there is a bug and I have submitted it as such. Basically the idea behind DatabaseByScript is that you run a script and in that script you do whatever you want to determine what objects you want displayed in the database. You are not limited to the standard criteria. They can even be different types of objects. This functionality was originally added in VW2020 to allow Landmark users to generate a schedule that would display the Landscape Area name before the list of plants that are in that area. In VW2020 a Vectorscript command WSScript_AddHandle was added. Your DatabaseByScript script would figure out what objects to include and what order to include them in and then you would pass the handle to each object to the WSScript_AddHandle(YourHandle) and the database was created. Recalculate the worksheet and the script would run again. In VW2021, in addition to the AddHandle a new function WSScript_AddHandleId that lets you add an ID (that I don't know what it is used for) to the returned value also. But in the initial release (and the Beta of SP2), if you use AddHandle, or AddHandleId with an incrementing ID, only about 1/2 the desired items are returned. The workaround is to use WSScript_AddHandleId with a fixed ID. The script has been parameterized to let the user specify the Record name, the Field name, the minimum value to return and the maximum value to return. The Field should contain a string representation of an integer. The only error checking the script does it to make sure the Field for each object contains a valid number. If the field contains a valid number then it converts the string to an integer and checks if it is in the range of the min and max (inclusive). Any items that meet the range are returned in the database. Once you get the database sub-items defined you can use all of the standard worksheet functions to display information about the objects, Record.Field combinations, SUMmarize item and Sum Values. There appears to be another bug I have not had time to fully research yet, but it looks like the first item returned is not SUMmarizing even if the column you are SUMing on is the same as other rows. I have attached a sample file showing both Lighting Devices and also 5 rectangles with a custom record/field combination of PTS.MKS that I was using for testing. Here is the script. Copy everything inside the Code block and paste into a new blank script in VW named StringField_By_Range To enter the script convert a worksheet row to a database and accept whatever default criteria come up. Then right click on the database header row and choose Edit Database Formula. Enter the following to set a range of Lighting Device Channel numbers to display. =DATABASEBYSCRIPT('StringField_By_Range', 'Lighting Device', 'Channel', 4, 105) In the above, 4 is the Min channel to display and 105 is the Max channel. Change those two as you see fit. If you have other objects that have a numeric field stored as a string you can change the Record and Field names above to work with them. Procedure StringField_By_Range; {October 3, 2020} {©2020 Patrick Stanford pat@coviana.com} {Licensed under the GNU Lesser General Public License} {No Warranty Expressed of Implied. Use at your own risk.} {A sample script to show how to use the DatabaseByScript} {functionality in a worksheet to create your own objects when} {the standard criteria are not enough.} {This was originally developed to allow the generation of a} {subset of objects (Lighting Device) which had a field that was} {formatted as a sting, but the user was using as numeric data.} {The desire was to get a subset of the channels using a Min and Max} {value. Since the data was a string, a simple Greater Than or} {Less Than would not work.} {This script is run from the Database Formula Bar using a syntax of:} {=DatabaseByScript('StringField_By_Range', 'Lighting Device', 'Channel',} { Min Channel Number, Max Channel Number)} {where Min Channel Number and Max Channel Number are Integers} {Procedure Execute does the heavy lifting. It converts the string} {representation of the number to an Integer. It then compares that} {Integer to the passed Min and Max Values. If the Integer is in} {the range then it adds the object to the database.} {The main body of the code only gets the parameters that are} {passed to the script and uses the passed Record & Field} {as Criteria in the ForEachObject procedure. ForEachObject} {gets a Handle for each object that matches the criteria} {and passes the handle to that object to the Execute procedure.} {As written, the only criteria is that the object has the} {passed Record (TheRecord) attached. The criteria in the } {ForEachObject line can be changed as necessary to return} {only the correct objects.} {The only error checking in this script is that the data in} {the field passes as TheField actually converts to a valid} {number.} {Do not operate heavy machinery or drive an automobile} {while using this script. If use causes excessive itching or } {unexplainable hair loss, discontinue use immediately and see} {a programmer immediately.} Var CMax, CMin, CInteger: Integer; TheRecord, TheField: String; B1: Boolean; Procedure Execute(Hd1:Handle); {Converts the value in TheRecord.TheField combination to a number} {If it is a valid number then it compares the data to CMin and CMax} {If the value is in the desired range, then add the object specified} {by Hd1 to the database} Begin B1:=ValidNumStr(GetRField(Hd1,TheRecord,TheField), CInteger); {AlrtDialog(Concat(Hd1,' ',CInteger, ' ', B1,' ',CMin,' ',CMax,' ',CInteger>=CMin,' ',CInteger<=CMax)); } If (B1 & (CInteger >= CMin) & (CInteger <= CMax)) Then Begin WSScript_AddHandleID(Hd1,1); {As of VW2021 SP2Beta1, AddHandle and AddHandleId used with} {a variable ID only return a portion of the expected results} {Using a fixed ID of 1 appears to return the correct items.} { AlrtDialog(Concat(CInteger));} {AlrtDialog added for debugging} End; End; Begin {Get the parameters passed top the script} TheRecord:=WSScript_GetPrmStr(0); TheField:=WSScript_GetPrmStr(1); {Record and Field are separate parameters because "escaping" the} {quotes properly to pass as a single Record.Field pair} {makes the script call almost unreadable} CMin:=WSScript_GetPrmInt(2); CMax:=WSScript_GetPrmInt(3); {Change the criteria in the next line to identify only the} {objects that any chance of being in the database. Additional} {criteria like, Layer, Class, In Symbol Definition, etc. would} {be typical. If you use the criteria builder, you probably} {want to edit the generated criteria string to use the variables} {TheRecord and TheField rather than hardcoded Record and Field} {names. This will provide additional flexibility for future use} {if you need to change the Record and field. They will only have} {to be changed in the DatabaseByScript call instead of editing} {the script.} ForEachObject(Execute, ((R IN [TheRecord]))); End; Run(Stringfield_By_Range); Ask again where I have not been clear. Really interesting Pat! Thank you! I will now spend my time trying to actually understand what the code does. 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.