• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

How to deal with Document vs windows vs tabs in Applescript? ID CC 2019

Explorer ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

Hi, 

 

I have a script that can move data from one unformatted table in one document to a formatted table in a second document. It works ok, but if I have a third document, then the script fails. I'm dealing with it with a clause that checks if there are 2 documents or not at the beginning of the script but I would like to be able to have a third document open for reference sometime so I want to modify the script. Don't laugh, it's an old script from Shane which I have adapted a bit.

 

--Table Data replace
--Use this script to replace data in a table already designed in ID CS4.
--You need two document opened, one with a table formatted and the other document with the table with the same number of columns and rows without formating. Select the part you want to replace in the first and the part you want to replace with in the other document and you're good to go.
--By Shane Stanley, from the ID Magazine issue 2.
--fixed number of rows and columns check that didn't work on 2013-03-25 by Jeff Lambert

tell application "Adobe InDesign CC 2019"
	if number of document is not 2 then
		beep
		activate
		display dialog "This script requires two documents open, with equivalent table areas selected." buttons {"OK"}
		return
	end if
	set columnCount1 to count of columns of selection of document 1
	set rowCount1 to count of rows of selection of document 1
	set columnCount2 to count of columns of selection of document 2
	set rowCount2 to count of rows of selection of document 2
	if (rowCount1 is not equal to rowCount2) then
		beep
		activate
		display dialog "The number of rows don't match." & return & " You have " & rowCount1 & " rows for the document in front vs " & return & rowCount2 & " rows for the document in back." buttons {"OK"}
		return
	else if (columnCount1 is not equal to columnCount2) then
		beep
		activate
		display dialog "The number of columns don't match." & return & " You have " & columnCount1 & " columns for the document in front vs " & return & columnCount2 & " columns for the document in back." buttons {"OK"}
		return
	end if
	display dialog "Which document contains the formatted table?" buttons {"Cancel", "Front", "Back"} default button 2
	if button returned of result = "Back" then
		set dataDocument to document 1
		set formatDocument to document 2
	else
		set dataDocument to document 2
		set formatDocument to document 1
	end if
	set ourData to contents of selection of dataDocument
	set contents of selection of formatDocument to ourData
end tell

  

Here's the way I would like to work on this. Having 3 documents open, Document1 in window 1, Document 2 and 3 in a second window. Document 1 would be the active document, and document 3 would be in a hidden tab in window 2.

 

example of documents setupexample of documents setup

 

I don't want to have a dialog that asks which document is the front and the back from a list, it would be too long since I have hundreds of tables to do this way. Having a dialog with two buttons is enough and it defaults to the front-most which is how I usually work, I just hit enter and I'm good to go.

So, how can I deal with the top document in each window? I could have 4 documents or more if possible but still be able to run the script and the only document the script has to work with would be the top ones from each window, not the other tabs which are hidden. If there are more then two windows, it could just throw an error, that would be fine.

Thanks for any help!

TOPICS
Scripting

Views

1.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

I’m not sure tabbing the windows will help. If your reference document is in front before you run the script (you click its title) you could send it to back, which would make the other 2 docs Document 1 and Document 2. So replace the if statement checking the number of open documents with:

 

 

tell application id "com.adobe.indesign"
	set dl to count of documents
	if dl is greater than 2 then
		set ds to every document
		set active document to item (dl - 1) of ds
		set active document to item dl of ds
	end if
end tell

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

Thanks Rob, I've tried it and I thought it worked but no. the third document may, or may not be there. The script needs to look at the two "visible" documents. If there are two documents, you select the table in both and run the script and everything works. If you have a third document, it was running weird and gave an error message (before your code and a change I had made from Shane's code). With your code, if you close a document, I had closed the Document1 because I did a revert on it. It ran all wrong assuming because the now doc ID wasn't then what was expected?
That's why I was asking if there is a way to tell a document that is in a particular window vs just the ID of the document.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

Hi Jeff,

is there a chance that you selected a table or table cells in three of your open documents?

 

Regards,
Uwe Laubender

( ACP )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

Hi Uwe,

 

