robust_excel_ole 1.16 → 1.17

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 87f0b689fc32747c5adbeaeff32f823b2153dc613a2dc27ae6b3a52060241ca0
4
- data.tar.gz: 2d89ef58db655b2a84b95b9dc3622fe1daae6bfafc37c1f03f9de1984cf7958e
3
+ metadata.gz: c268eff75271d48aae54af54c03c138e8a965a6c6965b6fc9b5fd330a346888d
4
+ data.tar.gz: '0921d96d9d20546523acb5ea5e419d8e2351307c23d25abe8b8d96010364b643'
5
5
  SHA512:
6
- metadata.gz: 2a0074c2f763882481cdc43bb9a99b0c3b62d8ed2bfea646fc5d6d581719f01df7bb8a223c0d3629d698695b56629f1813b26f363a962707df91c42b51bebee0
7
- data.tar.gz: 863b6380c04612c239bec9ce6998be0e9ed59ec884e2f57107aa2833f11b0ba4bca7258621bc48e818591a6c6d973fe961a5ca591b2dc85cd5a15fa13dbf1ed6
6
+ metadata.gz: c98669d651a2ff192bab0767ea16085a08cab8e0c656c3123b684080b96b62899967f3c4998637002dddf72eb1dbbd635f2ef102153d53842977adeba11d32c6
7
+ data.tar.gz: 1ac22fd73f4dae16142c1dc1d81bd9d9f8eeb5fbf95f85b4bcf26d99293b474c544aae863af4d40cc64052535ab40541956b69db8301274aade5afcacea37534
@@ -153,6 +153,7 @@ The method +General.to_reo+ enables type-lifting WIN32OLE objects to RobustExcel
153
153
  This object can be type-lifted to a RobustExcelOle workbook.
154
154
 
155
155
  workbook = win32ole_workbook.to_reo
156
+
156
157
  workbook.to_class
157
158
  => RobustExcelOle::Workbook
158
159
 
@@ -166,6 +167,9 @@ You can supply options, e.g. +:visible+.
166
167
 
167
168
  workbook = Workbook.new(win32ole_workbook, :visible => true)
168
169
 
170
+ You can also supply a workbook and options, e.g.
171
+
172
+ new_workbook = Workbook.new(workbook, :visible => true)
169
173
 
170
174
  === Identity transperence ===
171
175
 
@@ -3,16 +3,17 @@ if RUBY_PLATFORM =~ /java/
3
3
  else
4
4
  require 'win32ole'
5
5
  end
6
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/reo_common')
7
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/range_owners')
8
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/address')
6
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/base')
9
7
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/general')
8
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/vba_objects')
9
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/range_owners')
10
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/address_tool')
10
11
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/excel')
11
12
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/bookstore')
12
13
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/workbook')
13
14
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/worksheet')
14
- require File.join(File.dirname(__FILE__), 'robust_excel_ole/cell')
15
15
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/range')
16
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/cell')
16
17
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/cygwin') if RUBY_PLATFORM =~ /cygwin/
17
18
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/version')
18
19
 
@@ -2,37 +2,38 @@
2
2
 
3
3
  module RobustExcelOle
4
4
 
5
- class Address < REOCommon
5
+ class AddressTool < Base
6
6
 
7
- def self.new(r1c1_letters)
8
- @@row_letter = r1c1_letters[0..0]
9
- @@col_letter = r1c1_letters[1..1]
7
+ def initialize(address_string)
8
+ r1c1_letters = address_string.gsub(/[0-9]/,'')
9
+ @row_letter = r1c1_letters[0..0]
10
+ @col_letter = r1c1_letters[1..1]
10
11
  end
11
12
 
12
13
  # address formats that are valid:
13
14
  # r1c1-format: e.g. "Z3S1", "Z3S1:Z5S2", "Z[3]S1", "Z3S[-1]:Z[5]S1", "Z[3]", "S[-2]"
14
15
  # infinite ranges are not possible, e.g. "Z3:Z5", "S2:S5", "Z2", "S3", "Z[2]"
