robust_excel_ole 1.25 → 1.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,10 @@ module RobustExcelOle
16
16
 
17
17
  alias ole_object ole_table
18
18
 
19
+ using FindAllIndicesRefinement
20
+ using StringRefinement
21
+ using ToReoRefinement
22
+
19
23
  # constructs a list object (or table).
20
24
  # @param [Variable] worksheet_or_listobject a worksheet or a list object
21
25
  # @param [Variable] table_name_or_number a table name or table number
@@ -124,7 +128,7 @@ module RobustExcelOle
124
128
  rescue WIN32OLERuntimeError
125
129
  raise TableError, "could not delete values"
126
130
  end
127
- end
131
+ end
128
132
 
129
133
  def method_missing(name, *args)
130
134
  name_str = name.to_s
@@ -351,7 +355,7 @@ module RobustExcelOle
351
355
  listrows = @ole_table.ListRows
352
356
  result = []
353
357
  (1..listrows.Count).each do |row_number|
354
- row_values(row_number).find_each_index(value).each do |col_number|
358
+ row_values(row_number).find_all_indices(value).each do |col_number|
355
359
  result << @ole_table.Application.Intersect(listrows.Item(row_number).Range,
356
360
  @ole_table.ListColumns.Item(col_number+1).Range).to_reo
357
361
  end
@@ -16,6 +16,7 @@ module RobustExcelOle
16
16
 
17
17
  alias ole_object ole_range
18
18
 
19
+ using ToReoRefinement
19
20
 
20
21
  def initialize(win32_range, worksheet = nil)
21
22
  @ole_range = win32_range
@@ -221,11 +222,14 @@ module RobustExcelOle
221
222
  to_s
222
223
  end
223
224
 
225
+ using ParentRefinement
226
+ using StringRefinement
227
+
224
228
  # @private
225
229
  def self.worksheet_class
226
230
  @worksheet_class ||= begin
227
231
  module_name = parent_name
228
- "#{module_name}::Worksheet".constantize
232
+ "#{module_name}::Worksheet".constantize
229
233
  rescue NameError => e
230
234
  Worksheet
231
235
  end
@@ -14,7 +14,7 @@ module RobustExcelOle
14
14
  # @param [Hash] opts the options
15
15
  # @option opts [Symbol] :default the default value that is provided if no contents could be returned
16
16
  # @return [Variant] the contents of a range with given name
17
- def namevalue_glob(name, opts = { :default => :__not_provided })
17
+ def namevalue_global(name, opts = { :default => :__not_provided })
18
18
  name_obj = begin
19
19
  name_object(name)
20
20
  rescue NameNotFound => msg
@@ -63,7 +63,7 @@ module RobustExcelOle
63
63
  # @param [String] name the name of a range
64
64
  # @param [Variant] value the contents of the range
65
65
  # @option opts [Symbol] :color the color of the range when set
66
- def set_namevalue_glob(name, value, opts = { })
66
+ def set_namevalue_global(name, value, opts = { })
67
67
  begin
68
68
  name_obj = begin
69
69
  name_object(name)
@@ -89,81 +89,14 @@ module RobustExcelOle
89
89
  end
90
90
  end
91
91
 
