robust_excel_ole 1.15 → 1.16

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c75264c3aa717667b2c38799b6fad4043f45a307d9d434b8e3d4a00ca0eff35
4
- data.tar.gz: dbb9ba06291ab9f9efdb616d5b0f34d9f425166fc5a90accba4efed3b0afb99e
3
+ metadata.gz: 87f0b689fc32747c5adbeaeff32f823b2153dc613a2dc27ae6b3a52060241ca0
4
+ data.tar.gz: 2d89ef58db655b2a84b95b9dc3622fe1daae6bfafc37c1f03f9de1984cf7958e
5
5
  SHA512:
6
- metadata.gz: e171843b4c4fa899a2db7ee69f21656dfc005396cd3f372977a9e520ff47b019642ddb188af41870bf79216508195609389743ffdb100c8c7975450d4334da1b
7
- data.tar.gz: 5cb5bfe60497f110077d27746e90d15ad455e94a2a289762372407361f26cc7163e2ea211720782c99e4b00abb48be954a2507ae855faf0b0cc069408b1e73f6
6
+ metadata.gz: 2a0074c2f763882481cdc43bb9a99b0c3b62d8ed2bfea646fc5d6d581719f01df7bb8a223c0d3629d698695b56629f1813b26f363a962707df91c42b51bebee0
7
+ data.tar.gz: 863b6380c04612c239bec9ce6998be0e9ed59ec884e2f57107aa2833f11b0ba4bca7258621bc48e818591a6c6d973fe961a5ca591b2dc85cd5a15fa13dbf1ed6
data/Changelog CHANGED
@@ -1,6 +1,15 @@
1
1
  # Change Log
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
+ ## [1.16]
5
+
6
+ ### Added
7
+ - RangeOwners#set_namevalue, set_namevalue_glob, Worksheet#set_cellval:
8
+ optional parameter for color
9
+
10
+ ### Changed
11
+ - Workbook#color_if_modified removed
12
+
4
13
  ## [1.15]
5
14
 
6
15
  ### Added
data/README.rdoc CHANGED
@@ -17,7 +17,7 @@ Therefore, it runs on Windows only.
17
17
 
18
18
  == Requirements
19
19
 
20
- Ruby 2.1 or higher. Most functions run on Ruby 1.8.6, too.
20
+ Ruby 2.1 or higher.
21
21
 
22
22
  == Installation
23
23
 
Binary file
@@ -142,9 +142,9 @@ A special feature of RobustExcelOle is that it allows to reopen workbooks after
142
142
 
143
143
  The closed workbook is now alive again, i.e. is open and responds to Excel methods.
144
144
 
145
- === Promoting WIN32OLE objects to RobustExcelOle objects
145
+ === Type-lifting WIN32OLE objects to RobustExcelOle objects
146
146
 
147
- Promoting means here: enriching a given object of a certain class by properties and methods of another class.
147
+ Type-lifting means here: enriching a given object of a certain class by properties and methods of another class.
148
148
  The method +General.to_reo+ enables type-lifting WIN32OLE objects to RobustExcelOle objects, in the sense that the attributes and methods of RobustExcelOle can be applied to these objects. For example, assume we have a WIN32OLE workbook +win32ole_workbook+:
149
149
 
150
150
  win32ole_workbook.to_class
@@ -173,6 +173,18 @@ A RobustExcelOle Workbook object is a proxy of an Excel WIN32OLE workbook. A Wor
173
173
 
174
174
  Similarly, each Excel, Worksheet and a Range object in RobustExcelOle is a proxy of a corresponding Excel, Worksheet and a Range object in WIN32OLE. For these objects identity transperence holds as well.
175
175
 
176
+ === Opening workbooks given a network path and a hostname share path ===
177
+
178
+ RobustExcelOle allows opening workbooks via a network path starting with a drive letter different from the default drive (mostly 'C'), e.g.
179
+
180
+ workbook = Workbook.open('N:/data workbook.xls')
181
+
182
+ Likewise the corresponding hostname share path can be used, starting with '//', e.g.
183
+
184
+ workbook = Workbook.open("//DESKTOP-A5D5GJ5/spec/data/workbook.xls")
185
+
186
+ where 'DESKTOP-A5D5GJ5' shall be the hostname, and 'data' be the share.
187
+
176
188
  === Unobtrusively modifying a workbook
177
189
 
