Jump to content
Macro Express Forums

Solution to indexing an array with a variable


Recommended Posts

In the Script Editor dialogs that include a "Variables" button there is a problem. These buttons bring up a sub-dialog "Insert Variable". This dialog will allow an array variable to be chosen from a list of available variables. Left clicking the desired variable will place its name in the "Variable Name:" field (without enclosing %s) suffixed with a pair of empty square brackets. An appropriate index must be typed within those brackets. The program will only accept digits. Therefore, it might seem that an array could not be indexed by a variable. If that were the case, we would be unable to step through precessing each element of an array within a repeat block.

 

However, there is a simple solution. Enter a dummy integer index in the square brackets. Close the sub-dialog "Insert Variable". Now in the original dialog, replace the dummy index with the name of the indexing variable enclosed within %s.

 

The result will look something like this: %StringArray[%ArrayIndex%]"%. Now within a Repeat block we will be able to step through processing each element of the array %StringArray%.

Link to comment
Share on other sites

Your solution is exactly correct and I've done this same trick with several of my macros. Repeating thru arrays can be very handy. The other solution is to simply type the variable name in without using the Variables button. One might suggest to change this in the dialog but realistically I think it's better to have the validation working as it is as most users will not venture down this path and it's easy to work around.

Link to comment
Share on other sites

Arrrgh!! I can't get my own solution to work for me. Here is a sample that fails.

 

Variable Set String %StringText% to "some words"

Repeat Start (Repeat 10 times)

Variable Modify String: Copy a substring in %StringText%, starting at %Index% and 1 characters long to %Letters[%Index%]%

End Repeat

 

%StringText% is a string variable.

%Index% is an integer variable.

%Letters% is a string array variable.

 

This results in an empty %Letters% array.

 

If I modify the code to target %Letters[1]%, it leaves %Letters[1]% with the value "s", as expected.

 

Surely there must be a way to index an array with an integer variable. What am I missing here?

Link to comment
Share on other sites

I'm not sure whether you are asking me for the code of the test snippet or of the actual macro I am developing.

 

The test snippet's code is:

 

<VARIABLE SET STRING Option="\x00" Destination="%StringText%" Value="some words"/>

<REPEAT START Start="1" Step="1" Count="10" Save="TRUE" Variable="Index"/>

<VARIABLE MODIFY STRING Option="\x09" Destination="%Letters[%Index%]%" Variable="%StringText%" Start="%Index%" Count="1"/>

<END REPEAT/>

 

The actual macro will emulate Microsoft Word's capitalization command (normally triggered in Word by Shift/F3) for use in non-Word applications. Most immediately I want to use it in Open Office (though I don't want it restricted to that ap), because I am trying to wean myself from Microsoft.

 

If you want the script or code as it stands now, I can send it to you.

 

Thanks for your help.

 

Stan

Link to comment
Share on other sites

Next time you might try using the forums code box to paste your script commands in. I can clean them up but others might have issues.

 

I do not know how it is you're planning on doing this but the code you sent me works fine. My "Variables Values" tab in the debug pane is broken so I added a text box in the middle that would display all the array variables with numbers in the index part and one with %Index% in there and it worked just fine. In every iteration of the repeat it would display the next letter. Run this by itself for me and tell me why this doesn't work for you:

<VARIABLE SET STRING Option="\x00" Destination="%StringText%" Value="some words"/>
<REPEAT START Start="1" Step="1" Count="10" Save="TRUE" Variable="Index"/>
<VARIABLE MODIFY STRING Option="\x09" Destination="%Letters[%Index%]%" Variable="%StringText%" Start="%Index%" Count="1"/>
<TEXT BOX DISPLAY Title="Result" Content="{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fnil\\fcharset0 Tahoma;}{\\f1\\fnil Tahoma;}}\r\n\\viewkind4\\uc1\\pard\\f0\\fs16 Letter: %Letters[%Index%]%\\f1 \r\n\\par \\f0 Index: %Index%\r\n\\par Letter1: %Letters[1]%\r\n\\par Letter2: %Letters[2]%\r\n\\par Letter3: %Letters[3]%\r\n\\par Letter4: %Letters[4]%\r\n\\par Letter5: %Letters[5]%\r\n\\par Letter6: %Letters[6]%\r\n\\par Letter7: %Letters[7]%\r\n\\par Letter8: %Letters[8]%\r\n\\par Letter9: %Letters[9]%\r\n\\par Letter10: %Letters[10]%\r\n\\par \r\n\\par }\r\n" Left="Center" Top="425" Width="278" Height="258" Monitor="0" OnTop="FALSE" Keep_Focus="TRUE" Mode="\x00" Delay="0"/>
<END REPEAT/>

Also I think you might be going about this wrong. Or that is to say using the array in a way it's not best suited for and I'd like to show you a better way. But I want to know a couple of things first: Is your intention that %StringText% would have a whole bunch of words and that you want to apply some capitalization rule too? And what capitalization rule would you like to apply? EG Sentence Case, Title Case, All upper case, or other?

Link to comment
Share on other sites