15
- # int_range: e.g. [3,1], [3,"A"], [3..5,1..2], [3..5, "A".."B"],
16
- # [3..4, nil], [nil, 2..4], [2,nil], [nil,4]
16
+ # integer_ranges-fromat: e.g. [3,1], [3,"A"], [3..5,1..2], [3..5, "A".."B"],
17
+ # [3..4, nil], [nil, 2..4], [2,nil], [nil,4]
17
18
  # a1-format: e.g. "A3", "A3:B5", "A:B", "3:5", "A", "3"
18
19
 
19
- def self.r1c1(address)
20
+ def as_r1c1(address)
20
21
  transform_address(address,:r1c1)
21
22
  end
22
23
 
23
- def self.a1(address)
24
+ def as_a1(address)
24
25
  transform_address(address,:a1)
25
26
  end
26
27
 
27
28
  # valid address formats: e.g. [3,1], [3,"A"], [3..5,1..2], [3..5, "A".."B"],
28
29
  # [3..4, nil], [nil, 2..4], [2,nil], [nil,4]
29
- def self.int_range(address)
30
+ def as_integer_ranges(address)
30
31
  transform_address(address,:int_range)
31
32
  end
32
33
 
33
34
  private
34
35
 
35
- def self.transform_address(address, format)
36
+ def transform_address(address, format)
36
37
  address = address.is_a?(Array) ? address : [address]
37
38
  raise AddressInvalid, "address #{address.inspect} has more than two components" if address.size > 2
38
39
  begin
@@ -70,8 +71,8 @@ module RobustExcelOle
70
71
  raise AddressInvalid, "address (#{address.inspect}) format not correct"
71
72
  end
72
73
  if format==:r1c1
73
- r1c1_string(@@row_letter,rows,:min) + r1c1_string(@@col_letter,columns,:min) + ":" +
74
- r1c1_string(@@row_letter,rows,:max) + r1c1_string(@@col_letter,columns,:max)
74
+ r1c1_string(@row_letter,rows,:min) + r1c1_string(@col_letter,columns,:min) + ":" +
75
+ r1c1_string(@row_letter,rows,:max) + r1c1_string(@col_letter,columns,:max)
75
76
  elsif format==:int_range
76
77
  [rows,columns]
77
78
  else
@@ -79,8 +80,7 @@ module RobustExcelOle
79
80
  end
80
81
  end
81
82
 
82
- # @private
83
- def self.r1c1_string(letter,int_range,type)
83
+ def r1c1_string(letter,int_range,type)
84
84
  return "" if int_range.nil? || int_range.begin.nil?
85
85
  parameter = type == :min ? int_range.begin : int_range.end
86
86
  is_relative = parameter.is_a?(Array)
@@ -88,27 +88,28 @@ module RobustExcelOle
88
88
  letter + (is_relative ? "(" : "") + parameter.to_s + (is_relative ? ")" : "")
89
89
  end
90
90
 
91
- # @private
92
- def self.analyze(comp,format)
91
+ def analyze(comp,format)
93
92
  row_comp, col_comp = if format==:a1
94
93
  [comp.gsub(/[A-Z]/,''), comp.gsub(/[0-9]/,'')]
95
94
  else
96
- a,b = comp.split(@@row_letter)
97
- c,d = b.split(@@col_letter)
95
+ a,b = comp.split(@row_letter)
96
+ c,d = b.split(@col_letter)
98
97
  b.nil? ? ["",b] : (d.nil? ? [c,""] : [c,d])
99
98
  end
100
- def self.s2n(s)
99
+ def s2n(s)
101
100
  s!="" ? (s[0] == "[" ? [s.gsub(/\[|\]/,'').to_i] : (s.to_i!=0 ? s.to_i : s)) : nil
102
101
  end
103
102
  [s2n(row_comp), s2n(col_comp)]
104
103
  end
105
104
 
