Excel 2008 - Howto copy ranges from several files to new workbook?

I am new to applescript and am in need of help!

I need to copy a selected range from several different workbooks to a new workbook. The ranges need to be pasted in the same sheet, side by side in consecutive columns.

Also, is it possible to copy the file name for each selected range and paste it on the first cell of each column in the new workbook?

I have so far been able to come up with the following code (some of it borrowed from a code by StefanK):

set sourceFiles to (choose file with prompt "Choose source files" of type {"XLS6", "XLS7", "XLS8", "XLS", "TXT"} with multiple selections allowed without invisibles)

tell application "Microsoft Excel"
	activate
	set targetBook to make new workbook
	repeat with oneFile in sourceFiles
		set sourceBook to open workbook workbook file name (oneFile as text)
		repeat with copy_range in (get range "b587:b2614" of active sheet of sourceBook)
			if value of used range of copy_range is not "" then
				copy range (copy_range of active sheet of sourceBook)
				tell sheet "Sheet1" of targetBook
					paste worksheet destination last sheet of targetBook
				end tell
			end if
		end repeat
		close sourceBook saving no
	end repeat
end tell

I run it (with no errors popping up). It looks like it is copying the selected range, however nothing is pasted in the new workbook!

Any help would be greatly appreciated!

Model: Macbook 2.4 GHz 2 GB
AppleScript: 2.0
Browser: Firefox 2.0.0.14
Operating System: Mac OS X (10.5)

Hi,

if you have less than 26 source files, try this


property firstRow : 587
property lastRow : 2614

set sourceFiles to (choose file with prompt "Choose source files" of type {"XLS6", "XLS7", "XLS8", "XLS", "TXT"} with multiple selections allowed without invisibles)
set firstUnusedColumn to 1
tell application "Microsoft Excel"
	-- activate
	set targetBook to make new workbook
	repeat with oneFile in sourceFiles
		set sourceBook to open workbook workbook file name (oneFile as text)
		set thisName to name of sourceBook
		set copy_range to range ("b" & firstRow & ":b" & lastRow) of active sheet of sourceBook
		if value of used range of copy_range is not "" then
			tell sheet 1 of targetBook
				set value of cell 1 of column firstUnusedColumn to thisName
				set currentColumn to ASCII character (64 + firstUnusedColumn)
				set destinationRange to range (currentColumn & "2:" & currentColumn & (lastRow - firstRow + 2))
			end tell
			copy range copy_range destination destinationRange
			set firstUnusedColumn to firstUnusedColumn + 1
		end if
		close sourceBook saving no
	end repeat
end tell

if you have more than 26, you have to calculate the double letters of the columns (AA, AB etc.),
unless there is an easier way to define a range.

Hi StefanK,

Thank you very much for the help! The script works flawlessly! It does exactly what I needed. But as you guessed I do have more than 26 files. And being new to both Macs and applescript I not up to date on this language to understand how to “calculate the double letters of the columns (AA, AB etc.),” as you mentioned in your post!

I will play with it today and see if I can solve this puzzle!

Many thanks and cheers!

If you look in Excel at the columns, the next column after letter Z is double letter AA, then AB etc.
Excel expects a range in the format A1:A15, so you have to coerce the column number of firstUnusedColumn to the letter equivalent.
I’m sure, there is a easier way to copy and paste without this range format, but this also does it


property firstRow : 587
property lastRow : 2614

set sourceFiles to (choose file with prompt "Choose source files" of type {"XLS6", "XLS7", "XLS8", "XLS", "TXT"} with multiple selections allowed without invisibles)
set firstUnusedColumn to 1
tell application "Microsoft Excel"
	-- activate
	set targetBook to make new workbook
	repeat with oneFile in sourceFiles
		set sourceBook to open workbook workbook file name (oneFile as text)
		set thisName to name of sourceBook
		set copy_range to range ("b" & firstRow & ":b" & lastRow) of active sheet of sourceBook
		if value of used range of copy_range is not "" then
			tell sheet 1 of targetBook
				set value of cell 1 of column firstUnusedColumn to thisName
				set currentColumn to CalcColumnLetter(firstUnusedColumn)
				set destinationRange to range (currentColumn & "2:" & currentColumn & (lastRow - firstRow + 2))
			end tell
			copy range copy_range destination destinationRange
			set firstUnusedColumn to firstUnusedColumn + 1
		end if
		close sourceBook saving no
	end repeat
end tell

on CalcColumnLetter(theCol)
	set theCol to theCol - 1
	set H to theCol div 26
	if H > 0 then
		return (ASCII character (64 + H)) & (ASCII character (64 + (theCol mod 26) + 1))
	else
		return (ASCII character (64 + (theCol mod 26) + 1))
	end if
end CalcColumnLetter

Stefan,

Once again, thank you for your help!

I tried to run the updated version of the script, allowing more than 26 columns. However, I think there is a an error in the script, that I am too newbie to understand!

When I run it the following error message is displayed “Microsoft Excel got an error: sheet 1 of workbook “Sheet1” doesn’t understand the CalcColumnLetter message.”. And the following part of the script is highlighted “CalcColumnLetter(firstUnusedColumn)”.

I tried playing with the command “get offset” to paste the next column to the right of the current column, this script is able to copy only the name of the file to the first cell, and for some unknown (to me) reason, not the content of the selected range:

property firstRow : 587
property lastRow : 2614

set sourceFiles to (choose file with prompt "Choose source files" of type {"XLS6", "XLS7", "XLS8", "XLS", "TXT"} with multiple selections allowed without invisibles)

set firstUnusedColumn to 1

tell application "Microsoft Excel"
	activate
	set targetBook to make new workbook
	repeat with oneFile in sourceFiles
		set sourceBook to open workbook workbook file name (oneFile as text)
		set thisName to name of sourceBook
		set copy_range to range ("b" & firstRow & ":b" & lastRow) of active sheet of sourceBook
		if value of used range of copy_range is not "" then
			tell sheet 1 of targetBook
				set value of cell 1 of column firstUnusedColumn to thisName
				set destinationRange to (get offset range "a2" column offset 1)
			end tell
			copy range copy_range destination destinationRange
			set firstUnusedColumn to firstUnusedColumn + 1
		end if
		close sourceBook saving no
	end repeat
end tell

I am sorry to bother you so much with such a simple problem, but to beginner it is a challenging and fun problem!

Thank you once again!

Cheers

Sorry, I forgot the keyword my, because the handler call is within an application tell block


.
 set currentColumn to my CalcColumnLetter(firstUnusedColumn)
.

Edit:
PS:

Thanks, Jacques, for posting the simple way to retrieve the range address of a cell

Thank you all very much for the help! Thank you Stefan for all the effort in helping out with this code, your last correction did the trick! And thank you Jacques for another way to getting to the same answer! Both scripts work flawlessly, and will help me get started with scripting!

Cheers,

Eduardo