No, usually, I only have two document open when I do this. BUT, on occasion, I need to look a third document to see if I need to make any change. I do annual reports, so I start with the English version, then, transfer the French data in the formatted table in the English, it works great. But sometimes, I need to adjust the table for the french, so I look at what had been done from last year's document. That's why sometimes, I need the script to run even if there is 3 document open. But I never actually select on more than two documents at a time.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

Hi Jeff,

alright. Then we could look into every open document and see if and what actually is selected.

From your previous posts I understand that the target document is always the active one.

 

Where I am still unsure is:

In what order should the contents be applied.

 

Source cells selected:

SourceCells-SELECTED.PNG

 

Target cells selected:

TargetCells-SELECTED.PNG

 

 

Possible result A:

SourceContentsApplied-SELECTED.PNG

 

Possible result B:

 

PossibleResult-B.PNG

 

FWIW: I think that something like that was already discussed years ago in the former InDesign Scripting Forum. With a solution. But I am not able to find the discussion again.

 

What I can offer for now is ExtendScript (JavaScript) code to discern the source selection from the target selection.

Also code that collects the unformatted content of the source and code to collect the target cells:

 

( function()
{
	// Get all open documents:
	var allOpenDocs = app.documents.everyItem().getElements();
	
	// My assumption
	// The target document is the one you clicked to the front in one of the layout windows:
	var targetDoc = app.documents[0];

	// In that document you did a selection of table cells.
	// Either the whole table, all cells are selected, OR only some cells are selected:
	var targetSelection = targetDoc.selection[0];
	
	// Source selection is not known, we have to detect it:
	var sourceSelection;

	// Loop all documents but the top most with the target selection:
	for( var n=1; n<allOpenDocs.length; n++ )
	{
		// The least we can do is to check if there is a selection with length 1.
		// If the selection length is not 1 do nothing and continue the loop:
		if( allOpenDocs[n].selection.length != 1 ){ continue };
		
		// Next check if table cells are selected, when identified break the loop:
		if( allOpenDocs[n].selection[0].hasOwnProperty("cells") )
		{
			sourceSelection = allOpenDocs[n].selection[0] ;
			break;
		};
	};

	// No source selection found, alert and do nothing:
	if( sourceSelection == undefined ){ alert( "No target selection found. | SCRIPT " ); return };

	// All unformatted contents of the source is stored in an array:
	var sourceContentsArray = sourceSelection.cells.everyItem().contents;
	
	// We identified the target selection, made sure that cells are selected.
	// Store all selected cells in an array:
	var targetCells = targetSelection.cells.everyItem().getElements();
	
}() )

 

 

Regards,
Uwe Laubender

( ACP )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

Thanks Uwe,

 

I can live with always having my target document the active one, that's usually what I do anyway. 

For the question of how do I deal with mapping the cells, I check if I have the same number of rows and columns, if it's not the same, then the script stops and tells me the difference between the two. So either I selected the wrong range or something funny is happening. So your results A and B are moot in my case.

 

Good idea to check if the document has a selection, assuming that the target document is always the active one, that should work. Now I have to figure out how to do it in Applescript;-) Thanks for the idea!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 26, 2020 Feb 26, 2020

Copy link to clipboard

Copied

You can refer to documents by name. In JavaScript that would something like

 

app.documents.item ('document1.indd')

app.documents.item ('document2.indd')

 

and you can assign these to variables for easy reference:

 

var doc1 = app.documents.item ('document1.indd');

var doc2 = app.documents.item ('document2.indd');

 

Something similar should be possible in AppleScript.

 

P.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 27, 2020 Feb 27, 2020

Copy link to clipboard

Copied

Hi,

 

In AppleScript it would be some thing like

 

tell application "Adobe InDesign 2020"

    set doc1 to every document whose title is "Untitled-1"

end tell

 

Regards

 

Malcolm

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 27, 2020 Feb 27, 2020

Copy link to clipboard

Copied

Could you add a label to the documents when they are created, so they can be reliably id’d? So:

 

tell application id "com.adobe.indesign"
	set label of active document to "Unformatted"
end tell
tell application id "com.adobe.indesign"
	set label of active document to "Formatted"
end tell

Then you could have any number of documents open and bring the two documents to the front or make them variables