178
190
  The method +unobtrusively+ enables the user to read or modify a workbook, no matter if it is open in some Excel instance, if it is saved or unsaved, and if it is writable or not. When opening a workbook unobtrusively, its status remains unchanged. This status includes, whether the workbook is opened or closed, saved or unsaved, readonly or writable, visible or invisible, calculation mode is automatic or manual, and checking compatibility is turned on or off.
@@ -306,9 +306,12 @@ or
306
306
 
307
307
  workbook.set_namevalue_glob("name", "new_value")
308
308
 
309
- The method []= colors the written cell, if you have specified the color of the changed range via the method Workbook#color before, e.g.
309
+ You can color the range when setting the contents of a range.
310
+
311
+ workbook.set_namevalue_glob("name", "new_value", :color => 4)
312
+
313
+ The method []= sets the contents of a range and colors the range via some default color.
310
314
 
311
- workbook.color_if_modified = 4
312
315
  workbook["name"] = "new_value"
313
316
 
314
317
  Similarly, the contents of a named range can be read and modified in a worksheet
@@ -29,11 +29,9 @@ module RobustExcelOle
29
29
  # otherwise proceeds according to prefer_writable
30
30
  def fetch(filename, options = { :prefer_writable => true })
31
31
  return nil unless filename
32
-
33
32
  filename = General.absolute_path(filename)
34
33
  filename_key = General.canonize(filename)
35
- weakref_books = @filename2books[filename_key]
36
- weakref_books = consider_networkpaths(filename_key) if weakref_books.empty? || weakref_books.nil?
34
+ weakref_books = @filename2books[filename_key]
37
35
  return nil if weakref_books.nil? || weakref_books.empty?
38
36
 
39
37
  result = open_book = closed_book = nil
@@ -67,68 +65,6 @@ module RobustExcelOle
67
65
  result
68
66
  end
69
67
 
70
- # @private
71
- def consider_networkpaths(filename)
72
- network = WIN32OLE.new('WScript.Network')
73
- drives = network.enumnetworkdrives
74
- drive_letter, filename_after_drive_letter = filename.split(':')
75
- found_filename = nil
76
- # if filename starts with a drive letter not c and this drive exists,
77
- # then if there is the corresponding host_share_path in the bookstore,
78
- # then take the corresponding workbooks
79
- if drive_letter != 'c' && drive_letter != filename
80
- for i in 0 .. drives.Count-1
81
- next if i % 2 == 1
82
- if drives.Item(i).gsub(':','').downcase == drive_letter
83
- hostname_share = drives.Item(i+1).gsub('\\','/').gsub('//','').downcase
84
- break
85
- end
86
- end
87
- @filename2books.each do |stored_filename,_|
88
- if hostname_share && stored_filename
89
- if stored_filename[0] == '/'
90
- index_hostname = stored_filename[1,stored_filename.length].index('/')+2
91
- index_hostname_share = stored_filename[index_hostname,stored_filename.length].index('/')
92
- hostname_share_in_stored_filename = stored_filename[1,index_hostname+index_hostname_share-1]
93
- if hostname_share_in_stored_filename == hostname_share
94
- found_filename = stored_filename
95
- break
96
- end
97
- end
98
- end
99
- end
100
- elsif filename[0] == '/'
101
- # if filename starts with a host name and share, and this is an existing host name share path,
102
- # then if there are workbooks with the corresponding drive letter,
103
- # then take these workbooks,
104
- index_hostname = filename[1,filename.length].index('/')+2
105
- index_hostname_share = filename[index_hostname,filename.length].index('/')
106
- hostname_share_in_filename = filename[1,index_hostname+index_hostname_share-1]
107
- filename_after_hostname_share = filename[index_hostname+index_hostname_share+1, filename.length]
108
- require 'socket'
109
- hostname = Socket.gethostname
110
- if hostname_share_in_filename[0,hostname_share_in_filename.index('/')] == hostname.downcase
111
- for i in 0 .. drives.Count-1
112
- next if i % 2 == 1
113
- hostname_share = drives.Item(i+1).gsub('\\','/').gsub('//','').downcase
114
- if hostname_share == hostname_share_in_filename
115
- drive_letter = drives.Item(i).gsub(':','').downcase
116
- break
117
- end
118
- end
119
- @filename2books.each do |stored_filename,_|
120
- if stored_filename
121
- if drive_letter && stored_filename.start_with?(drive_letter.downcase) && stored_filename.end_with?(filename_after_hostname_share)
122
- found_filename = stored_filename
123
- break
124
- end
125
- end
126
- end
127
- end
128
- end
129
- @filename2books[found_filename]
130
- end
131
-
132
68
  # stores a workbook
