robust_excel_ole 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/README.rdoc +73 -26
  2. data/README_detail.rdoc +92 -27
  3. data/examples/edit_sheets/example_access_sheets_and_cells.rb +3 -3
  4. data/examples/edit_sheets/example_concating.rb +12 -12
  5. data/examples/edit_sheets/example_copying.rb +47 -0
  6. data/examples/edit_sheets/example_expanding.rb +17 -26
  7. data/examples/edit_sheets/example_naming.rb +13 -10
  8. data/examples/edit_sheets/example_ranges.rb +2 -2
  9. data/examples/edit_sheets/example_saving.rb +8 -14
  10. data/examples/open_save_close/example_control_to_excel.rb +1 -1
  11. data/examples/open_save_close/example_if_obstructed_closeifsaved.rb +3 -3
  12. data/examples/open_save_close/example_if_obstructed_save.rb +3 -3
  13. data/examples/open_save_close/example_if_unsaved_accept.rb +1 -1
  14. data/examples/open_save_close/example_if_unsaved_forget.rb +4 -4
  15. data/examples/open_save_close/example_if_unsaved_forget_more.rb +5 -5
  16. data/examples/open_save_close/example_read_only.rb +1 -1
  17. data/examples/open_save_close/example_rename_cells.rb +1 -13
  18. data/examples/open_save_close/example_simple.rb +1 -1
  19. data/examples/open_save_close/example_unobtrusively.rb +3 -3
  20. data/lib/robust_excel_ole.rb +81 -2
  21. data/lib/robust_excel_ole/book.rb +171 -118
  22. data/lib/robust_excel_ole/{book_store.rb → bookstore.rb} +2 -2
  23. data/lib/robust_excel_ole/excel.rb +153 -24
  24. data/lib/robust_excel_ole/range.rb +2 -2
  25. data/lib/robust_excel_ole/sheet.rb +84 -35
  26. data/lib/robust_excel_ole/version.rb +1 -1
  27. data/reo.bat +3 -0
  28. data/spec/book_close_spec.rb +179 -0
  29. data/spec/book_misc_spec.rb +365 -0
  30. data/spec/book_open_spec.rb +793 -0
  31. data/spec/book_save_spec.rb +257 -0
  32. data/spec/book_sheet_spec.rb +160 -0
  33. data/spec/book_spec.rb +145 -1533
  34. data/spec/book_subclass_spec.rb +50 -0
  35. data/spec/book_unobtr_spec.rb +950 -0
  36. data/spec/{book_store_spec.rb → bookstore_spec.rb} +5 -5
  37. data/spec/cell_spec.rb +6 -6
  38. data/spec/data/{more_workbook.xls → another_workbook.xls} +0 -0
  39. data/spec/data/different_workbook.xls +0 -0
  40. data/spec/data/workbook.xls +0 -0
  41. data/spec/data/workbook.xlsm +0 -0
  42. data/spec/data/workbook.xlsx +0 -0
  43. data/spec/data/workbook_linked.xlsm +0 -0
  44. data/spec/data/workbook_linked_sub.xlsm +0 -0
  45. data/spec/excel_spec.rb +204 -5
  46. data/spec/range_spec.rb +6 -6
  47. data/spec/sheet_spec.rb +122 -34
  48. metadata +18 -8
  49. data/spec/data/workbook_connected_sub.xlsm +0 -0