tell application id "com.adobe.indesign"
	set active document to item 1 of every document whose label is "Formatted"
	set active document to item 1 of every document whose label is "Unformatted"
end tell

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 27, 2020 Feb 27, 2020

Copy link to clipboard

Copied

Great idea Ray!

I'm not setting the label on the creation of the document, but I can run a small script to apply that label, which won't change anyway and will be sticky so I would have to apply it just once for the source document since it will be used for multiple formatted documents.

 

I'm just stock with the variable though. In your exemple,

set formattedDoc to item 1 of every document whose label is "Formatted"

I get

{Document ID 1 of application "Adobe InDesign CC 2019"}

if I do

set formattedDoc to active document

I get

Document ID 1 of application "Adobe InDesign CC 2019"

 

Which I can then reference with selections and all that good stuff. I know this is basic stuff but for the life of me, how do I get the content of item 1 not as a list?

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Feb 27, 2020 Feb 27, 2020

Copy link to clipboard

Copied

I think you are looking for the index, not the id

 

 

 

tell application id "com.adobe.indesign"
	set formatDoc to item 1 of every document whose label is "Formatted"
	
	get formatDoc
	--a single item list: {document id 2 of application "Adobe InDesign 2020"}
	
	get item 1 of formatDoc
	--document id 2 of application "Adobe InDesign 2020"
	
	get id of item 1 of formatDoc
	--returns the document’s id, which is not its display order, for that you need index
	
	get index of item 1 of formatDoc
	--the index is the display order, the active document‘s index is 1
	
end tell

 

 

 

 

 


tell application id "com.adobe.indesign"
	
	set formatDoc to item 1 of every document whose label is "Formatted"
	set i to index of item 1 of formatDoc
	
	--these are equivalent
	get properties of document i
	get properties of item 1 of formatDoc
	
end tell

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Feb 28, 2020 Feb 28, 2020

Copy link to clipboard

Copied

LATEST

Thanks to everyone!

 

I found the solution, don't know if it was the right way to do it, but it works and I worked with the script all day yesterday and it was fantastic!

 

For those interested, here it is.

--Table Data replace
--Use this script to replace data in a table already designed.
--This script requires two documents open, before running this script, 
--run the 02-set label formatted on the document with the formatted table and 02-set label unformatted on the document with the unformatted table.


tell application id "com.adobe.indesign"
	if (count of documents) is less than 2 then
		beep
		activate
		display dialog "This script requires two documents open, please open another document." buttons {"OK"}
		return
	end if
	try
		set formattedDoc to item 1 of every document whose label is "Formatted"
		set myFormattedDoc to item 1 of formattedDoc
	on error
		beep
		activate
		display dialog "This script requires two documents open, one with a Formatted Label, please run the script 02-set label formatted." buttons {"OK"}
		return
	end try
	
	
	try
		set unformattedDoc to item 1 of every document whose label is "Unformatted"
		set myUnformattedDoc to item 1 of unformattedDoc
		
	on error
		beep
		activate
		display dialog "This script requires two documents open, one with a Unformatted Label, please run the script 02-set label unformatted." buttons {"OK"}
		return
	end try
	
	
	set columnCount1 to count of columns of selection of myFormattedDoc
	set rowCount1 to count of rows of selection of myFormattedDoc
	set columnCount2 to count of columns of selection of myUnformattedDoc
	set rowCount2 to count of rows of selection of myUnformattedDoc
	
	
	if (rowCount1 is not equal to rowCount2) then
		beep
		activate
		display dialog "The number of rows don't match." & return & " You have " & rowCount1 & " rows for the document formatted vs " & return & rowCount2 & " rows for the document unformatted." buttons {"OK"}
		return
	else if (columnCount1 is not equal to columnCount2) then
		beep
		activate
		display dialog "The number of columns don't match." & return & " You have " & columnCount1 & " columns for the document in formatted vs " & return & columnCount2 & " columns for the document unformatted." buttons {"OK"}
		return
	end if
	
	set ourData to contents of selection of myUnformattedDoc
	set contents of selection of myFormattedDoc to ourData
end tell

The only thing still not working is if I have merged cells in the formatted table, then the number of column or row don't match and it gives me the error. But other then that, all is good. Thanks again guys!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines