kaj5021 Posted November 20, 2025 Share Posted November 20, 2025 (edited) I have a weird thing I'm trying to do in order to produce variable values based on constants, and define the constant to be use by concatenating a common text and the loop (FOR) variable. Example script below on a first try, which returns no errors but does not recognize the string as the name of a constant. I understand that this returns just the concatenation string (the name of the constant I'm trying to grab), so wondering if this is at all possible or what other way I could go about having a loop set the variables based on a list of constants. Should I instead make a list of the values and choose the value that matches my 'pass' variable (like a substring function, with the 'pass' variable as the index). Thanks in advance! PROCEDURE LoopRecToParam; CONST { The count of total passes the loop will take, dependant on the number of fields to transfer to parameters } kCOUNT=2; { Record Format Designations, such as 'Record Format'.'Record Field 1' } kRecordFormat='Record Format'; kRF1='Record Field 1'; kRF2='Record Field 2'; { Contextual Paramater Designations, such as 'Lighting Device'.'Inst Type' } kParamType='Object Type'; kPT1='Parameter 1'; kPT2='Parameter 2'; VAR Data:STRING; hLD: HANDLE; pass:INTEGER; BEGIN FOR pass:=1 TO kCOUNT DO hLD:= FSActLayer; { Ideally this would result in the constant kRF1 being used for the 'Data' variable } Data:=GetRField(hLD, kRecordFormat, Concat('kRF',pass)); { Same rule as above, if I can make it work, to define the parameter to use via Concat } SetRField(hLD,kParamType,Concat('kPT',pass),Data); ResetObject(hLD); END; RUN(LoopRecToParam); Edited November 20, 2025 by kaj5021 Quote Link to comment
Pat Stanford Posted November 20, 2025 Share Posted November 20, 2025 I think you will need to save the concated value into a variable and then use that variable in the GRField. The following works to return the field value of a Record names PTS and a field named MKS. Procedure Test; CONST M1='M'; K1='K'; S1='S'; VAR S2,S3:String; BEGIN S2:=Concat(M1,K1,S1); S3:=GetRField(FSActLayer, 'PTS', S2); AlrtDialog(Concat('Field ',S2,' = ', S3)); End; Run(Test); Quote Link to comment
kaj5021 Posted November 21, 2025 Author Share Posted November 21, 2025 Thank you @Pat Stanford, would I be able to define the constant to use via constants and variables? That's the only way I can imagine looping through the right fields and parameters to match them up and move the right source values to the right destinations. Another way I was considering was a char array, but not sure how I can translate that to call constants or variables into the GRField and SRField steps. Is this an approach that could do that, because I don't think I can build the exact field names every time using a variable combining constants. I'd need to (as far as I can tell) cycle through constants in a loop that already have the field names defined. Let me know if what you have there will actually work for what I'm trying to do and am just missing it. Thank you again! Really good to know for other uses I can see. Quote Link to comment
Pat Stanford Posted November 22, 2025 Share Posted November 22, 2025 After some additional research, you are not going to be able to do what you want in Vectorscript. But it is likely that you can in Python using the eval_() function. (without the underscore. The Forum errors on the exactly correct version) 1 Quote Link to comment
JBenghiat Posted November 22, 2025 Share Posted November 22, 2025 @kaj5021 can you give some sense of your end goals? If its to dynamically fetch field data, GetRField takes a string for it’s field parameter, so you can construct a string to retrieve the desired value. Note that if this is for another plug-in, you need to use the field’s universal name, which you can find when working with worksheets. if it’s to set and retrieve a variable number of data, your best approach is to serialize the data and store as a string, which is what Pat is describing. If you have an event enabled plug-in, you can even dynamically add widgets to object info to access the data. 1 Quote Link to comment
kaj5021 Posted November 24, 2025 Author Share Posted November 24, 2025 @Pat Stanford That was my worry, and what it looked like at my first tests (I'm very new to scripting in Vectorworks, but get the general functionality of scripts from other programs/projects). I'll look into Python, which I have more resources to help me through if I need than I do in Vectorscript. @JBenghiat End goal is to move the field values in a record format to the respective parameters of a lighting device/hanging position. In some cases the information that needs to move will depend on what is currently filled, and what the object type is. I was asking in another post if it was possible using the Data Manager to map the parameters in any way but I didn't think it was. I was hoping for a more direct "yes" or "no". So right now I have in my example a string (Data:=GetRField(hLD, kRecordFormat, Concat('kRF',pass))) that was trying to construct the constant to use (I understand now that just won't be interpreted the way I was hoping like a record or field/parameter would). I'm about to just test an ARRAY variable to set the field names to use in a loop, for example. That might be the work around instead of fetching the values through constants, if the array index can be the variable used to count the FOR passes. All in all, I want to do this (to start) on an object-by-object basis before building in the ForEachObject step. In another program, I would put all the fields to use in a value list and choose the value index to use based on the passes from a Loop, but I'm not sure how to do that here. Holding those values and splaying them out/combining the as needed for the parameters would be, I assume, the most efficient way to get the data and put it into the PIO. Widgets sound neat, but I'll have to learn more about them and if they would work for what we're doing here. The project is about collecting our specific data in the most user friendly way and moving the information from fields to the parameters is where we landed. Ideally we'd just be able to map parameters to take on record format fields values and not just have a one way street of data mapping for PIOs. Quote Link to comment
JBenghiat Posted November 24, 2025 Share Posted November 24, 2025 If you are attaching a record directly to the Lighting Device or rigging object, then the Data Manager will do this for you. Take a look at how the Data Manager handles the Rigging Object Info record that attaches to all rigging objects. For Lighting Devices, you can use the Additional Record settings specified in Spotlight Preferences to have additional data attached to symbols automatically populate Lighting Device fields. If this is your need, send me a personal message — I may have a solution for you that I'm currently testing. You can't concatenate the name of a constant or variable. I do recommend using constants for field names, e.g. kFieldNameGel = 'color'. In VS, you're going to have to write a series of if/then statements to map the field to the constant (which you can make a function); if inField = 'myField' THEN MyGetConstant = kSpotlightConstant. In python you can set up constants as a map, which is much easier. Quote Link to comment
kaj5021 Posted November 25, 2025 Author Share Posted November 25, 2025 @JBenghiat Attaching the records automatically is great through the Data Manager, the main problem I'm trying to solve is parameters taking on the field values, which seems like it's only possible from a script. Using a record format we can have a more specific set of fields that match our companies needs, and gives anyone working in a worksheet a one stop shop for sorting that data while being able to alter it in a worksheet. I didn't realize there was an Additional Records button in the spotlight settings, that's pretty useful. Does that work differently than the data manager when it comes to attaching records to lighting devices? If it's essentially the same thing, I'll stick to the data manager because we are attaching this record to CC devices, Equipment, Hanging Positions, and some standard geometry based on object type and class designation. The Data Manager has been great and very stable in this respect. I did test an Array variable yesterday and was able to get one field in, but it didn't do the second. I keep getting the error that the index is outside the array limits but I only have 2 indexes, the initial value is set to 1, and the limit value is set to 2. I'm not sure what I'm missing here, the first pass should be one and the second pass would meet the limit, so both fields from what I can see should get passed to their respective parameters. it seems to match them up to the right parameters using the pass variable as their index, but only does one at most by the end of the script. It seems like this should work if I can understand why the error comes up and fix it. I'm obviously missing something here 😅 PROCEDURE LoopRecToParam; VAR Data:STRING; hLD: HANDLE; pass:INTEGER; kRecordFormat:STRING; fields:ARRAY[1..2] OF STRING; kParamType:STRING; params:ARRAY[1..2] OF STRING; limit:INTEGER; BEGIN; { Variables for the FOR loop } pass:=1; limit:=2; { Field variables } kRecordFormat:='Record Format Name'; fields[1]:='Record Field 1'; fields[2]:='Record Field 2'; { Object type, like 'Lighting Device' } kParamType:='Object'; params[1]:='Parameter 1'; params[2]:='Parameter 2'; FOR pass:=1 TO limit DO; { Handle Variable } hLD:= FSActLayer; { Set the parameter vaue as the record field value } SetRField(hLD,kParamType,params[pass],GetRField(hLD, kRecordFormat, fields[pass])); {Reset the object to help the parameters display the proper value } ResetObject(hLD); END; RUN(LoopRecToParam); 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.