@@ -0,0 +1,47 @@
1
+ # example_copying.rb:
2
+ # each named cell is to be copied into another sheet
3
+ # unnamed cells shall not be copied
4
+ # if a sheet does not contain any named cell, then the sheet shall not be copied
5
+
6
+ require 'rubygems'
7
+ #require 'robust_excel_ole'
8
+ require File.join(File.dirname(__FILE__), '../../lib/robust_excel_ole')
9
+ require "fileutils"
10
+
11
+ include RobustExcelOle
12
+
13
+ begin
14
+ dir = "C:/data"
15
+ workbook_name = 'another_workbook.xls'
16
+ ws = workbook_name.split(".")
17
+ base_name = ws[0,ws.length-1].join(".")
18
+ suffix = ws.last
19
+ file_name = dir + "/" + workbook_name
20
+ extended_file_name = dir + "/" + base_name + "_copied" + "." + suffix
21
+ FileUtils.copy file_name, extended_file_name
22
+
23
+ Book.unobtrusively(extended_file_name) do |book|
24
+ book.extend Enumerable
25
+ sheet_names = book.map { |sheet| sheet.name }
26
+
27
+ book.each do |sheet|
28
+ new_sheet = book.add_sheet
29
+ contains_named_cells = false
30
+ sheet.each do |cell|
31
+ full_name = cell.Name.Name rescue nil
32
+ if full_name
33
+ sheet_name, short_name = full_name.split("!")
34
+ cell_name = short_name ? short_name : sheet_name
35
+ contains_named_cells = true
36
+ new_sheet[cell.Row, cell.Column].Value = cell.Value
37
+ new_sheet.set_name(cell_name, cell.Row,cell.Column)
38
+ end
39
+ end
40
+ new_sheet.Delete() unless contains_named_cells
41
+ end
42
+
43
+ sheet_names.each do |sheet_name|
44
+ book[sheet_name].Delete()
45
+ end
46
+ end
47
+ end
@@ -6,52 +6,43 @@
6
6
  # in addition to that, the cell B2 shall be named "name" and get the sheet name as its value
7
7
 
8
8
  require 'rubygems'
9
- require 'robust_excel_ole'
9
+ #require 'robust_excel_ole'
10
+ require File.join(File.dirname(__FILE__), '../../lib/robust_excel_ole')
10
11
  require "fileutils"
11
12
 
12
13
  include RobustExcelOle
13
14
 
14
15
  begin
15
- Excel.close_all
16
16
  dir = "C:/data"
17
17
  workbook_name = 'workbook_named_concat.xls'
18
- base_name = workbook_name[0,workbook_name.rindex('.')]
19
- suffix = workbook_name[workbook_name.rindex('.')+1,workbook_name.length]
18
+ ws = workbook_name.split(".")
19
+ base_name = ws[0,ws.length-1].join(".")
20
+ suffix = ws.last
20
21
  file_name = dir + "/" + workbook_name
21
22
  extended_file_name = dir + "/" + base_name + "_expanded" + "." + suffix
22
- book_orig = Book.open(file_name)
23
- book_orig.save_as(extended_file_name, :if_exists => :overwrite)
24
- book_orig.close
25
- sheet_names = []
23
+ FileUtils.copy file_name, extended_file_name
24
+
26
25
  Book.unobtrusively(extended_file_name) do |book|
27
- book.each do |sheet|
28
- sheet_names << sheet.name
29
- end
26
+ book.extend Enumerable
27
+ sheet_names = book.map { |sheet| sheet.name }
28
+
30
29
  book.Names.each do |excel_name|
31
30
  full_name = excel_name.Name
32
31
  sheet_name, short_name = full_name.split("!")
33
32
  sheet = excel_name.RefersToRange.Worksheet
34
- sheet_name = short_name ? short_name : full_name
35
- begin
36
- sheet_new = book.add_sheet(sheet, :as => sheet_name)
37
- rescue ExcelErrorSheet => msg
38
- if msg.message == "sheet name already exists"
39
- sheet_new = book.add_sheet(sheet, :as => (sheet_name+sheet.name))
40
- else
41
- puts msg.message
42
- end
43
- end
44
- sheet_new.Names.Add("Name" => "name", "RefersTo" => "=" + "$B$2")
45
- sheet_new[1,1].Value = sheet_name
33
+ sheet_name = short_name ? short_name : sheet_name
34
+ sheet_new = book.add_sheet sheet
46
35
  begin
47
36
  sheet_new.name = sheet_name