92
- # returns the contents of a range with a locally defined name
93
- # evaluates the formula if the contents is a formula
94
- # if the name could not be found or the range or value could not be determined,
95
- # then return default value, if provided, raise error otherwise
96
- # @param [String] name the name of a range
97
- # @param [Hash] opts the options
98
- # @option opts [Symbol] :default the default value that is provided if no contents could be returned
99
- # @return [Variant] the contents of a range with given name
100
- def namevalue(name, opts = { :default => :__not_provided })
101
- return namevalue_glob(name, opts) if self.is_a?(Workbook)
102
- begin
103
- ole_range = self.Range(name)
104
- rescue # WIN32OLERuntimeError, VBAMethodMissingError, Java::OrgRacobCom::ComFailException
105
- return opts[:default] unless opts[:default] == :__not_provided
106
- raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
107
- end
108
- begin
109
- worksheet = self if self.is_a?(Worksheet)
110
- #value = ole_range.Value
111
- value = if !::RANGES_JRUBY_BUG
112
- ole_range.Value
113
- else
114
- values = RobustExcelOle::Range.new(ole_range, worksheet).v
115
- (values.size==1 && values.first.size==1) ? values.first.first : values
116
- end
117
- rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
118
- return opts[:default] unless opts[:default] == :__not_provided
119
- raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect} in #{self.inspect}"
120
- end
121
- if value == -2146828288 + RobustExcelOle::XlErrName
122
- return opts[:default] unless opts[:default] == __not_provided
123
- raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}"
124
- end
125
- return opts[:default] unless (opts[:default] == :__not_provided) || value.nil?
126
- value
127
- end
128
-
129
- # assigns a value to a range given a locally defined name
130
- # @param [String] name the name of a range
131
- # @param [Variant] value the assigned value
132
- # @option opts [Symbol] :color the color of the cell when set
133
- def set_namevalue(name, value, opts = { })
134
- begin
135
- return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook)
136
- ole_range = self.Range(name)
137
- rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
138
- raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
139
- end
140
- begin
141
- ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
142
- if !::RANGES_JRUBY_BUG
143
- ole_range.Value = value
144
- else
145
- address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
146
- row, col = address_tool.as_integer_ranges(address_r1c1)
147
- row.each_with_index do |r,i|
148
- col.each_with_index do |c,j|
149
- ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:first) ? value[i][j] : value)
150
- end
151
- end
152
- end
153
- value
154
- rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
155
- raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}"
156
- end
157
- end
158
-
159
92
  # @private
160
93
  def nameval(name, opts = { :default => :__not_provided }) # :deprecated: #
161
- namevalue_glob(name, opts)
94
+ namevalue_global(name, opts)
162
95
  end
163
96
 
164
97
  # @private
165
98
  def set_nameval(name, value) # :deprecated: #
166
- set_namevalue_glob(name, value)
99
+ set_namevalue_global(name, value)
167
100
  end
168
101
 
169
102
  # @private
@@ -1,3 +1,3 @@
1
1
  module RobustExcelOle
2
- VERSION = "1.25"
2
+ VERSION = "1.30"
3
3
  end
@@ -11,14 +11,14 @@ module RobustExcelOle
11
11
 
12
12
  class Workbook < RangeOwners
13
13
 
14
- #include General
15
-
16
14
  attr_reader :ole_workbook
17
15
  attr_reader :excel
18
16
  attr_reader :stored_filename
19
17
 
20
18
  alias ole_object ole_workbook
21
19
 
