robust_excel_ole 1.15 → 1.18.2
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 +4 -4
- data/Changelog +27 -0
- data/README.rdoc +18 -1
- data/___dummy_workbook.xls +0 -0
- data/docs/README_excel.rdoc +6 -0
- data/docs/README_open.rdoc +18 -2
- data/docs/README_ranges.rdoc +11 -2
- data/examples/example_ruby_library.rb +27 -0
- data/extconf.rb +13 -0
- data/lib/robust_excel_ole.rb +4 -3
- data/lib/robust_excel_ole/{address.rb → address_tool.rb} +23 -22
- data/lib/robust_excel_ole/{reo_common.rb → base.rb} +2 -90
- data/lib/robust_excel_ole/bookstore.rb +14 -77
- data/lib/robust_excel_ole/cell.rb +30 -18
- data/lib/robust_excel_ole/excel.rb +71 -41
- data/lib/robust_excel_ole/general.rb +39 -14
- data/lib/robust_excel_ole/range.rb +42 -19
- data/lib/robust_excel_ole/range_owners.rb +40 -25
- data/lib/robust_excel_ole/vba_objects.rb +30 -0
- data/lib/robust_excel_ole/version.rb +1 -1
- data/lib/robust_excel_ole/workbook.rb +241 -235
- data/lib/robust_excel_ole/worksheet.rb +42 -21
- data/lib/rubygems_plugin.rb +3 -0
- data/robust_excel_ole.gemspec +1 -0
- data/spec/address_tool_spec.rb +175 -0
- data/spec/{reo_common_spec.rb → base_spec.rb} +11 -30
- data/spec/bookstore_spec.rb +3 -3
- data/spec/cell_spec.rb +67 -25
- data/spec/data/more_data/workbook.xls +0 -0
- data/spec/excel_spec.rb +41 -275
- data/spec/general_spec.rb +17 -23
- data/spec/range_spec.rb +57 -3
- data/spec/workbook_spec.rb +7 -75
- data/spec/workbook_specs/workbook_misc_spec.rb +11 -21
- data/spec/workbook_specs/workbook_open_spec.rb +570 -30
- data/spec/workbook_specs/workbook_unobtr_spec.rb +33 -33
- data/spec/worksheet_spec.rb +36 -4
- metadata +10 -6
- data/spec/address_spec.rb +0 -174
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e7e99b95395eacc6a02673421b2ff467afd173244990fc19a9834d1c9a2f6c0
|
4
|
+
data.tar.gz: c58927fbaf2b4d7f301dba8a17a52e966e9b25041ae44f6c782e02785c5df522
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d01c45a26903e3cfb9eb0a45c712a89b4e65dac4050982749df443199b4df19137d26dbb591a15b41ebede0db55877170774fb6f4095a1ec435aba78df7d064c
|
7
|
+
data.tar.gz: 8e8b3bcfde250213591e7536fc182a5b058e98361b68dfb0e6a95eae96ca5a66568ddf47030eba649870c1b7186686ad55d52e36ce79c10eec857745ff3ddd89
|
data/Changelog
CHANGED
@@ -1,6 +1,33 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [1.18] 2020-30-4
|
5
|
+
|
6
|
+
### Added
|
7
|
+
- Workbook#worksheets, worksheets_count
|
8
|
+
- Worksheet#each_value
|
9
|
+
- Range#value, value=
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
- Range#initialize: optional paramter worksheet
|
13
|
+
|
14
|
+
## [1.17]
|
15
|
+
|
16
|
+
### Added
|
17
|
+
- Excel#active_workbook
|
18
|
+
|
19
|
+
### Changed
|
20
|
+
- Excel#namevalue, set_namevalue, namevalue_glob, set_namevalue_glob are being removed
|
21
|
+
|
22
|
+
## [1.16]
|
23
|
+
|
24
|
+
### Added
|
25
|
+
- RangeOwners#set_namevalue, set_namevalue_glob, Worksheet#set_cellval:
|
26
|
+
optional parameter for color
|
27
|
+
|
28
|
+
### Changed
|
29
|
+
- Workbook#color_if_modified removed
|
30
|
+
|
4
31
|
## [1.15]
|
5
32
|
|
6
33
|
### Added
|
data/README.rdoc
CHANGED
@@ -14,10 +14,27 @@ Library references are supported.
|
|
14
14
|
RobustExcelOle works by sending VBA methods via Win32OLE.
|
15
15
|
Therefore, it runs on Windows only.
|
16
16
|
|
17
|
+
== Feature list
|
18
|
+
|
19
|
+
- opening and processing workbooks across various Excel instances
|
20
|
+
- reading and writing workbooks (cells and ranges)
|
21
|
+
- reopening and unobtrusively opening workbooks
|
22
|
+
- convenient methods for standard tasks (like opening, reading, writing, closing, saving workbooks, naming, adding, and copying ranges and worksheets)
|
23
|
+
- dealing with various cases of Excel and user behaviour, e.g. managing conflicts when opening workbooks (e.g. blocking or unsaved workbooks),
|
24
|
+
even with simultanously happening user interactions
|
25
|
+
- workarounds for Excel bugs and JRuby bugs
|
26
|
+
- various workbook formats, e.g. .xlsx, .xls, .xlsm are supported
|
27
|
+
- library references are supported
|
28
|
+
- console for convenient usage
|
29
|
+
|
30
|
+
== What's new?
|
31
|
+
|
32
|
+
- removing methods to operate on ranges directly from an Excel instance. However, you can use the method Excel.active_workbook to do so.
|
33
|
+
See ChangeLogs.
|
17
34
|
|
18
35
|
== Requirements
|
19
36
|
|
20
|
-
Ruby 2.1 or higher.
|
37
|
+
Ruby 2.1 or higher.
|
21
38
|
|
22
39
|
== Installation
|
23
40
|
|
data/___dummy_workbook.xls
CHANGED
Binary file
|
data/docs/README_excel.rdoc
CHANGED
@@ -124,6 +124,12 @@ or, with a block,
|
|
124
124
|
|
125
125
|
excel.each_workbook(:visible => true) {|w| puts w}
|
126
126
|
|
127
|
+
=== Accessing the active workbook
|
128
|
+
|
129
|
+
You can operate on the active workbook with help of the method Workbook#active_workbook, e.g.
|
130
|
+
|
131
|
+
workbook = excel.active_workbook
|
132
|
+
|
127
133
|
=== Bringing an Excel instance to the foreground
|
128
134
|
|
129
135
|
excel1.focus
|
data/docs/README_open.rdoc
CHANGED
@@ -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
|
-
===
|
145
|
+
=== Type-lifting WIN32OLE objects to RobustExcelOle objects
|
146
146
|
|
147
|
-
|
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
|
@@ -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
|
|
@@ -173,6 +177,18 @@ A RobustExcelOle Workbook object is a proxy of an Excel WIN32OLE workbook. A Wor
|
|
173
177
|
|
174
178
|
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
179
|
|
180
|
+
=== Opening workbooks given a network path and a hostname share path ===
|
181
|
+
|
182
|
+
RobustExcelOle allows opening workbooks via a network path starting with a drive letter different from the default drive (mostly 'C'), e.g.
|
183
|
+
|
184
|
+
workbook = Workbook.open('N:/data workbook.xls')
|
185
|
+
|
186
|
+
Likewise the corresponding hostname share path can be used, starting with '//', e.g.
|
187
|
+
|
188
|
+
workbook = Workbook.open("//DESKTOP-A5D5GJ5/spec/data/workbook.xls")
|
189
|
+
|
190
|
+
where 'DESKTOP-A5D5GJ5' shall be the hostname, and 'data' be the share.
|
191
|
+
|
176
192
|
=== Unobtrusively modifying a workbook
|
177
193
|
|
178
194
|
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.
|
data/docs/README_ranges.rdoc
CHANGED
@@ -306,9 +306,12 @@ or
|
|
306
306
|
|
307
307
|
workbook.set_namevalue_glob("name", "new_value")
|
308
308
|
|
309
|
-
|
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
|
@@ -391,6 +394,12 @@ The methods Worksheet#each, Worksheet#each_row and Worksheet#each_column enable
|
|
391
394
|
# do something with column
|
392
395
|
end
|
393
396
|
|
397
|
+
The method Worksheet#each_value accesses the values of each row.
|
398
|
+
|
399
|
+
worksheet.each_value do |row_values|
|
400
|
+
# do something with the row_values
|
401
|
+
end
|
402
|
+
|
394
403
|
You access a range of a row by giving the number of the row, and optionally, the range of the cell numbers.
|
395
404
|
|
396
405
|
worksheet.row_range(1) # => first row
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#require 'robust_excel_ole'
|
2
|
+
|
3
|
+
#workbook = Workbook.open './sample_excel_files/xlsx_500_rows.xlsx'
|
4
|
+
|
5
|
+
require_relative '../lib/robust_excel_ole'
|
6
|
+
|
7
|
+
include RobustExcelOle
|
8
|
+
|
9
|
+
workbook = Workbook.open './../spec/data/workbook.xls'
|
10
|
+
|
11
|
+
puts "Found #{workbook.worksheets_count} worksheets"
|
12
|
+
|
13
|
+
workbook.each do |worksheet|
|
14
|
+
puts "Reading: #{worksheet.name}"
|
15
|
+
num_rows = 0
|
16
|
+
|
17
|
+
worksheet.each do |row|
|
18
|
+
row_cells = row.map{ |cell| cell.value }
|
19
|
+
num_rows += 1
|
20
|
+
|
21
|
+
# uncomment to print out row values
|
22
|
+
# puts row_cells.join " "
|
23
|
+
end
|
24
|
+
puts "Read #{num_rows} rows"
|
25
|
+
end
|
26
|
+
|
27
|
+
puts 'Done'
|
data/extconf.rb
ADDED
data/lib/robust_excel_ole.rb
CHANGED
@@ -3,10 +3,11 @@ if RUBY_PLATFORM =~ /java/
|
|
3
3
|
else
|
4
4
|
require 'win32ole'
|
5
5
|
end
|
6
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/
|
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')
|
@@ -2,37 +2,38 @@
|
|
2
2
|
|
3
3
|
module RobustExcelOle
|
4
4
|
|
5
|
-
class
|
5
|
+
class AddressTool < Base
|
6
6
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
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
|
-
#
|
16
|
-
#
|
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
|
20
|
+
def as_r1c1(address)
|
20
21
|
transform_address(address,:r1c1)
|
21
22
|
end
|
22
23
|
|
23
|
-
def
|
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
|
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
|
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(
|
74
|
-
r1c1_string(
|
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
|
-
|
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
|
-
|
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(
|
97
|
-
c,d = b.split(
|
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
|
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
|
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 <
|
5
|
+
class Bookstore < Base
|
6
|
+
|
6
7
|
def initialize
|
7
8
|
@filename2books ||= Hash.new { |hash, key| hash[key] = [] }
|
8
9
|
@hidden_excel_instance = nil
|
@@ -29,11 +30,9 @@ module RobustExcelOle
|
|
29
30
|
# otherwise proceeds according to prefer_writable
|
30
31
|
def fetch(filename, options = { :prefer_writable => true })
|
31
32
|
return nil unless filename
|
32
|
-
|
33
33
|
filename = General.absolute_path(filename)
|
34
34
|
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?
|
35
|
+
weakref_books = @filename2books[filename_key]
|
37
36
|
return nil if weakref_books.nil? || weakref_books.empty?
|
38
37
|
|
39
38
|
result = open_book = closed_book = nil
|
@@ -67,68 +66,6 @@ module RobustExcelOle
|
|
67
66
|
result
|
68
67
|
end
|
69
68
|
|
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
69
|
# stores a workbook
|
133
70
|
# @param [Workbook] book a given book
|
134
71
|
def store(book)
|
@@ -138,8 +75,7 @@ module RobustExcelOle
|
|
138
75
|
# deletes the weak reference to the book
|
139
76
|
@filename2books[old_filename_key].delete(book)
|
140
77
|
end
|
141
|
-
@filename2books[filename_key] |= [WeakRef.new(book)]
|
142
|
-
book.stored_filename = book.filename
|
78
|
+
@filename2books[filename_key] |= [WeakRef.new(book)]
|
143
79
|
end
|
144
80
|
|
145
81
|
# creates and returns a separate Excel instance with Visible and DisplayAlerts equal false
|
@@ -168,7 +104,6 @@ module RobustExcelOle
|
|
168
104
|
|
169
105
|
private
|
170
106
|
|
171
|
-
# @private
|
172
107
|
def try_hidden_excel
|
173
108
|
@hidden_excel_instance.__getobj__ if @hidden_excel_instance && @hidden_excel_instance.weakref_alive? && @hidden_excel_instance.__getobj__.alive?
|
174
109
|
end
|
@@ -177,24 +112,26 @@ module RobustExcelOle
|
|
177
112
|
|
178
113
|
# prints the book store
|
179
114
|
# @private
|
180
|
-
def
|
181
|
-
#
|
115
|
+
def print_filename2books
|
116
|
+
#puts "@filename2books:"
|
182
117
|
if @filename2books
|
183
|
-
@filename2books.each do |
|
184
|
-
#
|
185
|
-
#
|
118
|
+
@filename2books.each do |filename,books|
|
119
|
+
#puts " filename: #{filename}"
|
120
|
+
#puts " books:"
|
186
121
|
if books.empty?
|
187
|
-
#
|
122
|
+
#puts " []"
|
188
123
|
else
|
189
124
|
books.each do |book|
|
190
125
|
if book.weakref_alive?
|
191
|
-
#
|
126
|
+
#puts "book.filename: #{book.filename}"
|
192
127
|
else # this should never happen
|
193
|
-
#
|
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
|