48
- rescue
49
- sheet_new.name = (sheet_name+sheet.name)
37
+ rescue ExcelErrorSheet => msg
38
+ sheet_new.name = sheet_name + sheet.name if msg.message == "sheet name already exists"
50
39
  end
40
+ sheet_new.set_name("name", 2, 2)
41
+ sheet_new["name"] = sheet_name
51
42
  end
43
+
52
44
  sheet_names.each do |sheet_name|
53
45
  book[sheet_name].Delete()
54
46
  end
55
47
  end
56
- Excel.close_all
57
48
  end
@@ -4,29 +4,32 @@
4
4
  # the new workbook's name is extended by the suffix "_named"
5
5
 
6
6
  require 'rubygems'
7
- require 'robust_excel_ole'
7
+ #require 'robust_excel_ole'
8
+ require File.join(File.dirname(__FILE__), '../../lib/robust_excel_ole')
8
9
  require "fileutils"
9
10
 
10
11
  include RobustExcelOle
11
12
 
12
13
  begin
13
- Excel.close_all
14
14
  dir = "C:/data"
15
15
  workbook_name = 'workbook.xls'
16
- base_name = workbook_name[0,workbook_name.rindex('.')]
17
- suffix = workbook_name[workbook_name.rindex('.')+1,workbook_name.length]
16
+ ws = workbook_name.split(".")
17
+ base_name = ws[0,ws.length-1].join(".")
18
+ suffix = ws.last
19
+ #base_name = File.basename(workbook_name, ".xls*")
20
+ #workbook_name =~ /^(.*)\.[^.]$/; base_name = $1
21
+ #base_name = workbook_name.sub(/^.*(\.[^.])$/; '')
22
+ #base_name = workbook_name[0,workbook_name.rindex('.')]
23
+ #suffix = workbook_name[workbook_name.rindex('.')+1,workbook_name.length]
18
24
  file_name = dir + "/" + workbook_name
19
25
  extended_file_name = dir + "/" + base_name + "_named" + "." + suffix
20
- book_orig = Book.open(file_name)
21
- book_orig.save_as(extended_file_name, :if_exists => :overwrite)
22
- book_orig.close
26
+ FileUtils.copy file_name, extended_file_name
27
+
23
28
  Book.unobtrusively(extended_file_name) do |book|
24
29
  book.each do |sheet|
25
30
  sheet.each do |cell_orig|
26
31
  contents = cell_orig.Value
27
- if contents && contents.class == String
28
- sheet.Names.Add("Name" => contents, "RefersTo" => "=" + cell_orig.Address)
29
- end
32
+ sheet.set_name(contents, cell_orig.Row, cell_orig.Column) if contents && contents.is_a?(String)
30
33
  end
31
34
  end
32
35
  end
@@ -15,8 +15,8 @@ begin
15
15
  File.delete simple_save_file rescue nil
16
16
  book = Book.open(simple_file) # open a book
17
17
  sheet = book['Sheet1'] # access a sheet via the name
18
- row_r = sheet.row_range(0) # access the whole range of the first row
19
- col_r = sheet.col_range(0, 0..1) # access the first two cells of the range of the first column
18
+ row_r = sheet.row_range(1) # access the whole range of the first row
19
+ col_r = sheet.col_range(1, 1..2) # access the first two cells of the range of the first column
20
20
  cell = col_r[0] # access the first cell of these cells
21
21
  puts "row range of 1st row: #{row_r.values}" # puts the values of the first row
22
22
  puts "1st and 2nd cell of the 1st column : #{col_r.values}" # and the first two cells of the first column
@@ -2,27 +2,25 @@
2
2
  # save the sheets of a book as separate workbooks
3
3
 
4
4
  require 'rubygems'
5
- require 'robust_excel_ole'
5
+ #require 'robust_excel_ole'
6
+ require File.join(File.dirname(__FILE__), '../../lib/robust_excel_ole')
6
7
  require "fileutils"