106
-
107
- # @private
108
- def self.str2num(str)
105
+ def str2num(str)
109
106
  str.tr("A-Z","0-9A-P").to_i(26) + (26**str.size-1)/25
110
107
  end
111
108
 
112
109
  end
113
110
 
111
+ # @private
112
+ class AddressInvalid < REOError
113
+ end
114
+
114
115
  end
@@ -50,94 +50,10 @@ module RobustExcelOle
50
50
  class MiscREOError < REOError
51
51
  end
52
52
 
53
- # @private
54
- class ExcelDamaged < ExcelREOError
55
- end
56
-
57
- # @private
58
- class UnsavedWorkbooks < ExcelREOError
59
- end
60
-
61
- # @private
62
- class WorkbookBlocked < WorkbookREOError
63
- end
64
-
65
- # @private
66
- class WorkbookNotSaved < WorkbookREOError
67
- end
68
-
69
- # @private
70
- class WorkbookReadOnly < WorkbookREOError
71
- end
72
-
73
- # @private
74
- class WorkbookBeingUsed < WorkbookREOError
75
- end
76
-
77
- # @private
78
- class WorkbookConnectingUnsavedError < WorkbookREOError
79
- end
80
-
81
- # @private
82
- class WorkbookConnectingBlockingError < WorkbookREOError
83
- end
84
-
85
- # @private
86
- class WorkbookConnectingUnknownError < WorkbookREOError
87
- end
88
-
89
- # @private
90
- class FileNotFound < FileREOError
91
- end
92
-
93
- # @private
94
- class FileNameNotGiven < FileREOError
95
- end
96
-
97
- # @private
98
- class FileAlreadyExists < FileREOError
99
- end
100
-
101
- # @private
102
- class NameNotFound < NamesREOError
103
- end
104
-
105
- # @private
106
- class NameAlreadyExists < NamesREOError
107
- end
108
-
109
- # @private
110
- class RangeNotEvaluatable < MiscREOError
111
- end
112
-
113
- # @private
114
- class RangeNotCreated < MiscREOError
115
- end
116
-
117
- # @private
118
- class RangeNotCopied < MiscREOError
119
- end
120
-
121
- # @private
122
- class OptionInvalid < MiscREOError
123
- end
124
-
125
- # @private
126
- class ObjectNotAlive < MiscREOError
127
- end
128
-
129
53
  # @private
130
54
  class TypeREOError < REOError
131
55
  end
132
56
 
133
- # @private
134
- class TimeOut < REOError
135
- end
136
-
137
- # @private
138
- class AddressInvalid < REOError
139
- end
140
-
141
57
  # @private
142
58
  class UnexpectedREOError < REOError
143
59
  end
@@ -145,13 +61,9 @@ module RobustExcelOle
145
61
  # @private
146
62
  class NotImplementedREOError < REOError
147
63
  end
64
+
148
65
 
149
- class REOCommon
150
-
151
- # @private
152
- def excel
153
- raise TypeREOError, 'receiver instance is neither an Excel nor a Workbook'
154
- end
66
+ class Base
155
67
 
156
68
  # @private
157
69
  def own_methods
@@ -2,7 +2,8 @@
2
2
 
3
3
  module RobustExcelOle
4
4
 
5
- class Bookstore < REOCommon
5
+ class Bookstore < Base
6
+
6
7
  def initialize
7
8
  @filename2books ||= Hash.new { |hash, key| hash[key] = [] }
8
9
  @hidden_excel_instance = nil
@@ -103,7 +104,6 @@ module RobustExcelOle
103
104
 
104
105
  private
105
106
 
106
- # @private
107
107
  def try_hidden_excel
108
108
  @hidden_excel_instance.__getobj__ if @hidden_excel_instance && @hidden_excel_instance.weakref_alive? && @hidden_excel_instance.__getobj__.alive?
109
109
  end
@@ -1,11 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module RobustExcelOle
4
- class Cell < REOCommon
5
- attr_reader :cell
4
+
5
+ class Cell < Range
6
+ attr_reader :ole_cell
6
7
 
7
8
  def initialize(win32_cell)