20
+ using ToReoRefinement
21
+
22
22
  CORE_DEFAULT_OPEN_OPTS = {
23
23
  :default => {:excel => :current},
24
24
  :force => {},
@@ -42,7 +42,7 @@ module RobustExcelOle
42
42
 
43
43
 
44
44
  # opens a workbook.
45
- # @param [String] file_or_workbook a file name or WIN32OLE workbook
45
+ # @param [String,Pathname] file_or_workbook a file name (string or pathname) or WIN32OLE workbook
46
46
  # @param [Hash] opts the options
47
47
  # @option opts [Hash] :default or :d
48
48
  # @option opts [Hash] :force or :f
@@ -235,13 +235,12 @@ module RobustExcelOle
235
235
  raise ExcelREOError, "Excel is not alive" unless @excel && @excel.alive?
236
236
  end
237
237
 
238
-
239
238
  # @private
240
239
  def ensure_workbook(filename, options)
241
240
  set_was_open options, true
242
241
  return if (@ole_workbook && alive? && (options[:read_only].nil? || @ole_workbook.ReadOnly == options[:read_only]))
243
242
  set_was_open options, false
244
- if options[:if_unsaved]==:accept &&
243
+ if options[:if_unsaved]==:accept && alive? &&
245
244
  ((options[:read_only]==true && self.ReadOnly==false) || (options[:read_only]==false && self.ReadOnly==true))
246
245
  raise OptionInvalid, ":if_unsaved:accept and change of read-only mode is not possible"
247
246
  end
@@ -254,6 +253,8 @@ module RobustExcelOle
254
253
  if @ole_workbook && alive?
255
254
  set_was_open options, true
256
255
  manage_blocking_or_unsaved_workbook(filename,options)
256
+ if @ole_workbook.ReadOnly != options[:read_only]
257
+ end
257
258
  open_or_create_workbook(filename,options) if @ole_workbook.ReadOnly != options[:read_only]
258
259
  else
259
260
  if (excel_option.nil? || excel_option == :current) &&
@@ -270,7 +271,6 @@ module RobustExcelOle
270
271
  # applies options to workbook named with filename
271
272
  def apply_options(filename, options)
272
273
  # changing read-only mode
273
- #ensure_workbook(filename, options) if options[:read_only] && options[:read_only] != @ole_workbook.ReadOnly
274
274
  if (!options[:read_only].nil?) && options[:read_only] != @ole_workbook.ReadOnly
275
275
  ensure_workbook(filename, options)
276
276
  end
@@ -327,7 +327,7 @@ module RobustExcelOle
327
327
  def manage_blocking_or_unsaved_workbook(filename, options)
328
328
  filename = General.absolute_path(filename)
329
329
  filename = General.canonize(filename)
330
- previous_file = General.canonize(@ole_workbook.Fullname)
330
+ previous_file = General.canonize(@ole_workbook.Fullname.gsub('\\','/'))
331
331
  obstructed_by_other_book = (File.basename(filename) == File.basename(previous_file)) &&
332
332
  (File.dirname(filename) != File.dirname(previous_file))
333
333
  if obstructed_by_other_book
@@ -557,11 +557,13 @@ module RobustExcelOle
557
557
  # allows to read or modify a workbook such that its state remains unchanged
558
558
  # state comprises: open, saved, writable, visible, calculation mode, check compatibility
559
559
  # @param [String] file_or_workbook a file name or WIN32OLE workbook
560
- # @param [Hash] opts the options
561
- # @option opts [Variant] :if_closed :current (default), :new or an Excel instance
562
- # @option opts [Boolean] :read_only true/false (default), open the workbook in read-only/read-write modus (save changes)
563
- # @option opts [Boolean] :writable true (default)/false changes of the workbook shall be saved/not saved
560
+ # @param [Hash] opts the options
561
+ # @option opts [Boolean] :read_only true/false (default), force to open the workbook in read-only/read-write mode
562
+ # @option opts [Boolean] :writable true (default)/false changes of the workbook shall be saved/not saved,
563
+ # and the workbook is being opened in read-only/read-write mode by default
564
+ # (when the workbook was not open before)
564
565
  # @option opts [Boolean] :keep_open whether the workbook shall be kept open after unobtrusively opening (default: false)
566
+ # @option opts [Variant] :if_closed :current (default), :new or an Excel instance
565
567
  # @return [Workbook] a workbook
566
568
  def self.unobtrusively(file_or_workbook, opts = { }, &block)
567
569
  file = (file_or_workbook.is_a? WIN32OLE) ? file_or_workbook.Fullname.tr('\\','/') : file_or_workbook
@@ -591,20 +593,24 @@ module RobustExcelOle
591
593
  end
592
594
  open_opts = excel_opts.merge({:if_unsaved => :accept})
593
595
  begin
594
- open_opts[:was_open] = nil
596
+ open_opts[:was_open] = nil
595
597
  book = open(file, open_opts)
598
+ #book = open(file, :read_only => !opts[:writable]) if !opts[:writable].nil? && !open_opts[:was_open]
596
599
  was_visible = book.visible
597
600
  was_writable = book.writable
598
601
  was_saved = book.saved
599
602
  was_check_compatibility = book.check_compatibility
600
603
  was_calculation = book.excel.properties[:calculation]
604
+ #opts[:read_only] = !opts[:writable] unless (opts[:writable].nil? || open_opts[:was_open])
605
+ opts[:read_only] = !opts[:writable] unless (!opts[:read_only].nil? || opts[:writable].nil? || open_opts[:was_open])
601
606
  book.send :apply_options, file, opts
602
607
  yield book
603
608
  ensure
604
609
  if book && book.alive?
605
610
  do_not_write = opts[:read_only] || opts[:writable]==false
606
611
  book.save unless book.saved || do_not_write || !book.writable
607
- if (opts[:read_only] && was_writable) || (!opts[:read_only] && !was_writable)
612
+ #if opts[:writable].nil? && opts[:was_open] &&
613
+ if ((opts[:read_only] && was_writable) || (!opts[:read_only] && !was_writable))
608
614
  book.send :apply_options, file, opts.merge({:read_only => !was_writable,
609
615
  :if_unsaved => (opts[:writable]==false ? :forget : :save)})
610
616
  end
@@ -904,14 +910,14 @@ module RobustExcelOle
904
910
  # @param [String] name the name of a range
905
911
  # @returns [Variant] the value of the range
906
912
  def [] name
907
- namevalue_glob(name)
913
+ namevalue_global(name)
908
914
  end
909
915
 
910
916
  # sets the value of a range
911
917
  # @param [String] name the name of the range
912
918
  # @param [Variant] value the contents of the range
913
919
  def []= (name, value)
914
- set_namevalue_glob(name, value)
920
+ set_namevalue_global(name, value)
915
921
  end
916
922
 
917
923
  # sets options
@@ -1026,11 +1032,14 @@ module RobustExcelOle
1026
1032
  '#<Workbook: ' + ('not alive ' unless alive?).to_s + (File.basename(self.filename) if alive?).to_s + " #{@excel}" + '>'
1027
1033
  end
1028
1034
 
1035
+ using ParentRefinement
1036
+ using StringRefinement
1037
+
1029
1038
  # @private
1030
1039
  def self.excel_class
1031
1040
  @excel_class ||= begin
1032
1041
  module_name = self.parent_name
1033
- "#{module_name}::Excel".constantize
1042
+ "#{module_name}::Excel".constantize
1034
1043
  rescue NameError => e
1035
1044
  # trace "excel_class: NameError: #{e}"
1036
1045
  Excel
@@ -1041,7 +1050,7 @@ module RobustExcelOle
1041
1050
  def self.worksheet_class
1042
1051
  @worksheet_class ||= begin
1043
1052
  module_name = self.parent_name
1044
- "#{module_name}::Worksheet".constantize
1053
+ "#{module_name}::Worksheet".constantize
1045
1054
  rescue NameError => e
1046
1055
  Worksheet
1047
1056
  end
@@ -80,7 +80,7 @@ module RobustExcelOle
80
80
  else
81
81
  name = p1
82
82
  begin
83
- namevalue_glob(name)
83
+ namevalue_global(name)
84
84
  rescue REOError
85
85
  namevalue(name)
86
86
  end
@@ -96,10 +96,10 @@ module RobustExcelOle
96
96
  else
97
97
  name, value = p1, p2
98
98
  begin
99
- set_namevalue_glob(name, value)
99
+ set_namevalue_global(name, value)
100
100
  rescue REOError
101
101
  begin
102
- workbook.set_namevalue_glob(name, value)
102
+ workbook.set_namevalue_global(name, value)
103
103
  rescue REOError
104
104
  set_namevalue(name, value)
105
105
  end
@@ -107,6 +107,71 @@ module RobustExcelOle
107
107
  end
108
108
  end
109
109
 
110
+ # returns the contents of a range with a locally defined name
111
+ # evaluates the formula if the contents is a formula
112
+ # if the name could not be found or the range or value could not be determined,
113
+ # then return default value, if provided, raise error otherwise
114
+ # @param [String] name the name of a range
115
+ # @param [Hash] opts the options
116
+ # @option opts [Symbol] :default the default value that is provided if no contents could be returned
117
+ # @return [Variant] the contents of a range with given name
118
+ def namevalue(name, opts = { :default => :__not_provided })
119
+ begin
120
+ ole_range = self.Range(name)
121
+ rescue # WIN32OLERuntimeError, VBAMethodMissingError, Java::OrgRacobCom::ComFailException
122
+ return opts[:default] unless opts[:default] == :__not_provided
123
+ raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
124
+ end
125
+ begin
126
+ worksheet = self if self.is_a?(Worksheet)
127
+ #value = ole_range.Value
128
+ value = if !::RANGES_JRUBY_BUG
129
+ ole_range.Value
130
+ else
131
+ values = RobustExcelOle::Range.new(ole_range, worksheet).v
132
+ (values.size==1 && values.first.size==1) ? values.first.first : values
133
+ end
134
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
135
+ return opts[:default] unless opts[:default] == :__not_provided
136
+ raise RangeNotEvaluatable, "cannot determine value of range named #{name.inspect} in #{self.inspect}"
137
+ end
138
+ if value == -2146828288 + RobustExcelOle::XlErrName
139
+ return opts[:default] unless opts[:default] == __not_provided
140
+ raise RangeNotEvaluatable, "cannot evaluate range named #{name.inspect} in #{File.basename(workbook.stored_filename).inspect rescue nil}"
141
+ end
142
+ return opts[:default] unless (opts[:default] == :__not_provided) || value.nil?
143
+ value
144
+ end
145
+
146
+ # assigns a value to a range given a locally defined name
147
+ # @param [String] name the name of a range
148
+ # @param [Variant] value the assigned value
149
+ # @option opts [Symbol] :color the color of the cell when set
150
+ def set_namevalue(name, value, opts = { })
151
+ begin
152
+ ole_range = self.Range(name)
153
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
154
+ raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
155
+ end
156
+ begin
157
+ ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
158
+ if !::RANGES_JRUBY_BUG
159
+ ole_range.Value = value
160
+ else
161
+ address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
162
+ row, col = address_tool.as_integer_ranges(address_r1c1)
163
+ row.each_with_index do |r,i|
164
+ col.each_with_index do |c,j|
165
+ ole_range.Cells(i+1,j+1).Value = (value.respond_to?(:first) ? value[i][j] : value)
166
+ end
167
+ end
168
+ end
169
+ value
170
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
171
+ raise RangeNotEvaluatable, "cannot assign value to range named #{name.inspect} in #{self.inspect}"
172
+ end
173
+ end
174
+
110
175
  # value of a cell, if row and column are given
111
176
  # @params row and column
112
177
  # @returns value of the cell
@@ -248,11 +313,14 @@ module RobustExcelOle
248
313
  false
249
314
  end
250
315
 
316
+ using ParentRefinement
317
+ using StringRefinement
318
+
251
319
  # @private
252
320
  def self.workbook_class
253
321
  @workbook_class ||= begin
254
322
  module_name = self.parent_name
255
- "#{module_name}::Workbook".constantize
323
+ "#{module_name}::Workbook".constantize
256
324
  rescue NameError => e
257
325
  Workbook
258
326
  end
@@ -36,19 +36,6 @@ module RobustExcelOle
36
36
  rm_tmp(@dir)
37
37
  end
38
38
 
39
- describe "trace" do
40
-
41
- it "should put some number" do
42
- a = 4
43
- Base::trace "some text #{a}"
44
- end
45
-
46
- it "should put another text" do
47
- b = Workbook.open(@simple_file)
48
- Base::trace "book: #{b}"
49
- end
50
- end
51
-
52
39
  describe "own_methods" do
53
40
 
54
41
  before do
@@ -57,8 +44,8 @@ module RobustExcelOle
57
44
  ["Activate", "ActiveSheet", "Application", "Close", "FullName", "HasPassword", "Name", "Names",
58
45
  "Password", "Protect", "ProtectSharing", "ProtectStructure", "Protect", "ReadOnly", "Save",
59
46
  "SaveAs", "Saved", "Sheets", "Unprotect"]
60
- @book_methods = ["focus", "add_sheet", "alive?", "close", "filename", "namevalue", "ole_object",
61
- "ole_workbook", "reopen", "save", "save_as", "saved", "set_namevalue"]
47
+ @book_methods = ["focus", "add_sheet", "alive?", "close", "filename", "ole_object",
48
+ "ole_workbook", "reopen", "save", "save_as", "saved"]
62
49
  @ole_excel_methods =
63
50
  ["ActiveCell", "ActiveSheet", "ActiveWorkbook", "Application", "Calculate", "Cells", "Columns",
64
51
  "DisplayAlerts", "Evaluate", "Hwnd", "Name", "Names", "Quit", "Range", "Ready", "Save",
@@ -82,6 +69,21 @@ module RobustExcelOle
82
69
 
83
70
  end
84
71
 
72
+ describe "trace" do
73
+
74
+ it "should put some number" do
75
+ a = 4
76
+ Base::trace "some text #{a}"
77
+ end
78
+
79
+ it "should put another text" do
80
+ b = Workbook.open(@simple_file)
81
+ Base::trace "book: #{b}"
82
+ end
83
+ end
84
+
85
+
86
+
85
87
  describe "misc" do
86
88
 
87
89
  it "should" do