7
8
 
8
9
  include RobustExcelOle
9
10
 
10
11
  begin
11
- Excel.close_all
12
+
12
13
  dir = "C:/data"
13
- workbook_name = 'workbook.xls'
14
- base_name = workbook_name[0,workbook_name.rindex('.')]
15
- suffix = workbook_name[workbook_name.rindex('.')+1,workbook_name.length]
14
+ workbook_name = 'workbook_named.xls'
15
+ ws = workbook_name.split(".")
16
+ base_name = ws[0,ws.length-1].join(".")
17
+ suffix = ws.last
16
18
  file_name = dir + "/" + workbook_name
19
+
17
20
  Book.unobtrusively(file_name) do |book_orig|
18
21
  book_orig.each do |sheet_orig|
19
22
  file_sheet_name = dir + "/" + base_name + "_" + sheet_orig.name + "." + suffix
20
23
  Excel.current.generate_workbook(file_sheet_name)
21
- end
22
- end
23
- Book.unobtrusively(file_name) do |book_orig|
24
- book_orig.each do |sheet_orig|
25
- file_sheet_name = dir + "/" + base_name + "_" + sheet_orig.name + "." + suffix
26
24
  # delete all existing sheets, and add the sheet
27
25
  book = Book.open(file_sheet_name)
28
26
  book.add_sheet sheet_orig
@@ -33,12 +31,8 @@ begin
33
31
  # alternative: delete all other sheets
34
32
  #book = Book.open(file_sheet_name, :force_excel => :new, :visible => true)
35
33
  #book.each do |sheet|
36
- # p "sheet.Name: #{sheet.Name}"
37
34
  # book[sheet.Name].Delete() unless sheet.Name == sheet_orig.Name
38
35
  #end
39
- #sleep 3
40
- #book.save_as(file_sheet_name, :if_exists => :overwrite)
41
- #book.close
42
36
  end
43
37
  end
44
38
  end
@@ -15,7 +15,7 @@ begin
15
15
  book.excel.visible = true # make current Excel visible
16
16
  sleep 1
17
17
  sheet = book[0] # access a sheet
18
- sheet[0,0] = sheet[0,0].Value == "simple" ? "complex" : "simple" # change a cell
18
+ sheet[1,1] = sheet[1,1].Value == "simple" ? "complex" : "simple" # change a cell
19
19
  sleep 1
20
20
  begin
21
21
  new_book = Book.open(file_name, :if_unsaved => :alert) # open another book with the same file name
@@ -15,8 +15,8 @@ begin
15
15
  book = Book.open(file_name, :visible => true) # open a book, make Excel visible
16
16
  sleep 1
17
17
  sheet = book[0]
18
- first_cell = sheet[0,0].Value # access a sheet
19
- sheet[0,0] = first_cell == "simple" ? "complex" : "simple" # change a cell
18
+ first_cell = sheet[1,1].Value # access a sheet
19
+ sheet[1,1] = first_cell == "simple" ? "complex" : "simple" # change a cell
20
20
  sleep 1
21
21
  begin
22
22
  new_book = Book.open(other_file_name, :if_obstructed => :close_if_saved) # raises an exception since the file is not saved
@@ -27,7 +27,7 @@ begin
27
27
  new_book = Book.open(file_name, :if_obstructed => :close_if_saved) # open the new book, close the saved book
28
28
  sleep 1
29
29
  new_sheet = new_book[0]
30
- new_first_cell = new_sheet[0,0].Value
30
+ new_first_cell = new_sheet[1,1].Value
31
31
  puts "the old book was saved" unless new_first_cell == first_cell
32
32
  new_book.close # close the books
33
33
  ensure
@@ -15,15 +15,15 @@ begin
15
15
  book = Book.open(file_name, :visible => true) # open a book, make Excel visible
16
16
  sleep 1
17
17
  sheet = book[0]