8
- @cell = win32_cell.MergeCells ? win32_cell.MergeArea.Item(1,1) : win32_cell
9
+ @ole_cell = win32_cell.MergeCells ? win32_cell.MergeArea.Item(1,1) : win32_cell
10
+ super
9
11
  end
10
12
 
11
13
  def v
@@ -16,25 +18,27 @@ module RobustExcelOle
16
18
  self.Value = value
17
19
  end
18
20
 
21
+ private
22
+
19
23
  # @private
20
24
  def method_missing(name, *args)
21
- #if name.to_s[0,1] =~ /[A-Z]/
22
- if ::ERRORMESSAGE_JRUBY_BUG
23
- begin
24
- @cell.send(name, *args)
25
- rescue Java::OrgRacobCom::ComFailException
26
- raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
25
+ if name.to_s[0,1] =~ /[A-Z]/
26
+ if ::ERRORMESSAGE_JRUBY_BUG
27
+ begin
28
+ @ole_cell.send(name, *args)
29
+ rescue Java::OrgRacobCom::ComFailException
30
+ raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
31
+ end
32
+ else
33
+ begin
34
+ @ole_cell.send(name, *args)
35
+ rescue NoMethodError
36
+ raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
37
+ end
27
38
  end
28
39
  else
29
- begin
30
- @cell.send(name, *args)
31
- rescue NoMethodError
32
- raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
33
- end
40
+ super
34
41
  end
35
- # else
36
- # super
37
- # end
38
42
  end
39
43
  end
40
44
  end
@@ -16,9 +16,10 @@ module RobustExcelOle
16
16
  # that you would apply for an Application object.
17
17
  # See https://docs.microsoft.com/en-us/office/vba/api/excel.application(object)#methods
18
18
 
19
- class Excel < RangeOwners
19
+ class Excel < VbaObjects
20
20
  attr_reader :ole_excel
21
21
  attr_reader :properties
22
+ attr_reader :address_tool
22
23
 
23
24
  alias ole_object ole_excel
24
25
 
@@ -125,10 +126,18 @@ module RobustExcelOle
125
126
  self
126
127
  end
127
128
 
129
+ # @private
130
+ def address_tool
131
+ raise(ExcelREOError, "Excel contains no workbook") unless @ole_excel.Workbooks.Count > 0
132
+ @address_tool ||= begin
133
+ address_string = @ole_excel.Workbooks.Item(1).Worksheets.Item(1).Cells.Item(1,1).Address(true,true,XlR1C1)
134
+ address_tool_class.new(address_string)
135
+ end
136
+ end
137
+
128
138
  private
129
139
 
130
140
  # retain the saved status of all workbooks
131
- # @private
132
141
  def retain_saved_workbooks
133
142
  saved_stati = @ole_excel.Workbooks.map { |w| w.Saved }
134
143
  begin
@@ -138,7 +147,6 @@ module RobustExcelOle
138
147
  end
139
148
  end
140
149
 
141
- # @private
142
150
  def ole_workbooks
143
151
  ole_workbooks = begin
144
152
  @ole_excel.Workbooks
@@ -153,11 +161,13 @@ module RobustExcelOle
153
161
 
154
162
  public
155
163
 
164
+ # @private
156
165
  def self.contains_unsaved_workbooks?
157
166
  !Excel.current.unsaved_workbooks.empty?
158
167
  end
159
168
 
160
169
  # returns unsaved workbooks (win32ole objects)
170
+ # @private
161
171
  def unsaved_workbooks
162
172
  unsaved_workbooks = []
163
173
  begin
@@ -175,6 +185,7 @@ module RobustExcelOle
175
185
  # :forget -> closes the Excel instance without saving the workbooks
176
186
  # :save -> saves the workbooks before closing
177
187
  # :alert -> let Excel do it
188
+ # @private
178
189
  def close_workbooks(options = { :if_unsaved => :raise })
179
190
  return unless alive?
180
191
 
