• MacTech Network:
  • Tech Support
  • |
  • MacForge.net
  • |
  • Apple News
  • |
  • Register Domains
  • |
  • SSL Certificates
  • |
  • iPod Deals
  • |
  • Mac Deals
  • |
  • Mac Book Shelf

MAC TECH

  • Home
  • Magazine
    • About MacTech in Print
    • Issue Table of Contents
    • Subscribe
    • Risk Free Sample
    • Back Issues
    • MacTech DVD
  • Archives
    • MacTech Print Archives
    • MacMod
    • MacTutor
    • FrameWorks
    • develop
  • Forums
  • News
    • MacTech News
    • MacTech Blog
    • MacTech Reviews and KoolTools
    • Whitepapers, Screencasts, Videos and Books
    • News Scanner
    • Rumors Scanner
    • Documentation Scanner
    • Submit News or PR
    • MacTech News List
  • Store
  • Apple Expo
    • by Category
    • by Company
    • by Product
  • Job Board
  • Editorial
    • Submit News or PR
    • Writer's Kit
    • Editorial Staff
    • Editorial Calendar
  • Advertising
    • Benefits of MacTech
    • Mechanicals and Submission
    • Dates and Deadlines
    • Submit Apple Expo Entry
  • User
    • Register for Ongoing Raffles
    • Register new user
    • Edit User Settings
    • Logout
  • Contact
    • Customer Service
    • Webmaster Feedback
    • Submit News or PR
    • Suggest an article
  • Connect Tools
    • MacTech Live Podcast
    • RSS Feeds
    • Twitter

Moving from Microsoft Office VBA to AppleScript:
MacTech's Guide to Making the Transition

Introduction  |  Table of Contents

Page Prev and Page Next buttons at bottom of the page.

Would you like a hard copy
or PDF of this Guide?

You can get a hard copy sent to you
AND download a PDF now ($19.95)
, or

... just download a PDF ($9.95).

Either way, you get a complimentary
MacTech Magazine Subscription

courtesy of the
Microsoft Mac Business Unit


 

  Magazine Reg. Price:  $50.00 value  
  Guide Reg. Price:  $40.00 value  
  You Save:  over $80.00!  

April, 2007
Page 38



          end if        

     end repeat

     set screen updating to true   

end tell

AppleScript does not have anything like VBA's .Next(wdRow) to go on to the next row no matter where you are in the loop or if you just deleted a row or not. Any sort of repeat loop, even one iterating through a previously-formed list such as

set allRows to every row of theTable

is still composed of objects that are references. And in this case, as in many cases the references are by index {row 1 of table 1, row 2 of table 1, row 3 of table 1, … etc.} So even if you

set allRows to every row of theTable

repeat with i from 1 to (count allRows)

   set theRow to item i of allRows

hoping that it will merely go fetch the item i of your list as it was when you made the list, that is not the case. That item was a reference to row i of theTable, so now it goes and re-evaluates row i of the table, which has a different content than row i had previously (if you altered the table during the loop). The result is that it will skip an item. This is not the case in an application like Entourage where almost every application reference is to a "hard-coded" object with a unique ID in its database. That is a sort of "luxury" a database-based application can have.

(In Entourage, all references to objects, however you make them – by name, by index, whatever – all resolve to the "canonic" reference by ID. So a list of allMessages in a folder, for example, would consist of {message id 12345, message id 12346, message id 12347, message id 12348}. Even if you deleted the second item of that list, it does not disappear from the list, so getting item 3 of allMessages still gets you message id 12347, not id 12348.)

In Word, as in the Finder and most other applications, the index of the reference will be re-evaluated, and you'll end up with an item skipped and later an error when the final indices are found not to exist any longer. That's why you have to iterate backwards, since indices lower than items you have deleted are not affected.

There are some situations where you can work around Word's propensity to re-evaluate every reference: for example, application references such as active document. If you set a variable like theDoc to active document (meaning the document in the front, of course), then minimize (collapse) window 1 of the front document to the Dock, and then call theDoc again (perhaps to activate it again), your original reference is lost, since Word re-evaluates theDoc to the new document that is now in the front!

The way to get around this is to find something that uniquely identifies the current active document and refer to it by this identifier when setting your variable. The ideal unique identifier of any document is its name: there can only be one document with the same name:

tell application "Microsoft Word"

     set theName to name of active document

     set theDoc to document theName

end tell

Here the variable theDoc remains "hard-coded" to the document currently active. So even when you collapse its window to the Dock and another document becomes active window, the variable theDoc remains pointing to the same document that it was originally set to, and you can re-activate or do anything to it without it pointing to a different document.

But in the case of this list of allRows, where each individual list item is a reference to {row 1 of table 1, row 2 of table 1… etc.} – a list of rows by index – and gets re-evaluated when called, resulting in skipped items and an error. So you must iterate backwards. There is no unique identifying feature for any row, at least not when getting 'every row' as a list. (Although the Dictionary definition for table claims that you can get a row element "by name" that really means "by index" since rows do not have a name property). It‘s the index for each row that constantly gets re-evaluated as you delete rows, so iterating backwards is the only way to do it.

Because of the repeat with i from numRows to 1 by -1 format, where i is a counter that does not need to be explicitly incremented by you, there is also no need for an initializing statement equivalent to VBA's

Set oRow = oTable.Rows(1).Range

That all gets taken care of inside the repeat loop by

set rowText to text object of row 1 of theTable

Similarly there is no need for a check for textInRow being true, since there's nothing to do if it is: the i counter will increment by itself.

The screen updating and status bar features work just the same in AppleScript as in VBA, only with the adaptations above you will now see the status bar counting down to 1 (which is neat in itself since you'll know how far there is to go before it finishes).

Remove all empty paragraphs from a document

Here's an example that shouldn't require a repeat loop, therefore no backwards iterations either. That's because it uses Find/Replace to do the removing in one go. It comes from a macro by Dave Rado at <http://www.word.mvps.org/FAQs/MacrosVBA/DeleteEmptyParas.htm>, which has extra code to remove empty lines from within and around tables in the document. That code is quite similar to the example just above here, extended to all the tables in a document, and does require converting to backwards repeat loop iterations "by -1". You should not have any trouble adding those portions if you've been following the examples here so far.



< Previous Page Next Page>
 
MacTech Only Search:
Community Search:

 
 
 

 
 
 
 
 
  • SPREAD THE WORD:
  • Slashdot
  • Digg
  • Del.icio.us
  • Reddit
  • Newsvine
  • Generate a short URL for this page:



MacTech Magazine. www.mactech.com
Toll Free 877-MACTECH, Outside US/Canada: 805-494-9797
MacTech is a registered trademark of Xplain Corporation. Xplain, "The journal of Apple technology", Apple Expo, Explain It, MacDev, MacDev-1, THINK Reference, NetProfessional, Apple Expo, MacTech Central, MacTech Domains, MacNews, MacForge, and the MacTutorMan are trademarks or service marks of Xplain Corporation. Sprocket is a registered trademark of eSprocket Corporation. Other trademarks and copyrights appearing in this printing or software remain the property of their respective holders.
All contents are Copyright 1984-2010 by Xplain Corporation. All rights reserved. Theme designed by Icreon.
 
Nov. 20: Take Control of Syncing Data in Sow Leopard' released
Nov. 19: Cocktail 4.5 (Leopard Edition) released
Nov. 19: macProVideo offers new Cubase tutorials
Nov. 18: S Stardom anounces Safe Capsule, a companion piece for Apple's
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live
Nov. 17: Ableton releases Max for Live