18
- first_cell = sheet[0,0].value # access a sheet
19
- sheet[0,0] = first_cell == "simple" ? "complex" : "simple" # change a cell
18
+ first_cell = sheet[1,1].value # access a sheet
19
+ sheet[1,1] = first_cell == "simple" ? "complex" : "simple" # change a cell
20
20
  sleep 1
21
21
  new_book = Book.open(other_file_name, :if_obstructed => :save) # open a book with the same file name in a different path
22
22
  sleep 1 #save the old book, close it, before
23
23
  old_book = Book.open(file_name, :if_obstructed => :forget ,:visible => true) # open the old book
24
24
  sleep 1
25
25
  old_sheet = old_book[0]
26
- old_first_cell = old_sheet[0,0].value
26
+ old_first_cell = old_sheet[1,1].value
27
27
  puts "the old book was saved" unless old_first_cell == first_cell
28
28
  new_book.close # close the books
29
29
  old_book.close
@@ -13,7 +13,7 @@ begin
13
13
  file_name = dir + 'workbook.xls'
14
14
  book = Book.open(file_name) # open a book
15
15
  sheet = book[0] # access a sheet
16
- sheet[0,0] = sheet[0,0].value == "simple" ? "complex" : "simple" # change a cell
16
+ sheet[1,1] = sheet[1,1].value == "simple" ? "complex" : "simple" # change a cell
17
17
  begin
18
18
  new_book = Book.open(file_name) # open another book with the same file name
19
19
  rescue ExcelErrorOpen => msg # by default: raises an exception:
@@ -15,17 +15,17 @@ begin
15
15
  book.excel.visible = true # make current Excel visible
16
16
  sleep 1
17
17
  sheet = book[0] # access a sheet
18
- first_cell = sheet[0,0].value
19
- sheet[0,0] = first_cell == "simple" ? "complex" : "simple" # change a cell
18
+ first_cell = sheet[1,1].value
19
+ sheet[1,1] = first_cell == "simple" ? "complex" : "simple" # change a cell
20
20
  sleep 1
21
21
  new_book = Book.open(file_name, :if_unsaved => :forget) # open another book with the same file name
22
22
  # and close the unsaved book without saving it
23
23
  sheet_new_book = new_book[0]
24
- if (not book.alive?) && new_book.alive? && sheet_new_book[0,0].value == first_cell then # check whether the unsaved book
24
+ if (not book.alive?) && new_book.alive? && sheet_new_book[1,1].value == first_cell then # check whether the unsaved book
25
25
  puts "open with :if_unsaved => :forget : the unsaved book is closed and not saved." # is closed and was not saved
26
26
  end
27
27
  sleep 1
28
- sheet_new_book[0,0] = sheet_new_book[0,0].value == "simple" ? "complex" : "simple" # change a cell
28
+ sheet_new_book[1,1] = sheet_new_book[1,1].value == "simple" ? "complex" : "simple" # change a cell
29
29
  # open another book in a new Excel application, and make Excel visible, leaving the unsaved book open
30
30
  another_book = Book.open(file_name, :if_unsaved => :new_excel, :visible => true)
31
31
  sleep 3 # leaving the unsaved book open
@@ -15,21 +15,21 @@ begin
15
15
  book.excel.visible = true # make current Excel visible
16
16
  sleep
17
17
  sheet = book[0] # access a sheet
18
- first_cell = sheet[0,0].value
19
- sheet[0,0] = first_cell == "simple" ? "complex" : "simple" # change a cell
18
+ first_cell = sheet[1,1].value
19
+ sheet[1,1] = first_cell == "simple" ? "complex" : "simple" # change a cell
20
20
  sleep 1
21
21
  new_book = Book.open(file_name, :if_unsaved => :new_excel, :visible => true) # open another book with the same file name in a new Excel
22
22
  sheet_new_book = new_book[0]