@@ -382,12 +393,11 @@ module RobustExcelOle
382
393
  @@hwnd2excel.size
383
394
  end
384
395
 
385
- #private
396
+ private
386
397
 
387
398
  # returns a Win32OLE object that represents a Excel instance to which Excel connects
388
399
  # connects to the first opened Excel instance
389
400
  # if this Excel instance is being closed, then Excel creates a new Excel instance
390
- # @private
391
401
  def self.current_ole_excel
392
402
  if ::CONNECT_EXCEL_JRUBY_BUG
393
403
  result = known_excel_instance
@@ -430,6 +440,25 @@ module RobustExcelOle
430
440
  nil
431
441
  end
432
442
 
443
+ def self.hwnd2excel(hwnd)
444
+ excel_weakref = @@hwnd2excel[hwnd]
445
+ if excel_weakref
446
+ if excel_weakref.weakref_alive?
447
+ excel_weakref.__getobj__
448
+ else
449
+ trace 'dead reference to an Excel'
450
+ begin
451
+ @@hwnd2excel.delete(hwnd)
452
+ nil
453
+ rescue
454
+ trace "Warning: deleting dead reference failed! (hwnd: #{hwnd.inspect})"
455
+ end
456
+ end
457
+ end
458
+ end
459
+
460
+ public
461
+
433
462
  # returns all Excel objects for all Excel instances opened with RobustExcelOle
434
463
  def self.known_excel_instances
435
464
  pid2excel = {}
@@ -464,24 +493,6 @@ module RobustExcelOle
464
493
  self
465
494
  end
466
495
 
467
- # @private
468
- def self.hwnd2excel(hwnd)
469
- excel_weakref = @@hwnd2excel[hwnd]
470
- if excel_weakref
471
- if excel_weakref.weakref_alive?
472
- excel_weakref.__getobj__
473
- else
474
- trace 'dead reference to an Excel'
475
- begin
476
- @@hwnd2excel.delete(hwnd)
477
- nil
478
- rescue
479
- trace "Warning: deleting dead reference failed! (hwnd: #{hwnd.inspect})"
480
- end
481
- end
482
- end
483
- end
484
-
485
496
  # @private
486
497
  def hwnd
487
498
  self.Hwnd
@@ -700,7 +711,9 @@ module RobustExcelOle
700
711
  def workbook
701
712
  return @workbook unless @workbook.nil?
702
713
  @workbook = workbook_class.new(@ole_excel.ActiveWorkbook)
703
- end
714
+ end
715
+
716
+ alias_method :active_workbook, :workbook
704
717
 
705
718
  # @private
706
719
  def to_s
@@ -727,11 +740,26 @@ module RobustExcelOle
727
740
  self.class.workbook_class
728
741
  end
729
742
 
743
+ # @private
744
+ def self.address_tool_class
745
+ @address_tool_class ||= begin
746
+ module_name = parent_name
747
+ "#{module_name}::AddressTool".constantize
748
+ rescue NameError => e
749
+ AddressTool
750
+ end
751
+ end
752
+
753
+ # @private
754
+ def address_tool_class
755
+ self.class.address_tool_class
756
+ end
757
+
758
+
730
759
  include MethodHelpers
731
760
 
732
761
  private
733
762
 
734
- # @private
735
763
  def method_missing(name, *args)
736
764
  if name.to_s[0,1] =~ /[A-Z]/
737
765
  raise ObjectNotAlive, 'method missing: Excel not alive' unless alive?
@@ -754,7 +782,16 @@ module RobustExcelOle
754
782
  end
755
783
  end
756
784
 
757
- public
785
+ public
786
+
787
+ # @private
788
+ class ExcelDamaged < ExcelREOError
789
+ end
790
+
791
+ # @private
792
+ class UnsavedWorkbooks < ExcelREOError
793
+ end
794
+
758
795
 
759
796
  Application = Excel
760
797
 
@@ -763,3 +800,4 @@ end
763
800
  class WIN32OLE
764
801
  include Enumerable
765
802
  end
803
+