133
69
  # @param [Workbook] book a given book
134
70
  def store(book)
@@ -138,8 +74,7 @@ module RobustExcelOle
138
74
  # deletes the weak reference to the book
139
75
  @filename2books[old_filename_key].delete(book)
140
76
  end
141
- @filename2books[filename_key] |= [WeakRef.new(book)]
142
- book.stored_filename = book.filename
77
+ @filename2books[filename_key] |= [WeakRef.new(book)]
143
78
  end
144
79
 
145
80
  # creates and returns a separate Excel instance with Visible and DisplayAlerts equal false
@@ -177,24 +112,26 @@ module RobustExcelOle
177
112
 
178
113
  # prints the book store
179
114
  # @private
180
- def print
181
- # trace "@filename2books:"
115
+ def print_filename2books
116
+ #puts "@filename2books:"
182
117
  if @filename2books
183
- @filename2books.each do |_filename,books|
184
- # trace " filename: #{filename}"
185
- # trace " books:"
118
+ @filename2books.each do |filename,books|
119
+ #puts " filename: #{filename}"
120
+ #puts " books:"
186
121
  if books.empty?
187
- # trace " []"
122
+ #puts " []"
188
123
  else
189
124
  books.each do |book|
190
125
  if book.weakref_alive?
191
- # trace "#{book}"
126
+ #puts "book.filename: #{book.filename}"
192
127
  else # this should never happen
193
- # trace "weakref not alive"
128
+ #puts "weakref not alive"
194
129
  end
195
130
  end
196
131
  end
197
132
  end
133
+ else
134
+ #puts "nil"
198
135
  end
199
136
  end
200
137
  end
@@ -19,7 +19,7 @@ module RobustExcelOle
19
19
  # @private
20
20
  def method_missing(name, *args)
21
21
  #if name.to_s[0,1] =~ /[A-Z]/
22
- if ::JRUBY_BUG_ERRORMESSAGE
22
+ if ::ERRORMESSAGE_JRUBY_BUG
23
23
  begin
24
24
  @cell.send(name, *args)
25
25
  rescue Java::OrgRacobCom::ComFailException
@@ -17,7 +17,7 @@ module RobustExcelOle
17
17
  # See https://docs.microsoft.com/en-us/office/vba/api/excel.application(object)#methods
18
18
 
19
19
  class Excel < RangeOwners
20
- attr_accessor :ole_excel
20
+ attr_reader :ole_excel
21
21
  attr_reader :properties
22
22
 
23
23
  alias ole_object ole_excel
@@ -111,10 +111,8 @@ module RobustExcelOle
111
111
  # @return [Excel] an Excel instance
112
112
  def recreate(opts = {})
113
113
  unless alive?
114
- opts = {
115
- :visible => @properties[:visible] || false,
116
- :displayalerts => @properties[:displayalerts] || :if_visible
117
- }.merge(opts)
114
+ opts = {:visible => false, :displayalerts => :if_visible}.merge(
115
+ {:visible => @properties[:visible], :displayalerts => @properties[:displayalerts]}).merge(opts)
118
116
  @ole_excel = WIN32OLE.new('Excel.Application')
119
117
  set_options(opts)
120
118
  if opts[:reopen_workbooks]
@@ -391,7 +389,7 @@ module RobustExcelOle
391
389
  # if this Excel instance is being closed, then Excel creates a new Excel instance
392
390
  # @private
393
391
  def self.current_ole_excel
394
- if ::JRUBY_BUG_CONNECT
392
+ if ::CONNECT_EXCEL_JRUBY_BUG
395
393
  result = known_excel_instance
396
394
  if result.nil?
397
395
  if excels_number > 0
@@ -694,10 +692,7 @@ module RobustExcelOle
694
692
  # @param [String] name the name of the range
695
693
  # @param [Variant] value the contents of the range
696
694
  def []=(name, value)
697
- old_color_if_modified = workbook.color_if_modified
698
- workbook.color_if_modified = 42 unless workbook.nil? # aqua-marin
699
- set_namevalue_glob(name,value)
700
- workbook.color_if_modified = old_color_if_modified
695
+ set_namevalue_glob(name, value, :color => 42)
701
696
  end
702
697
 
703
698
  # @private
@@ -740,7 +735,7 @@ module RobustExcelOle
740
735
  def method_missing(name, *args)
741
736
  if name.to_s[0,1] =~ /[A-Z]/
742
737
  raise ObjectNotAlive, 'method missing: Excel not alive' unless alive?