23
- if (not book.alive?) && new_book.alive? && sheet_new_book[0,0].value == first_cell then # check whether the unsaved book
23
+ if (not book.alive?) && new_book.alive? && sheet_new_book[1,1].value == first_cell then # check whether the unsaved book
24
24
  puts "open with :if_unsaved => :forget : the unsaved book is closed and not saved." # is closed and was not saved
25
25
  end
26
26
  sleep 1
27
- sheet_new_book[0,0] = sheet_new_book[0,0].value == "simple" ? "complex" : "simple" # change a cell
27
+ sheet_new_book[1,1] = sheet_new_book[1,1].value == "simple" ? "complex" : "simple" # change a cell
28
28
  # open another book in the running Excel application, and make Excel visible, closing the unsaved book
29
29
  another_book = Book.open(file_name, :if_unsaved => :forget, :visible => true)
30
30
  sleep 1
31
31
  sheet_another_book = another_book[0]
32
- sheet_another_book[0,0] = sheet_another_book[0,0].value == "simple" ? "complex" : "simple" # change a cell
32
+ sheet_another_book[1,1] = sheet_another_book[1,1].value == "simple" ? "complex" : "simple" # change a cell
33
33
  another_book.close(:if_unsaved => :forget ) # close the last book without saving it.
34
34
  book.close(:if_unsaved => :save) # close the first book and save it before
35
35
  ensure
@@ -14,7 +14,7 @@ begin
14
14
  book = Book.open(file_name, :read_only => true, :visible => true) # open a book with read_only and make Excel visible
15
15
  sheet = book[0] # access a sheet
16
16
  sleep 1
17
- sheet[0,0] = sheet[0,0].value == "simple" ? "complex" : "simple" # change a cell
17
+ sheet[1,1] = sheet[1,1].value == "simple" ? "complex" : "simple" # change a cell
18
18
  sleep 1
19
19
  begin
20
20
  book.save # simple save.
@@ -14,12 +14,10 @@ begin
14
14
  book = Book.open(file_name) # open a book. default: :read_only => false
15
15
  book.excel.visible = true # make current Excel visible
16
16
  sheet = book[0]
17
- #sheet.Names.Add("Wert","$A$1"
18
-
19
17
  workbook = book.workbook
20
18
  fullname = workbook.Fullname
21
19
  puts "fullname: #{fullname}"
22
- workbook.Names.Add("a_name", "=$A$1") # rename cell A1 to "a_name"
20
+ sheet.add_name(1,1,"a_name") # rename cell A1 to "a_name"
23
21
  number = workbook.Names.Count
24
22
  puts "number of name objects :#{number}"
25
23
  name_object = workbook.Names("a_name")
@@ -48,17 +46,7 @@ begin
48
46
  new_name_object.Visible = false
49
47
  puts "visible: #{new_name_object.Visible}"
50
48
  sleep 2
51
-
52
- # to do:
53
- # read, write contents of the cell (under the old name)
54
- # read, write contents in the cell under the new name
55
-
56
- #sheet.Cells
57
- # sheet[0,0].value
58
- # Worksheets("sheet1").Cells
59
-
60
49
  new_name_object.Delete
61
-
62
50
  sleep 2
63
51
  book.close(:if_unsaved => :forget) # close the book
64
52
 
@@ -16,7 +16,7 @@ begin
16
16
  book.excel.visible = true # make current Excel visible
17
17
  sheet = book[0] # access a sheet
18
18
  sleep 1
19
- sheet[0,0] = sheet[0,0].value == "simple" ? "complex" : "simple" # change a cell
19
+ sheet[1,1] = sheet[1,1].value == "simple" ? "complex" : "simple" # change a cell
20
20
  sleep 1
21
21
  book.save # simple save
22
22
  begin
@@ -12,14 +12,14 @@ begin
12
12
  simple_file = dir + 'workbook.xls'
13
13
  book = Book.open(simple_file, :visible => true) # open a book, make Excel visible
14
14
  old_sheet = book[0]
