I tend to use inline functions for this type of thing.
E.G.
Inline C# Function: Find spoken item and calculate corresponding coordinates, wait until execution finishes
Move mouse cursor to screen coordinates by text/token X:{INT:~x}, Y:{INT:~y}
Click left mouse button
where "Find spoken item and calculate corresponding coordinates" contains
using System;
using System.Windows.Forms;
public class VAInline
{
string[] items =
{
"Item 1", "Item 2", "Item 3",
"Item 4", "Item 5", "Item 6",
"Item 7", "Item 8", "Item 9",
};
const int itemsPerColumn = 3;
const int startingX = 100; //Leftmost cursor position for the item in column 1, row 1
const int startingY = 200; //Topmost cursor position for the item in column 1, row 1
const int columnOffset = 100; //Distance from the starting point the cursor should move horizontally for each column but the first
const int rowOffset = 200; //Distance from the starting point the cursor should move vertically for row but the first
public void main()
{
if (VA.Command.Action() == "External")
{
Clipboard.SetText("Select [" + String.Join(";", items) + "]"); //The "When I say" contents are configured here
VA.WriteToLog("\"When I say\" contents copied to clipboard", "black");
return;
}
int spokenItemIndex = Array.FindIndex(items, x => x.Equals(VA.Command.Segment(1), StringComparison.CurrentCultureIgnoreCase));
if (spokenItemIndex == -1)
{
VA.WriteToLog("Error: Spoken item could not be found", "red");
return;
}
VA.SetInt("~x", startingX + ((spokenItemIndex % itemsPerColumn) * columnOffset));
VA.SetInt("~y", startingY + ((spokenItemIndex / itemsPerColumn) * rowOffset));
}
}
You can input the names of your items as elements of the "items" array, as shown (I.E. the name of your item, wrapped in double quotes, followed by a comma).
The item definitions don't actually need to be arranged in a grid; you could put them all on one line of you wanted to.
Instead of then manually needing to input those same values in the "When I say" field of the command, you can execute the command from the command list (by right-clicking it and choosing "Execute"), which will copy the appropriately-formatted values to the clipboard, after which you can edit the command and paste them into the "When I say" field
If you'd prefer to input the item names outside of the inline function, this alternate version could be used:
Set text [~items] to 'Item 1;Item 2;Item 3;Item 4;Item 5;Item 6;Item 7;Item 8;Item 9'
Inline C# Function: Find spoken item and calculate corresponding coordinates, wait until execution finishes
Move mouse cursor to screen coordinates by text/token X:{INT:~x}, Y:{INT:~y}
Click left mouse button
where "Find spoken item and calculate corresponding coordinates" contains
using System;
using System.Windows.Forms;
public class VAInline
{
const int itemsPerColumn = 3;
const int startingX = 100; //Leftmost cursor position for the item in column 1, row 1
const int startingY = 200; //Topmost cursor position for the item in column 1, row 1
const int columnOffset = 100; //Distance from the starting point the cursor should move horizontally for each column but the first
const int rowOffset = 200; //Distance from the starting point the cursor should move vertically for row but the first
public void main()
{
string[] items = VA.GetText("~items").Split(';');
if (VA.Command.Action() == "External")
{
Clipboard.SetText("Select [" + String.Join(";", items) + "]");
VA.WriteToLog("\"When I say\" contents copied to clipboard", "black");
return;
}
int spokenItemIndex = Array.FindIndex(items, x => x.Equals(VA.Command.Segment(1), StringComparison.CurrentCultureIgnoreCase));
if (spokenItemIndex == -1)
{
VA.WriteToLog("Error: Spoken item could not be found", "red");
return;
}
VA.SetInt("~x", startingX + ((spokenItemIndex % itemsPerColumn) * columnOffset));
VA.SetInt("~y", startingY + ((spokenItemIndex / itemsPerColumn) * rowOffset));
}
}