743
- if ::JRUBY_BUG_ERRORMESSAGE
738
+ if ::ERRORMESSAGE_JRUBY_BUG
744
739
  begin
745
740
  @ole_excel.send(name, *args)
746
741
  rescue Java::OrgRacobCom::ComFailException => msg
@@ -3,24 +3,47 @@
3
3
  module General
4
4
 
5
5
  IS_JRUBY_PLATFORM = (RUBY_PLATFORM =~ /java/)
6
- ::JRUBY_BUG_CONNECT = IS_JRUBY_PLATFORM && true
7
- ::JRUBY_BUG_COPYSHEETS = IS_JRUBY_PLATFORM && true
8
- ::JRUBY_BUG_ERRORMESSAGE = IS_JRUBY_PLATFORM && true
9
- ::JRUBY_BUG_CONNECTEXCEL = IS_JRUBY_PLATFORM && true
10
- ::JRUBY_BUG_RANGES = IS_JRUBY_PLATFORM && true
11
-
6
+ ::EXPANDPATH_JRUBY_BUG = IS_JRUBY_PLATFORM && true
7
+ ::CONNECT_JRUBY_BUG = IS_JRUBY_PLATFORM && true
8
+ ::COPYSHEETS_JRUBY_BUG = IS_JRUBY_PLATFORM && true
9
+ ::ERRORMESSAGE_JRUBY_BUG = IS_JRUBY_PLATFORM && true
10
+ ::CONNECT_EXCEL_JRUBY_BUG = IS_JRUBY_PLATFORM && true
11
+ ::RANGES_JRUBY_BUG = IS_JRUBY_PLATFORM && true
12
+
13
+ @private
14
+ def network2hostnamesharepath(filename)
15
+ network = WIN32OLE.new('WScript.Network')
16
+ drives = network.enumnetworkdrives
17
+ drive_letter, filename_after_drive_letter = filename.split(':')
18
+ # if filename starts with a drive letter not c and this drive exists,
19
+ # then determine the corresponding host_share_path
20
+ default_drive = File.absolute_path(".")[0]
21
+ if drive_letter != default_drive && drive_letter != filename
22
+ for i in 0 .. drives.Count-1
23
+ next if i % 2 == 1
24
+ if drives.Item(i).gsub(':','') == drive_letter
25
+ hostname_share = drives.Item(i+1) #.gsub('\\','/').gsub('//','')
26
+ break
27
+ end
28
+ end
29
+ hostname_share + filename_after_drive_letter if hostname_share
30
+ else
31
+ return filename
32
+ end
33
+ end
12
34
 
13
35
  # @private
14
- def absolute_path(file)
36
+ def absolute_path(file)
37
+ file[0,2] = './' if ::EXPANDPATH_JRUBY_BUG && file =~ /[A-Z]:[^\/]/
15
38
  file = File.expand_path(file)
16
39
  file = RobustExcelOle::Cygwin.cygpath('-w', file) if RUBY_PLATFORM =~ /cygwin/
17
40
  WIN32OLE.new('Scripting.FileSystemObject').GetAbsolutePathName(file).tr('/','\\')
18
41
  end
19
42
 
20
43
  # @private
21
- def canonize(filename)
44
+ def canonize(filename)
22
45
  raise TypeREOError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
23
-
46
+ filename = network2hostnamesharepath(filename)
24
47
  normalize(filename).downcase
25
48
  end
26
49
 
@@ -27,7 +27,7 @@ module RobustExcelOle
27
27
  # @returns [Array] the values
28
28
  def values(range = nil)
29
29
  #result = map { |x| x.Value }.flatten
30
- result_unflatten = if !::JRUBY_BUG_RANGES
30
+ result_unflatten = if !::RANGES_JRUBY_BUG
31
31
  map { |x| x.v }
32
32
  else
33
33
  self.v
@@ -44,7 +44,7 @@ module RobustExcelOle
44
44
 
45
45
  def v
46
46
  begin
47
- if !::JRUBY_BUG_RANGES
47
+ if !::RANGES_JRUBY_BUG
48
48
  self.Value
49
49
  else
50
50
  address_r1c1 = self.AddressLocal(true,true,XlR1C1)
@@ -65,7 +65,7 @@ module RobustExcelOle
65
65
 
66
66
  def v=(value)
67
67
  begin
68
- if !::JRUBY_BUG_RANGES
68
+ if !::RANGES_JRUBY_BUG
69
69
  ole_range.Value = value
70
70
  else
71
71
  address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
