Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Replace Word in Text Doc with Cell in Excel Doc

I have a Text Document with 80 variables throughout the text, each of which I want to easily replace with the information I have in any one, of the several hundred, Excel documents on my Mac.

I would like to open a my text document and have Automator replace

A_1
with whatever text is in the Cell A1 of an also open Excel Doc, and then automatically move down to
A_2
,
A_3
, and so on.

I have scoured the 'net and tried a ton of methods including the recording tool but I’m not having much success.

I would like to use Automator for this, but if you have a Mac program you suggest instead, I would love your advice on that too.


Thanks so much (:

MacBook, OS X Yosemite (10.10.3)

Posted on Apr 22, 2015 2:45 PM

Reply
7 replies

Apr 22, 2015 2:56 PM in response to calviwills

I am being curious more than helpful with the following:


So some type of script has to look up the contents of hundreds of Excel files?


Can you provide some more detail as to how your text document is laid out?


E.g. is it narrative with A_1 and A_2 throughout the text or it is line by line with some structure?


What is an example content of the Excel cell for a variable such as A_2 ?

Apr 23, 2015 10:50 AM in response to calviwills

You may be overthinking this... at least as far as how complex this may be.


Your use case is pretty unique, so you're not likely to find a pre-built app/script that will do it for you, but the semantics of what you're trying to do is pretty straightforward and amount to a few lines of AppleScript (plus some error checking, if you care).


In short, you have a couple of steps to consider:


1) Get the data from Excel

2) Loop through the text document, replacing known source strings (e.g. "A_1") with values from the Excel data.

3) There is no step 3.


Now, your original post was a little light on details, so I'm making some assumptions here, but it shouldn't be hard to change the use cases.

For a start you mention "A_1", "A_2", etc., so I'm going to assume that all the cell data is in column A and that there's a fixed number of rows. If that's the case, you can get this data via simply:


tell application "Microsoft Excel"

set cell_data to value of every cell of range "A1:A30" of worksheet 1 of document 1

end tell


Now you have a list of values of all cells in the range "A1:A30".

You can edit the script to grab any other range of cells, or be more creative to dynamically determine the number of non-empty cells if you like. For simplicitie's sake let's go with a fixed, known range A1:A30.

That's also it as far as Excel is concerned - we have the data we need (and, to be honest, the less AppleScripting you have to do with Excel, the better your mental health will be).


Now we have our cell data, we just need to iterate through the text document and perform a series of find/replace actions.

