robust_excel_ole 1.26 → 1.31
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 +17 -0
- data/README.rdoc +12 -5
- data/benchmarking/reo_example.rb +1 -1
- data/benchmarking/reo_example1.rb +1 -1
- data/benchmarking/reo_example2.rb +1 -1
- data/bin/jreo +20 -1
- data/bin/reo +20 -1
- data/docs/README_open.rdoc +8 -4
- data/docs/README_sheet.rdoc +1 -7
- data/examples/introductory_examples/example_open.rb +11 -0
- data/lib/robust_excel_ole.rb +19 -16
- data/lib/robust_excel_ole/base.rb +5 -0
- data/lib/robust_excel_ole/bookstore.rb +1 -1
- data/lib/robust_excel_ole/cell.rb +1 -1
- data/lib/robust_excel_ole/cygwin.rb +2 -0
- data/lib/robust_excel_ole/excel.rb +12 -22
- data/lib/robust_excel_ole/general.rb +270 -206
- data/lib/robust_excel_ole/list_object.rb +18 -115
- data/lib/robust_excel_ole/list_row.rb +128 -0
- data/lib/robust_excel_ole/range.rb +5 -1
- data/lib/robust_excel_ole/range_owners.rb +4 -71
- data/lib/robust_excel_ole/version.rb +1 -1
- data/lib/robust_excel_ole/workbook.rb +71 -29
- data/lib/robust_excel_ole/worksheet.rb +107 -22
- data/lib/spec_helper.rb +1 -1
- data/spec/address_tool_spec.rb +2 -2
- data/spec/base_spec.rb +19 -17
- data/spec/bookstore_spec.rb +1 -1
- data/spec/cell_spec.rb +1 -1
- data/spec/cygwin_spec.rb +1 -1
- data/spec/data/more_data/workbook.xls +0 -0
- data/spec/excel_spec.rb +1 -1
- data/spec/general_spec.rb +64 -7
- data/spec/list_object_spec.rb +85 -20
- data/spec/range_spec.rb +1 -14
- data/spec/spec_helper.rb +1 -1
- data/spec/workbook_spec.rb +12 -12
- data/spec/workbook_specs/workbook_all_spec.rb +8 -28
- data/spec/workbook_specs/workbook_close_spec.rb +1 -1
- data/spec/workbook_specs/workbook_misc_spec.rb +33 -33
- data/spec/workbook_specs/workbook_open_spec.rb +56 -5
- data/spec/workbook_specs/workbook_save_spec.rb +1 -1
- data/spec/workbook_specs/workbook_sheet_spec.rb +1 -1
- data/spec/workbook_specs/workbook_subclass_spec.rb +1 -1
- data/spec/workbook_specs/workbook_unobtr_spec.rb +273 -115
- data/spec/worksheet_spec.rb +51 -19
- metadata +3 -5
- data/jreo.bat +0 -3
- data/lib/reo_console.rb +0 -68
- data/reo.bat +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 304ee26bf15359eec5e54ac846203b60f3d7419e54779ced816182f76f6e9b46
|
4
|
+
data.tar.gz: 0ea8a4d763d10b286cd29610261b815ca51308cb364483935c5c396fa31e2c67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae94a7357c87e0069e15e279a0eb420df939840192fc2e674f8e3c1890bebdaa7c49d37e0d8a888939f8009109fc7fabf0105e7b76f6b75f168431cb58d2e0e1
|
7
|
+
data.tar.gz: 450ebbad0840bd557c652cc2fa9027dee4a45114a6d3b8ea0065fd5120e9b916ad26ad63a1f97088bb148f1dc07cff7fd9cdf8c9b956e6a0ee2295be4434dec2
|
data/Changelog
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
# Change Log
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
3
|
|
4
|
+
## [1.31] 2021-14-01
|
5
|
+
|
6
|
+
### Added
|
7
|
+
- Worksheet#table
|
8
|
+
|
9
|
+
## [1.30] 2020-18-11
|
10
|
+
|
11
|
+
## [1.29] 2020-05-11
|
12
|
+
|
13
|
+
### Added
|
14
|
+
- Workbook.open can also take a Pathname object
|
15
|
+
- General#init_reo_for_win32ole
|
16
|
+
|
17
|
+
## [1.28] 2020-23-10
|
18
|
+
|
19
|
+
## [1.27] 2020-16-10
|
20
|
+
|
4
21
|
## [1.26] 2020-09-10
|
5
22
|
|
6
23
|
### Added
|
data/README.rdoc
CHANGED
@@ -320,7 +320,11 @@ For more details about reading and writing contents of cells and ranges see {REA
|
|
320
320
|
|
321
321
|
=== More features
|
322
322
|
|
323
|
-
The
|
323
|
+
1. The method +General.change_current_binding+ allows to change the value of self within the current binding, while preserving the local variables, without starting another repl. Assume, +object+ shall be the self, then you would put
|
324
|
+
|
325
|
+
General.change_current_binding(object)
|
326
|
+
|
327
|
+
Without this method, the ruby shell 'pry' allows to change the value of 'self' in the console as well, e.g.
|
324
328
|
|
325
329
|
object.pry
|
326
330
|
|
@@ -328,13 +332,16 @@ or
|
|
328
332
|
|
329
333
|
cd object
|
330
334
|
|
331
|
-
|
335
|
+
However, this command also starts another pry repl (with another binding). Moreover, local variables in the previous binding are forgotten.
|
336
|
+
|
337
|
+
|
338
|
+
2. The class Win32Ole is being extended such that RobustExcelOle methods can be applied to Win32Ole objects. As mentioned above, the RobustExcelOle objects are wrapper of corresponding WIN32OLE objects. So the RobustExcelOle objects and their wrapped Win32Ole objects are interchangeable. One example would be
|
332
339
|
|
333
|
-
|
340
|
+
range.ole_range.copy([4,3])
|
334
341
|
|
335
|
-
|
342
|
+
Likewise it is possible to convert ("type-lift") Win32Ole objects into the corresponding RobustExcelOle object, using the method +to_reo+. It is a refinement of the class WIN32OLE. So you can write
|
336
343
|
|
337
|
-
|
344
|
+
using ToReoRefinement
|
338
345
|
|
339
346
|
range = sheet.Names.Item("firstcell").to_reo
|
340
347
|
|
data/benchmarking/reo_example.rb
CHANGED
data/bin/jreo
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# -*- jruby -*-
|
3
3
|
|
4
4
|
require 'pry'
|
5
|
-
|
5
|
+
require_relative '../lib/robust_excel_ole'
|
6
6
|
|
7
7
|
include REO
|
8
8
|
include General
|
@@ -15,10 +15,29 @@ Pry.config.prompt_name = "REO "
|
|
15
15
|
#Pry.config.history_save = true
|
16
16
|
#Pry.editor = 'notepad' # 'subl', 'vi'
|
17
17
|
|
18
|
+
prompt_proc1 = proc { |target_self, nest_level, pry|
|
19
|
+
"[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> "
|
20
|
+
}
|
21
|
+
|
22
|
+
prompt_proc2 = proc { |target_self, nest_level, pry|
|
23
|
+
"[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self.inspect.gsub(/\"/, ''))})})#{":#{nest_level}" unless nest_level.zero?}* "
|
24
|
+
}
|
25
|
+
|
26
|
+
Pry.config.prompt = if RUBY_PLATFORM =~ /java/
|
27
|
+
[prompt_proc1, prompt_proc2]
|
28
|
+
else
|
29
|
+
Pry::Prompt.new(
|
30
|
+
"REO",
|
31
|
+
"The RobustExcelOle Prompt. Besides the standard information it puts the current object",
|
32
|
+
[prompt_proc1, prompt_proc2]
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
18
36
|
hooks = Pry::Hooks.new
|
19
37
|
|
20
38
|
hooks.add_hook :when_started, :hook12 do
|
21
39
|
puts 'REO console started'
|
22
40
|
puts
|
23
41
|
end
|
42
|
+
|
24
43
|
Pry.start(nil, hooks: hooks)
|
data/bin/reo
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# -*- ruby -*-
|
3
3
|
|
4
4
|
require 'pry'
|
5
|
-
|
5
|
+
require_relative '../lib/robust_excel_ole'
|
6
6
|
|
7
7
|
include REO
|
8
8
|
include General
|
@@ -15,10 +15,29 @@ Pry.config.prompt_name = "REO "
|
|
15
15
|
#Pry.config.history_save = true
|
16
16
|
#Pry.editor = 'notepad' # 'subl', 'vi'
|
17
17
|
|
18
|
+
prompt_proc1 = proc { |target_self, nest_level, pry|
|
19
|
+
"[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}> "
|
20
|
+
}
|
21
|
+
|
22
|
+
prompt_proc2 = proc { |target_self, nest_level, pry|
|
23
|
+
"[#{pry.input_ring.count}] #{pry.config.prompt_name}(#{Pry.view_clip(target_self)})#{":#{nest_level}" unless nest_level.zero?}* "
|
24
|
+
}
|
25
|
+
|
26
|
+
Pry.config.prompt = if RUBY_PLATFORM =~ /java/
|
27
|
+
[prompt_proc1, prompt_proc2]
|
28
|
+
else
|
29
|
+
Pry::Prompt.new(
|
30
|
+
"REO",
|
31
|
+
"The RobustExcelOle Prompt. Besides the standard information it puts the current object",
|
32
|
+
[prompt_proc1, prompt_proc2]
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
18
36
|
hooks = Pry::Hooks.new
|
19
37
|
|
20
38
|
hooks.add_hook :when_started, :hook12 do
|
21
39
|
puts 'REO console started'
|
22
40
|
puts
|
23
41
|
end
|
42
|
+
|
24
43
|
Pry.start(nil, hooks: hooks)
|
data/docs/README_open.rdoc
CHANGED
@@ -17,6 +17,11 @@ The semantics is similar to, e.g., +File.open+.
|
|
17
17
|
# do something
|
18
18
|
end
|
19
19
|
|
20
|
+
You can provide the filename as a string (as above) or as Pathname object.
|
21
|
+
|
22
|
+
pathname = Pathname('spec/data/workbook.xls')
|
23
|
+
workbook = Workbook.open(pathname)
|
24
|
+
|
20
25
|
The options are the following:
|
21
26
|
|
22
27
|
+:default+:: if the workbook was already open, then use the properties of this workbook.otherwise use the properties stated in +:default+
|
@@ -195,12 +200,11 @@ The method +unobtrusively+ enables the user to read or modify a workbook, no mat
|
|
195
200
|
|
196
201
|
Options are the following:
|
197
202
|
|
198
|
-
+:if_closed+:: the Excel instance in which to open the workbook, if it was closed (default: +:current+). (Note: this option works workbooks opened via RobustExcelOle only.)
|
199
|
-
|
200
203
|
+:read_only+:: Whether the workbook shall be forced to be open in ReadOnly mode
|
201
|
-
+:writable+:: Whether changes in the workbook shall be saved
|
202
|
-
|
204
|
+
+:writable+:: Whether changes in the workbook shall be saved and the workbook shall be opened in ReadOnly mode by default (i.e., when the workbook was not open before) (default: true)
|
203
205
|
+:keep_open+:: Whether the workbook shall be open after unobtrusively opening (default: false)
|
206
|
+
+:if_closed+:: the Excel instance in which to open the workbook, if it was closed (default: +:current+).
|
207
|
+
(Note: this option works workbooks opened via RobustExcelOle only.)
|
204
208
|
|
205
209
|
There are the class method and the instance method of +unobtrusively+. Here is an example of the class method:
|
206
210
|
|
data/docs/README_sheet.rdoc
CHANGED
@@ -92,17 +92,11 @@ The methods Worksheet#each, Worksheet#each_row and Worksheet#each_column enable
|
|
92
92
|
# do something with column
|
93
93
|
end
|
94
94
|
|
95
|
-
The method Worksheet#values yields
|
95
|
+
The method Worksheet#values yields a 2-dimensional array that contains the values in each row, e.g.
|
96
96
|
|
97
97
|
worksheet.values
|
98
98
|
=> [["foo", "workbook", "sheet1"], ["foo", nil, "foobaaa"], ["matz", "is", "nice"]]
|
99
99
|
|
100
|
-
The method Worksheet#each_rowvalue enables to access the values of each row.
|
101
|
-
|
102
|
-
worksheet.each_rowvalue do |row_values|
|
103
|
-
# do something with the row_values
|
104
|
-
end
|
105
|
-
|
106
100
|
You access a range of a row by giving the number of the row, and optionally, the range of the cell numbers.
|
107
101
|
|
108
102
|
worksheet.row_range(1) # => first row
|
@@ -18,7 +18,18 @@ puts "open a workbook"
|
|
18
18
|
book = Workbook.open(simple_file)
|
19
19
|
puts "make it visible"
|
20
20
|
book.visible = true
|
21
|
+
|
22
|
+
ole_workbook = book.ole_workbook
|
23
|
+
puts "ole_workbook: #{ole_workbook}"
|
24
|
+
sheet = ole_workbook.sheet(1)
|
25
|
+
puts "sheet: #{sheet}"
|
26
|
+
|
27
|
+
using ToReoRefinement
|
21
28
|
puts "book: #{book}"
|
29
|
+
ole_workbook = book.ole_workbook
|
30
|
+
puts "ole_workbook: #{ole_workbook.inspect}"
|
31
|
+
upliftet_ole_workbook = ole_workbook.to_reo
|
32
|
+
puts "upliftet_ole_workbook: #{upliftet_ole_workbook.inspect}"
|
22
33
|
# open a workbook in a new Excel instance
|
23
34
|
puts "open the workbook in a new Excel instance and make it visible"
|
24
35
|
book2 = Workbook.open(another_simple_file, :default => {:excel => :new}, :visible => true)
|
data/lib/robust_excel_ole.rb
CHANGED
@@ -1,22 +1,25 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
1
3
|
if RUBY_PLATFORM =~ /java/
|
2
4
|
require 'jruby-win32ole'
|
3
5
|
else
|
4
6
|
require 'win32ole'
|
5
7
|
end
|
6
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/base')
|
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')
|
11
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/excel')
|
12
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/bookstore')
|
13
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/workbook')
|
14
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/worksheet')
|
15
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/cell')
|
16
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/range')
|
17
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/list_object')
|
18
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/cygwin') if RUBY_PLATFORM =~ /cygwin/
|
19
|
-
require File.join(File.dirname(__FILE__), 'robust_excel_ole/version')
|
20
8
|
|
21
|
-
|
22
|
-
|
9
|
+
require_relative 'robust_excel_ole/general'
|
10
|
+
require_relative 'robust_excel_ole/base'
|
11
|
+
require_relative 'robust_excel_ole/vba_objects'
|
12
|
+
require_relative 'robust_excel_ole/range_owners'
|
13
|
+
require_relative 'robust_excel_ole/address_tool'
|
14
|
+
require_relative 'robust_excel_ole/excel'
|
15
|
+
require_relative 'robust_excel_ole/bookstore'
|
16
|
+
require_relative 'robust_excel_ole/workbook'
|
17
|
+
require_relative 'robust_excel_ole/worksheet'
|
18
|
+
require_relative 'robust_excel_ole/cell'
|
19
|
+
require_relative 'robust_excel_ole/range'
|
20
|
+
require_relative 'robust_excel_ole/list_row'
|
21
|
+
require_relative 'robust_excel_ole/list_object'
|
22
|
+
require_relative 'robust_excel_ole/cygwin' if RUBY_PLATFORM =~ /cygwin/
|
23
|
+
require_relative 'robust_excel_ole/version'
|
24
|
+
|
25
|
+
General.init_reo_for_win32ole
|
@@ -15,6 +15,7 @@ module RobustExcelOle
|
|
15
15
|
# See https://docs.microsoft.com/en-us/office/vba/api/excel.application(object)#methods
|
16
16
|
|
17
17
|
class Excel < VbaObjects
|
18
|
+
|
18
19
|
attr_reader :ole_excel
|
19
20
|
attr_reader :properties
|
20
21
|
attr_reader :address_tool
|
@@ -370,7 +371,7 @@ module RobustExcelOle
|
|
370
371
|
number = 0
|
371
372
|
WIN32OLE.connect('winmgmts:\\\\.').InstancesOf('win32_process').each do |p|
|
372
373
|
begin
|
373
|
-
if p.
|
374
|
+
if p.Name == 'EXCEL.EXE'
|
374
375
|
Process.kill('KILL', p.processid)
|
375
376
|
number += 1
|
376
377
|
end
|
@@ -384,7 +385,7 @@ module RobustExcelOle
|
|
384
385
|
|
385
386
|
def self.excels_number
|
386
387
|
processes = WIN32OLE.connect('winmgmts:\\\\.').InstancesOf('win32_process')
|
387
|
-
processes.select { |p| p.
|
388
|
+
processes.select { |p| p.Name == 'EXCEL.EXE' }.size
|
388
389
|
end
|
389
390
|
|
390
391
|
def self.known_excels_number
|
@@ -417,7 +418,7 @@ module RobustExcelOle
|
|
417
418
|
result.Visible # send any method, just to see if it responds
|
418
419
|
rescue
|
419
420
|
trace 'dead excel ' + (begin
|
420
|
-
"Window-handle = #{result.
|
421
|
+
"Window-handle = #{result.Hwnd}"
|
421
422
|
rescue
|
422
423
|
'without window handle'
|
423
424
|
end)
|
@@ -471,13 +472,13 @@ module RobustExcelOle
|
|
471
472
|
pid2excel[pid] = excel
|
472
473
|
end
|
473
474
|
processes = WIN32OLE.connect('winmgmts:\\\\.').InstancesOf('win32_process')
|
474
|
-
processes.select { |p| Excel.new(pid2excel[p.
|
475
|
+
processes.select { |p| Excel.new(pid2excel[p.ProcessId]) if p.Name == 'EXCEL.EXE' && pid2excel.include?(p.ProcessId) }
|
475
476
|
result = []
|
476
477
|
processes.each do |p|
|
477
|
-
next unless p.
|
478
|
+
next unless p.Name == 'EXCEL.EXE'
|
478
479
|
|
479
|
-
if pid2excel.include?(p.
|
480
|
-
excel = pid2excel[p.
|
480
|
+
if pid2excel.include?(p.ProcessId)
|
481
|
+
excel = pid2excel[p.ProcessId]
|
481
482
|
result << excel
|
482
483
|
end
|
483
484
|
# how to connect to an (interactively opened) Excel instance and get a WIN32OLE object?
|
@@ -684,21 +685,7 @@ module RobustExcelOle
|
|
684
685
|
# Win32API.new("user32","SetForegroundWindow","","I").call
|
685
686
|
# end
|
686
687
|
end
|
687
|
-
|
688
|
-
# returns the value of a range
|
689
|
-
# @param [String] name the name of a range
|
690
|
-
# @returns [Variant] the value of the range
|
691
|
-
def [] name
|
692
|
-
namevalue_glob(name)
|
693
|
-
end
|
694
|
-
|
695
|
-
# sets the value of a range
|
696
|
-
# @param [String] name the name of the range
|
697
|
-
# @param [Variant] value the contents of the range
|
698
|
-
def []=(name, value)
|
699
|
-
set_namevalue_glob(name, value)
|
700
|
-
end
|
701
|
-
|
688
|
+
|
702
689
|
# @private
|
703
690
|
# returns active workbook
|
704
691
|
def workbook
|
@@ -717,6 +704,9 @@ module RobustExcelOle
|
|
717
704
|
to_s
|
718
705
|
end
|
719
706
|
|
707
|
+
using ParentRefinement
|
708
|
+
using StringRefinement
|
709
|
+
|
720
710
|
# @private
|
721
711
|
def self.workbook_class
|
722
712
|
@workbook_class ||= begin
|
@@ -1,78 +1,163 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
+
require 'pathname'
|
2
3
|
|
3
|
-
|
4
|
+
# @private
|
5
|
+
#class WIN32OLE
|
6
|
+
module ToReoRefinement
|
4
7
|
|
5
|
-
|
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
|
-
NetworkDrive = Struct.new(:drive_letter, :network_name) do
|
8
|
+
refine WIN32OLE do
|
15
9
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
# type-lifting WIN32OLE objects to RobustExcelOle objects
|
11
|
+
def to_reo
|
12
|
+
General.class2method.each do |element|
|
13
|
+
classname = element.first.first
|
14
|
+
method = element.first.last
|
15
|
+
begin
|
16
|
+
self.send(method)
|
17
|
+
if classname == RobustExcelOle::Range && self.Rows.Count == 1 && self.Columns.Count == 1
|
18
|
+
return Cell.new(self, self.Parent)
|
19
|
+
else
|
20
|
+
return classname.new(self)
|
21
|
+
end
|
22
|
+
rescue
|
23
|
+
next
|
24
|
+
end
|
21
25
|
end
|
22
|
-
|
26
|
+
raise TypeREOError, "given object cannot be type-lifted to a RobustExcelOle object"
|
23
27
|
end
|
24
28
|
|
25
29
|
end
|
26
30
|
|
27
|
-
|
28
|
-
def hostnameshare2networkpath(filename)
|
29
|
-
return filename unless filename[0,2] == "//"
|
30
|
-
network = WIN32OLE.new('WScript.Network')
|
31
|
-
drives = network.enumnetworkdrives
|
32
|
-
network_drives = NetworkDrive.get_all(drives)
|
33
|
-
f_c = filename.dup
|
34
|
-
network_drive = network_drives.find do |d|
|
35
|
-
e = f_c.sub!(d.network_name,d.drive_letter)
|
36
|
-
return e if e
|
37
|
-
end
|
38
|
-
filename
|
39
|
-
end
|
31
|
+
end
|
40
32
|
|
41
|
-
|
42
|
-
|
43
|
-
return file if file[0,2] == "//"
|
44
|
-
file[0,2] = './' if ::EXPANDPATH_JRUBY_BUG && file =~ /[A-Z]:[^\/]/
|
45
|
-
file = File.expand_path(file)
|
46
|
-
file = RobustExcelOle::Cygwin.cygpath('-w', file) if RUBY_PLATFORM =~ /cygwin/
|
47
|
-
WIN32OLE.new('Scripting.FileSystemObject').GetAbsolutePathName(file) #.tr('/','\\')
|
48
|
-
end
|
33
|
+
# @private
|
34
|
+
class WIN32OLE
|
49
35
|
|
50
|
-
|
51
|
-
def canonize(filename)
|
52
|
-
raise TypeREOError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
|
53
|
-
filename = hostnameshare2networkpath(filename)
|
54
|
-
normalize(filename) if filename
|
55
|
-
end
|
36
|
+
include Enumerable
|
56
37
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
38
|
+
end
|
39
|
+
|
40
|
+
# @private
|
41
|
+
module FindAllIndicesRefinement
|
42
|
+
|
43
|
+
refine Array do
|
44
|
+
|
45
|
+
def find_all_indices elem
|
46
|
+
found, index, result = -1, -1, []
|
47
|
+
while found
|
48
|
+
found = self[index+1..-1].index(elem)
|
49
|
+
if found
|
50
|
+
index = index + found + 1
|
51
|
+
result << index
|
52
|
+
end
|
53
|
+
end
|
54
|
+
result
|
55
|
+
end
|
66
56
|
|
67
|
-
def change_current_binding(current_object)
|
68
|
-
Pry.change_current_binding(current_object)
|
69
57
|
end
|
70
58
|
|
71
|
-
|
59
|
+
end
|
60
|
+
|
61
|
+
# @private
|
62
|
+
module StringRefinement
|
63
|
+
|
64
|
+
refine String do
|
65
|
+
|
66
|
+
def / path_part
|
67
|
+
if empty?
|
68
|
+
path_part
|
69
|
+
else
|
70
|
+
if path_part.nil? || path_part.empty?
|
71
|
+
self
|
72
|
+
else
|
73
|
+
begin
|
74
|
+
path_part = path_part.strip
|
75
|
+
(path_part =~ /^(\/|([A-Z]:\/))/i) ? path_part : (self.chomp('/') + '/' + path_part)
|
76
|
+
rescue TypeError
|
77
|
+
raise TypeError, "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def replace_umlauts
|
84
|
+
word = self.force_encoding('iso-8859-1').encode('utf-8')
|
85
|
+
#word = self.encode("UTF-8")
|
86
|
+
#word = self.encode("UTF-8", "Windows-1252")
|
87
|
+
word.gsub('ä','ae').gsub('Ä','Ae').gsub('ö','oe').gsub('Ö','Oe').gsub('ü','ue').gsub('Ü','Ue')
|
88
|
+
word.gsub('ß','ss').gsub('²','2').gsub('³','3')
|
89
|
+
#word.gsub("\x84",'ae').gsub("\x8E",'Ae').gsub("\x94",'oe').gsub("\x99",'Oe').gsub("\x81",'ue').gsub("\x9A",'Ue')
|
90
|
+
#word.gsub("\xE1",'ss').gsub("\xFD",'2').gsub("\xFC",'3')
|
91
|
+
word
|
92
|
+
end
|
93
|
+
|
94
|
+
# taken from http://apidock.com/rails/ActiveSupport/Inflector/underscore
|
95
|
+
def underscore
|
96
|
+
word = gsub('::', '/')
|
97
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
98
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
99
|
+
word.tr!('-', '_')
|
100
|
+
word.downcase!
|
101
|
+
word
|
102
|
+
end
|
72
103
|
|
104
|
+
# taken from http://apidock.com/rails/ActiveSupport/Inflector/constantize
|
105
|
+
# File activesupport/lib/active_support/inflector/methods.rb, line 226
|
106
|
+
def constantize # (camel_cased_word)
|
107
|
+
names = split('::')
|
108
|
+
|
109
|
+
# Trigger a builtin NameError exception including the ill-formed constant in the message.
|
110
|
+
Object.const_get(self) if names.empty?
|
111
|
+
|
112
|
+
# Remove the first blank element in case of '::ClassName' notation.
|
113
|
+
names.shift if names.size > 1 && names.first.empty?
|
114
|
+
|
115
|
+
names.inject(Object) do |constant, name|
|
116
|
+
if constant == Object
|
117
|
+
constant.const_get(name)
|
118
|
+
else
|
119
|
+
candidate = constant.const_get(name)
|
120
|
+
next candidate if constant.const_defined?(name)
|
121
|
+
next candidate unless Object.const_defined?(name)
|
122
|
+
|
123
|
+
# Go down the ancestors to check it it's owned
|
124
|
+
# directly before we reach Object or the end of ancestors.
|
125
|
+
constant = constant.ancestors.inject do |const, ancestor|
|
126
|
+
break const if ancestor == Object
|
127
|
+
break ancestor if ancestor.const_defined?(name)
|
128
|
+
|
129
|
+
const
|
130
|
+
end
|
131
|
+
|
132
|
+
# owner is in Object, so raise
|
133
|
+
constant.const_get(name)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
73
138
|
end
|
74
139
|
|
75
140
|
# @private
|
141
|
+
module ParentRefinement
|
142
|
+
|
143
|
+
using StringRefinement
|
144
|
+
|
145
|
+
# taken from http://api.rubyonrails.org/v2.3.8/classes/ActiveSupport/CoreExtensions/Module.html#M000806
|
146
|
+
refine Module do
|
147
|
+
|
148
|
+
def parent_name
|
149
|
+
unless defined? @parent_name
|
150
|
+
@parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
151
|
+
end
|
152
|
+
@parent_name
|
153
|
+
end
|
154
|
+
|
155
|
+
def parent
|
156
|
+
parent_name ? parent_name.constantize : Object
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
76
161
|
class Integer
|
77
162
|
|
78
163
|
alias old_spaceship <=>
|
@@ -102,183 +187,164 @@ class Array
|
|
102
187
|
end
|
103
188
|
end
|
104
189
|
|
105
|
-
def find_each_index find
|
106
|
-
found, index, q = -1, -1, []
|
107
|
-
while found
|
108
|
-
found = self[index+1..-1].index(find)
|
109
|
-
if found
|
110
|
-
index = index + found + 1
|
111
|
-
q << index
|
112
|
-
end
|
113
|
-
end
|
114
|
-
q
|
115
|
-
end
|
116
190
|
end
|
117
191
|
|
118
|
-
# @private
|
119
|
-
class WIN32OLE
|
120
192
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
next
|
193
|
+
module General
|
194
|
+
|
195
|
+
using ToReoRefinement
|
196
|
+
|
197
|
+
IS_JRUBY_PLATFORM = (RUBY_PLATFORM =~ /java/)
|
198
|
+
::EXPANDPATH_JRUBY_BUG = IS_JRUBY_PLATFORM && true
|
199
|
+
::CONNECT_JRUBY_BUG = IS_JRUBY_PLATFORM && true
|
200
|
+
::COPYSHEETS_JRUBY_BUG = IS_JRUBY_PLATFORM && true
|
201
|
+
::ERRORMESSAGE_JRUBY_BUG = IS_JRUBY_PLATFORM && true
|
202
|
+
::CONNECT_EXCEL_JRUBY_BUG = IS_JRUBY_PLATFORM && true
|
203
|
+
::RANGES_JRUBY_BUG = IS_JRUBY_PLATFORM && true
|
204
|
+
|
205
|
+
# @private
|
206
|
+
NetworkDrive = Struct.new(:drive_letter, :network_name) do
|
207
|
+
|
208
|
+
def self.get_all_drives
|
209
|
+
network = WIN32OLE.new('WScript.Network')
|
210
|
+
drives = network.enumnetworkdrives
|
211
|
+
ndrives = []
|
212
|
+
count = drives.Count
|
213
|
+
(0..(count - 1)).step(2) do |i|
|
214
|
+
ndrives << NetworkDrive.new( drives.Item(i), drives.Item(i + 1).tr('\\','/'))
|
144
215
|
end
|
216
|
+
ndrives
|
145
217
|
end
|
146
|
-
raise TypeREOError, "given object cannot be type-lifted to a RobustExcelOle object"
|
147
218
|
end
|
148
219
|
|
149
|
-
|
150
|
-
def
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
=
|
163
|
-
|
164
|
-
|
165
|
-
def method_missing(name, *args, &blk)
|
166
|
-
puts "method_missing:"
|
167
|
-
puts "name: #{name.inspect}"
|
168
|
-
#raise NoMethodError if name.to_s == "Hwnd" or name.to_s == "FullName" or name.to_s == "UsedRange" or name.to_s == "Row" or name.to_s == "ListRows"
|
169
|
-
begin
|
170
|
-
reo_obj = self.to_reo
|
171
|
-
puts "reo_obj: #{reo_obj.inspect}"
|
172
|
-
rescue
|
173
|
-
puts "$!.message: #{$!.message}"
|
174
|
-
method_missing_before_implicit_typelift(name, *args, &blk)
|
175
|
-
end
|
176
|
-
reo_obj.send(name, *args, &blk)
|
220
|
+
# @private
|
221
|
+
def hostnameshare2networkpath(filename)
|
222
|
+
return filename unless filename[0,2] == "//"
|
223
|
+
NetworkDrive.get_all_drives.inject(filename) do |fn_modified, d|
|
224
|
+
fn_modified.sub(/#{(Regexp.escape(d.network_name))}/i,d.drive_letter)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# @private
|
229
|
+
def absolute_path(file)
|
230
|
+
file = file.to_path if file.respond_to?(:to_path)
|
231
|
+
return file if file[0,2] == "//"
|
232
|
+
file[0,2] = './' if ::EXPANDPATH_JRUBY_BUG && file =~ /[A-Z]:[^\/]/
|
233
|
+
file = File.expand_path(file)
|
234
|
+
file = RobustExcelOle::Cygwin.cygpath('-w', file) if RUBY_PLATFORM =~ /cygwin/
|
235
|
+
WIN32OLE.new('Scripting.FileSystemObject').GetAbsolutePathName(file) #.tr('/','\\')
|
177
236
|
end
|
178
|
-
=end
|
179
237
|
|
180
|
-
|
238
|
+
# @private
|
239
|
+
def canonize(filename)
|
240
|
+
raise TypeREOError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
|
241
|
+
filename = hostnameshare2networkpath(filename)
|
242
|
+
normalize(filename) if filename
|
243
|
+
end
|
181
244
|
|
182
|
-
# @private
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
else
|
191
|
-
begin
|
192
|
-
File.join self, path_part
|
193
|
-
rescue TypeError
|
194
|
-
raise TypeError, "Only strings can be parts of paths (given: #{path_part.inspect} of class #{path_part.class})"
|
195
|
-
end
|
196
|
-
end
|
197
|
-
end
|
245
|
+
# @private
|
246
|
+
def normalize(path)
|
247
|
+
return unless path
|
248
|
+
path = path.gsub('/./', '/') + '/'
|
249
|
+
path = path.gsub(/[\/\\]+/, '/')
|
250
|
+
nil while path.gsub!(/(\/|^)(?!\.\.?)([^\/]+)\/\.\.\//, '\1')
|
251
|
+
path = path.chomp('/')
|
252
|
+
path
|
198
253
|
end
|
199
254
|
|
200
|
-
#
|
201
|
-
def
|
202
|
-
|
203
|
-
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
|
204
|
-
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
205
|
-
word.tr!('-', '_')
|
206
|
-
word.downcase!
|
207
|
-
word
|
255
|
+
# @private
|
256
|
+
def change_current_binding(current_object)
|
257
|
+
Pry.change_current_binding(current_object)
|
208
258
|
end
|
209
259
|
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
260
|
+
# @private
|
261
|
+
def class2method
|
262
|
+
[{RobustExcelOle::Excel => :Hwnd},
|
263
|
+
{RobustExcelOle::Workbook => :FullName},
|
264
|
+
{RobustExcelOle::Worksheet => :UsedRange},
|
265
|
+
{RobustExcelOle::Range => :Row},
|
266
|
+
{RobustExcelOle::ListObject => :ListRows}]
|
216
267
|
end
|
217
268
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
#word.gsub!(/\x9A/,'Ue')
|
232
|
-
word
|
269
|
+
# @private
|
270
|
+
# enable RobustExcelOle methods to Win32Ole objects
|
271
|
+
def init_reo_for_win32ole
|
272
|
+
class2method.each do |element|
|
273
|
+
classname = element.first.first
|
274
|
+
meths = (classname.instance_methods(false) - WIN32OLE.instance_methods(false) - Object.methods - Enumerable.instance_methods(false) - [:Calculation=])
|
275
|
+
meths.each do |inst_method|
|
276
|
+
WIN32OLE.send(:define_method, inst_method) do |*args, &blk|
|
277
|
+
self.to_reo.send(inst_method, *args, &blk)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
nil
|
233
282
|
end
|
234
283
|
|
235
|
-
|
236
|
-
|
237
|
-
def constantize # (camel_cased_word)
|
238
|
-
names = split('::')
|
284
|
+
module_function :absolute_path, :canonize, :normalize, :change_current_binding, :class2method,
|
285
|
+
:init_reo_for_win32ole, :hostnameshare2networkpath, :test
|
239
286
|
|
240
|
-
|
241
|
-
Object.const_get(self) if names.empty?
|
287
|
+
end
|
242
288
|
|
243
|
-
# Remove the first blank element in case of '::ClassName' notation.
|
244
|
-
names.shift if names.size > 1 && names.first.empty?
|
245
289
|
|
246
|
-
|
247
|
-
|
248
|
-
constant.const_get(name)
|
249
|
-
else
|
250
|
-
candidate = constant.const_get(name)
|
251
|
-
next candidate if constant.const_defined?(name)
|
252
|
-
next candidate unless Object.const_defined?(name)
|
290
|
+
# @private
|
291
|
+
class Pry
|
253
292
|
|
254
|
-
|
255
|
-
|
256
|
-
constant = constant.ancestors.inject do |const, ancestor|
|
257
|
-
break const if ancestor == Object
|
258
|
-
break ancestor if ancestor.const_defined?(name)
|
293
|
+
# change the current binding such that self is the current object in the pry-instance,
|
294
|
+
# preserve the local variables
|
259
295
|
|
260
|
-
|
261
|
-
|
296
|
+
class << self
|
297
|
+
attr_accessor :pry_instance
|
298
|
+
end
|
262
299
|
|
263
|
-
|
264
|
-
|
265
|
-
|
300
|
+
def self.change_current_binding(current_object)
|
301
|
+
pry_instance = self.pry_instance
|
302
|
+
old_binding = pry_instance.binding_stack.pop
|
303
|
+
pry_instance.push_binding(current_object.__binding__)
|
304
|
+
exclude_vars = [:__, :_, :_dir, :_dir_, :_file, :_file_, :_in_, :_out_, :_ex, :_ex_, :pry_instance]
|
305
|
+
old_binding.local_variables.each do |var|
|
306
|
+
pry_instance.add_sticky_local(var) {old_binding.local_variable_get(var)} unless exclude_vars.include?(var)
|
266
307
|
end
|
308
|
+
self.pry_instance = pry_instance
|
309
|
+
nil
|
267
310
|
end
|
268
|
-
end
|
269
311
|
|
270
|
-
|
271
|
-
#
|
272
|
-
class
|
273
|
-
|
274
|
-
unless defined? @parent_name
|
275
|
-
@parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
276
|
-
end
|
277
|
-
@parent_name
|
312
|
+
def push_initial_binding(target = nil)
|
313
|
+
# memorize the current pry instance
|
314
|
+
self.class.pry_instance = self
|
315
|
+
push_binding(target || Pry.toplevel_binding)
|
278
316
|
end
|
279
317
|
|
280
|
-
|
281
|
-
|
318
|
+
class REPL
|
319
|
+
|
320
|
+
def read
|
321
|
+
@indent.reset if pry.eval_string.empty?
|
322
|
+
current_prompt = pry.select_prompt
|
323
|
+
indentation = pry.config.auto_indent ? @indent.current_prefix : ''
|
324
|
+
val = read_line("#{current_prompt}#{indentation}")
|
325
|
+
# Return nil for EOF, :no_more_input for error, or :control_c for <Ctrl-C>
|
326
|
+
return val unless val.is_a?(String)
|
327
|
+
if pry.config.auto_indent
|
328
|
+
original_val = "#{indentation}#{val}"
|
329
|
+
indented_val = @indent.indent(val)
|
330
|
+
|
331
|
+
if output.tty? &&
|
332
|
+
pry.config.correct_indent &&
|
333
|
+
Pry::Helpers::BaseHelpers.use_ansi_codes?
|
334
|
+
# avoid repeating read line
|
335
|
+
|
336
|
+
#output.print @indent.correct_indentation(
|
337
|
+
# current_prompt,
|
338
|
+
# indented_val,
|
339
|
+
# calculate_overhang(current_prompt, original_val, indented_val)
|
340
|
+
#)
|
341
|
+
output.flush
|
342
|
+
end
|
343
|
+
else
|
344
|
+
indented_val = val
|
345
|
+
end
|
346
|
+
indented_val
|
347
|
+
end
|
282
348
|
end
|
283
349
|
end
|
284
350
|
|
@@ -302,5 +368,3 @@ module MethodHelpers
|
|
302
368
|
end
|
303
369
|
end
|
304
370
|
end
|
305
|
-
|
306
|
-
REO = RobustExcelOle
|