15
- p "1st cell: #{old_sheet[0,0].value}"
15
+ p "1st cell: #{old_sheet[1,1].value}"
16
16
  sleep 2
17
17
  Book.unobtrusively(simple_file) do |book| # modify the book and keep its status unchanged
18
18
  sheet = book[0]
19
- sheet[0,0] = sheet[0,0].value == "simple" ? "complex" : "simple"
19
+ sheet[1,1] = sheet[1,1].value == "simple" ? "complex" : "simple"
20
20
  end
21
21
  new_sheet = book[0]
22
- p "1st cell: #{new_sheet[0,0].value}"
22
+ p "1st cell: #{new_sheet[1,1].value}"
23
23
  p "book saved" if book.Saved
24
24
  book.close # close the book
25
25
  ensure
@@ -1,6 +1,6 @@
1
1
  require "win32ole"
2
2
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/excel')
3
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/book_store')
3
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/bookstore')
4
4
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/book')
5
5
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/sheet')
6
6
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/cell')
@@ -9,6 +9,8 @@ require File.join(File.dirname(__FILE__), 'robust_excel_ole/cygwin') if RUBY_PLA
9
9
  #+#require "robust_excel_ole/version"
10
10
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/version')
11
11
 
12
+ REO = RobustExcelOle
13
+
12
14
  module RobustExcelOle
13
15
 
14
16
  def absolute_path(file)
@@ -24,8 +26,85 @@ module RobustExcelOle
24
26
 
25
27
  module_function :absolute_path, :canonize
26
28
 
27
-
28
29
  class VBAMethodMissingError < RuntimeError # :nodoc: #
29
30
  end
30
31
 
31
32
  end
33
+
34
+ class Object
35
+ def excel
36
+ raise ExcelErrorOpen, "provided instance is neither an Excel nor a Book"
37
+ end
38
+
39
+ end
40
+
41
+ class ::String
42
+ def / path_part
43
+ if empty?
44
+ path_part
45
+ else
46
+ begin
47
+ File.join self, path_part
48
+ rescue TypeError
49
+ raise "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
50
+ end
51
+ end
52
+ end
53
+
54
+ # taken from http://apidock.com/rails/ActiveSupport/Inflector/underscore
55
+ def underscore
56
+ word = gsub('::', '/')
57
+ word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
58
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
59
+ word.tr!("-", "_")
60
+ word.downcase!
61
+ word
62
+ end
63
+
64
+ # taken from http://apidock.com/rails/ActiveSupport/Inflector/constantize
65
+ # File activesupport/lib/active_support/inflector/methods.rb, line 226
66
+ def constantize #(camel_cased_word)
67
+ names = self.split('::')
68
+
69
+ # Trigger a builtin NameError exception including the ill-formed constant in the message.
70
+ Object.const_get(self) if names.empty?
71
+
72
+ # Remove the first blank element in case of '::ClassName' notation.
73
+ names.shift if names.size > 1 && names.first.empty?
74
+
75
+ names.inject(Object) do |constant, name|
76
+ if constant == Object
77
+ constant.const_get(name)
78
+ else
79
+ candidate = constant.const_get(name)
80
+ next candidate if constant.const_defined?(name)
81
+ next candidate unless Object.const_defined?(name)
82
+
83
+ # Go down the ancestors to check it it's owned
84
+ # directly before we reach Object or the end of ancestors.
85
+ constant = constant.ancestors.inject do |const, ancestor|
86
+ break const if ancestor == Object
87
+ break ancestor if ancestor.const_defined?(name)
88
+ const
89
+ end
90
+
91
+ # owner is in Object, so raise
92
+ constant.const_get(name)
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ # taken from http://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Module.html#M000806
99
+ class Module
100
+ def parent_name
101
+ unless defined? @parent_name
102
+ @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
103
+ end
104
+ @parent_name
105
+ end
106
+ def parent
107
+ parent_name ? parent_name.constantize : Object
108
+ end
109
+ end
110
+