You don't say if this is a plain text file, or if it's a formatted document in Word, or Pages, or something else. For now I'll assume plain text and we're using TextWangler (my text editor of choice), but other apps are equally valid with minor changes (unless you're using Microsoft Word, who's AppleScript implementation is, incredibly, even worse than Excel's).

To perform a replace in TextWrangler to replace every occurrence of "A_1" with the value from the first cell, you'd write something like:


tell application "TextWrangler"

tell text of text document 1


replace "A_1"using (item 1 of cell_data)options {starting at top:true, match words:true}


endtell

end tell


the options at the end make sure the entire document is checked, and that only "A_1" is matched (e.g. not A_11, A_12, etc.)


So now you have the basic construct - how to extract the data from Excel, and how to perform a find/replace. The only missing part is iterating through all the cell values (where the above example only handles the first cell). That last point can be addressed with a simple loop:


tell application "TextWrangler"

tell text of text document 1

repeat with index from 1 to count cell_data


replace ("A_" & index as text) using (itemindex of cell_data) options {starting at top:true, match words:true}

end repeat

end tell

end tell

Now you can see I setup a loop that iterates through the number of cells in cell_data and performs a replace using the index to match the cells (e.g. A_1 matches cell 1, A_2 matches cell 2, etc.)


So now, the completed script should look like:


tell application "Microsoft Excel"

set cell_data to value of every cell of range "A1:A30" of worksheet 1 of document 1

end tell


tell application "TextWrangler"

tell text of text document 1

repeat with index from 1 to count cell_data


replace ("A_" & index as text) using (itemindex of cell_data) options {starting at top:true, match words:true}

end repeat

end tell

end tell


Just open your Excel sheet, open the text document, and run.


As I hinted at the beginning, this is only a skeleton example, and there is more that you might want/need.

For example, there's no error checking to make sure that there's any Excel document actually open (nor TextWrangler document for that matter).

There's also no handling of cells outside of the A column - I took your original post literally, but if you want to match any cell on the sheet (e.g. A_3, B_43, AD_256) then there's more work to do.

Apr 23, 2015 11:02 AM in response to Camelot

Camelot,

I am literally in tears right now just thinking about how much time you just saved me. It's overwhelming. Thank you a million times over!


Please stick with me because I tested the code you sent me and it works like a charm but I would love to try an edit.

I have 2 rows in the Excel doc, A1:39 and B1:39.

Is it possible to make the same program replace B_1, B_2 with corresponding cells, as well?


<Edited by Host>

Apr 23, 2015 11:57 AM in response to calviwills

I have 2 rows in the Excel doc, A1:39 and B1:39.

Is it possible to make the same program replace B_1, B_2 with corresponding cells, as well?


Sure. That's pretty easy, and there are a couple of ways of doing it. The simplest may be to implement two runs - extract the two columns of data from Excel, and run two sets of replace commands - one for the A column and one for the B, like:


tell application "Microsoft Excel"

set colA_data to value of every cell of range "A1:A39" of worksheet 1 of document 1

set colB_data to value of every cell of range "B1:B39" of worksheet 1 of document 1

end tell


tell application "TextWrangler"

tell text of text document 1

repeat with index from 1 to count colA_data


replace ("A_" & index as text) using (itemindex of colA_data) options {starting at top:true, match words:true}


replace ("B_" & index as text) using (itemindex of colB_data) options {starting at top:true, match words:true}

end repeat

end tell

end tell


Here you can see I copy out two ranges from Excel into colA_data and colB_data. Then I run two replacements inside the loop, one for each of the columns.

This is a little fragile in that it assumes the two columns are equal length (i.e. both have 39 rows). If they don't you may need to change the loop, or change the loop to the longest column.


This is a slightly more flexible model which would allow you to select a two-dimensional range (e.g. A1:B39), but that gets more complex when working out the column split, so for this I'd prefer to keep track of the columns separately.

Apr 23, 2015 12:47 PM in response to Camelot

Camelot,

Either you were sent by God or you are God. Thank you a million times over!

Your codes work flawlessly!


I have come across an issue though, and it's completely my fault, not yours-- and I think you predicted it earlier:

Camelot wrote:


You may be overthinking this... at least as far as how complex this may be.


I may have over-thought the complexity of things because I have no idea what is possible with Apple-Script.



You see, I have a web-form that I have to fill and submit many times. Each with different entries. The default text in each Text-Box is something like A_1 or B_2, which needs to be replaced by the corresponding Excel Cell in a given document.


So you see, I was planning to copy the source code of the form (via developer mode) and paste it into TextWrangler, then use the program you made, and paste the edited version back into Safari, so I could submit a filled form.


But as you probably realize, I could save myself several more steps if the program simply replaced the text from the form fields, directly in Safari, without copying source code to TextWrangler.


How difficult would it be to do that? I realize this has strayed from the original request, but I suppose these threads do that a lot as you programers open the eyes of novice users to such possibilities!


If no, or you're un-interested, I understand. Just let me know and I will be happy to close this topic as you have answered the original question fully, and for that I can't thank you enough!


- Calvin W

Apr 23, 2015 11:21 PM in response to calviwills

Ahh, now I've piqued your interest and, unfortunately, the next level you're looking at is automating web applications. bwahahaha!


Seriously, though there are two ways to script web applications via your browser - one is to use UI scripting to emulate the actions you'd take to fill out the form itself, the other is to use JavaScript in the browser to populate (and submit) the form. (There may be a third option, which is to bypass the browser altogether and just submit the form data directly, but let's ignore that for now). Each case, though, is a minefield until itself.


In the case of UI scripting you're relying on the web form being consistent and never changing. It's also intolerant of you doing anything else on the machine at the time because it will interrupt the flow, potentially putting the wrong data in the wrong fields.

The more direct approach is to populate the field via JavaScript commands (invoked via Safari's do Javascript action), but this requires an understanding of JavaScript and the form itself, and will break if the form changes in any way. I also suck at Javascript and can't help you build a solution based on this option.

If you can work out the Javascript I can get you the AppleScript wrapper around it 🙂


So where does that leave us? Hard to tell since I don't know how often you use this, and how much time/effort it's worth to you. My initial reaction would be to just extend the existing script to not only edit the HTML as we do now, filling in the form data, but also re-opening the page in your browser and submitting the form. This takes out a good chunk of the remaining work involved in submitting the data back to the server.

Apr 24, 2015 8:57 AM in response to Camelot

I'm interested in the first idea. This is pretty important to me so I'm would like to see this work.

However I have another thought. What if Automator went down the list and filled out according to an Excel doc? It would take longer and allow for more error possibilities but it could work, yeah?


Here's part of my form code. The "module_Id numbers are always changing I think which may make things difficult.


I have learned that the browser has to think that a person is actually filling our the form. I'm not sure why but this thing is picky.


What's your thoughts?

| Here are three rows of HTML from my web form. I saved it as a JS to avoid a browser from trying to read it, but it's HTML.


Here is a pic:


User uploaded file


Thanks (:

Replace Word in Text Doc with Cell in Excel Doc

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.