Aha! The problem seems to have been with my debug variables display. The value of StringText is displayed properly by the Variable Values Debugger, but it does not display the Letters array values as I step though the repeat. Your addition of the Text Box display revealed that they were being correctly set. Maybe you are not the only one who has a broken debug pane.

 

Thanks for alerting me to the proper use of the CODEBOX. I haven't been on this forum since 2004 when I did my last serious work with Macro Express.

 

Yes, I have a bunch of words to which I do want to apply a capitalization rule. Uppercase and lowercase are easy. Its Title Case that is responsible for my contortions. I'd welcome a better way to do this--or anything else, for that matter.

 

Thanks again.

 

Stan

Link to comment
Share on other sites

For the record the incident number for the variables debug pane not updating is 6205 and a write up on it can be found at my page here. ISS thought they had fixed it and marked it resolved but I recently brought it back up with them. I hope they get it fixed soon, it's killing me!

 

As for your approach I think it could be done better. Storing each text in a different array index is an unnecessary complication IMHO. What I would do is to go thru letter by letter from a source variable to a results variable. Start by getting the %length% of the text and use that for the number of repeats. Then with each iteration store the the iteration in %position%. In each iteration copy one character at %position% and store it in %char%. Now test if it's a space and trip the boolean var %space%. If it's a space simply append that character to %result% and skip the rest. This is the trigger for the next iteration. On the next iteration you test to see if the last one was a space and if it is see if the character is a lower case letter. Do this by getting the ASCII value and if it's greater than 96 and less than 123 it's a lower case letter. In ASCII lower "a" is 97 and z is 122. If that's the case subtract 32, upper A is 65 thus the difference, to get the upper case equivalent. Now convert back to a letter and write to %char% flip the space boolean var back off. In each iteration you simply append to %result% and move on. Very simple. You could also add a lot of functionality by coming up with different logic for each type of case conversions. Shouldn't make it too much more complicated.

 

After reading this i decided it sounded way more complicated than it is so I decided to create an example and posted it to my website here. As you can see it's not at all complicated, in fact only 21 lines of code.

Link to comment
Share on other sites

Thanks for the leg up, Cory.

 

Well, my macro is finished. It recognizes the case of either a selected word/phrase or the word in which the cursor is located, and it replaces lowercase with Title Case, Title Case with ALL CAPS, & ALL CAPS with lowercase.

 

I have avoided arrays, and in the conversion to Title Case I have used a slightly modified version of your macro.

 

Unfortunately, my dream of creating a macro that would work in any text editing application has faltered with OpenOffice Writer (my primary application). My macro works there, but it takes too long. For every other application I have tried (including Microsoft Word, where it is superfluous), the replacement is virtually instantaneous. For Writer, it takes several seconds.

 

If anyone wants the macro, I could make it available (of course, with your permission to use your macro). I notice that you posted your macro on your site. Lacking a site, as I do, what it the best place to make our macros available to others?

 

Stan

Link to comment
Share on other sites

Why is it any slower? Are you running this in the editor or are you copying it to your clipboard? If copying it to your clipboard as in my example they should all process at the same speed which should be nearly instantaneous.

Link to comment
Share on other sites

I've managed to fix the problem with the debugger pane. The variable values pane was getting messed up because you were using [%Index%] as a part of the variable and we weren't taking that into account. The next build has this fixed.

 

As for the clipboard speed in Writer, please go into MEPro's options > Preferences > Playback > Delays and double-check your "failed clipboard commands" delay. I would recommend setting it no higher than 250 ms. If the clipboard can't be opened by MEPro (because Writer still has it locked), then MEPro will wait for the specified time before trying again, up to five times. This might help you out.

 

Also, make sure that you're not using this in the debugger as there is more information being passed back and forth between the debugger and the player (unlike in ME3), so it's a tad slower that way, too.

Link to comment
Share on other sites

I am not running it in the editor. In fact, the editor is closed.

 

In Open Office Writer the macro takes about five seconds to change the case of the selection, regardless of the length of the selection. In other programs (this reply editor, for instance), it is almost instantaneous.

 

The "failed clipboard commands" setting was the default 250 ms. I reset it to 100 ms. That made no perceptible difference in the delay.

 

Cory, I am copying the selected text to a string variable, processing it, and then pasting it back into the original document. When the text is being converted to Title Case I am using your macro. When the conversion is to lowercase or Uppercase, I am not. All three cases show the same five second delay.

Link to comment
Share on other sites

Well guys, I have egg on my face.

 

I discovered what was causing the delay in the execution of my capitalization macro in Open Office Writer. The activation I had chosen was Shift/F5. For some reason in Writer, and only in Writer, I was not releasing the Shift key for five seconds after I pressed the combination. So long as the Shift key is depressed the macro's execution is delayed. I have verified that I can get the same delay in any editor and that I can eliminate it from Writer simply by promptly releasing both keys.

 

I am sorry to have caused needless fuss. I can only hope my folly is of benefit to someone else. I did learn a lot along the way. Thanks especially to Cory and Chris for furthering my Macro Express Pro education.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...