@@ -240,7 +240,7 @@ module RobustExcelOle
240
240
  # @private
241
241
  def method_missing(name, *args)
242
242
  if name.to_s[0,1] =~ /[A-Z]/
243
- if ::JRUBY_BUG_ERRORMESSAGE
243
+ if ::ERRORMESSAGE_JRUBY_BUG
244
244
  begin
245
245
  @ole_range.send(name, *args)
246
246
  rescue Java::OrgRacobCom::ComFailException
@@ -24,7 +24,7 @@ module RobustExcelOle
24
24
  ole_range = name_obj.RefersToRange
25
25
  value = begin
26
26
  #name_obj.RefersToRange.Value
27
- if !::JRUBY_BUG_RANGES
27
+ if !::RANGES_JRUBY_BUG
28
28
  ole_range.Value
29
29
  else
30
30
  values = RobustExcelOle::Range.new(ole_range).v
@@ -39,7 +39,7 @@ module RobustExcelOle
39
39
  #sheet.Evaluate(name_obj.Name).Value
40
40
  # does it result in a range?
41
41
  ole_range = sheet.Evaluate(name_obj.Name)
42
- if !::JRUBY_BUG_RANGES
42
+ if !::RANGES_JRUBY_BUG
43
43
  ole_range.Value
44
44
  else
45
45
  values = RobustExcelOle::Range.new(ole_range).v
@@ -61,7 +61,8 @@ module RobustExcelOle
61
61
  # sets the contents of a range
62
62
  # @param [String] name the name of a range
63
63
  # @param [Variant] value the contents of the range
64
- def set_namevalue_glob(name, value, opts = { }) # opts is deprecated
64
+ # @option opts [Symbol] :color the color of the cell when set
65
+ def set_namevalue_glob(name, value, opts = { })
65
66
  begin
66
67
  name_obj = begin
67
68
  name_object(name)
@@ -69,9 +70,8 @@ module RobustExcelOle
69
70
  raise
70
71
  end
71
72
  ole_range = name_object(name).RefersToRange
72
- workbook.color_if_modified = opts[:color] unless opts[:color].nil?
73
- ole_range.Interior.ColorIndex = workbook.color_if_modified unless workbook.color_if_modified.nil?
74
- if !::JRUBY_BUG_RANGES
73
+ ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
74
+ if !::RANGES_JRUBY_BUG
75
75
  ole_range.Value = value
76
76
  else
77
77
  address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
@@ -106,7 +106,7 @@ module RobustExcelOle
106
106
  end
107
107
  begin
108
108
  #value = ole_range.Value
109
- value = if !::JRUBY_BUG_RANGES
109
+ value = if !::RANGES_JRUBY_BUG
110
110
  ole_range.Value
111
111
  else
112
112
  values = RobustExcelOle::Range.new(ole_range).v
@@ -127,17 +127,17 @@ module RobustExcelOle
127
127
  # assigns a value to a range given a locally defined name
128
128
  # @param [String] name the name of a range
129
129
  # @param [Variant] value the assigned value
130
- def set_namevalue(name, value, opts = { }) # opts is deprecated
130
+ # @option opts [Symbol] :color the color of the cell when set
131
+ def set_namevalue(name, value, opts = { })
131
132
  begin
132
- return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook) # opts deprecated
133
+ return set_namevalue_glob(name, value, opts) if self.is_a?(Workbook)
133
134
  ole_range = self.Range(name)
134
- rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
135
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
135
136
  raise NameNotFound, "name #{name.inspect} not in #{self.inspect}"
136
137
  end
137
138
  begin
138
- workbook.color_if_modified = opts[:color] unless opts[:color].nil?
139
- ole_range.Interior.ColorIndex = workbook.color_if_modified unless workbook.color_if_modified.nil?
140
- if !::JRUBY_BUG_RANGES
139
+ ole_range.Interior.ColorIndex = opts[:color] unless opts[:color].nil?
140
+ if !::RANGES_JRUBY_BUG
141
141
  ole_range.Value = value
142
142
  else
143
143
  address_r1c1 = ole_range.AddressLocal(true,true,XlR1C1)
@@ -263,7 +263,7 @@ module RobustExcelOle
263
263
 
264
264
  def name_object(name)
265
265
  self.Names.Item(name)
266
- rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException
266
+ rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException, VBAMethodMissingError
267
267
  begin
268
268
  self.Parent.Names.Item(name)
269
269
  rescue WIN32OLERuntimeError, Java::OrgRacobCom::ComFailException