robust_excel_ole 1.19 → 1.19.1

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: c5ff7771ae8a35d2cf47dce37e92a9d4d720148faa91eb37dc2342b1239f7d0a
4
- data.tar.gz: 4d50eb99f297d38a60845eca2550a36ae2734694b538c52eb23052a9e9db0077
3
+ metadata.gz: cc09b14fea1e80ffe22d0f47b5b5155b044b669ecabdd882995a966480516085
4
+ data.tar.gz: 85b55ef13fc3506b2fce3271e1f1c40cd97c3dd872dff4d79a953dbcef68d58b
5
5
  SHA512:
6
- metadata.gz: 2ccd9358b7d0ca576c8120e249c7af4122c4040f51357efc339536f93cde6d8a6b9a2bb32071382f5c5d8ddc3f084920831eda36df0c1a8ed9698972cea9d516
7
- data.tar.gz: f1b813c71610b01d3bfd7e70245a52b02522910b2d0cbd6a9742825c06a131f47bc7f9310c59749b0caf881fef6d8a8bc64336f709ba2104a4f78bff844a44b6
6
+ metadata.gz: 7ec786a35f9ce637f0bdc745f6ef4bb3c683d9cbe6242a2a0bc9a27636c72b1d95e7b47bf8c49c3cc188d9e09406b5ef270abbce7a7d71ad32ec0e0277c15aae
7
+ data.tar.gz: cb64cb1d4068da94c0ea6765e6626078c5cc8672bc40c5c18f6962cc5cbcf14c4be4a5032302e8936f5012a54d0891aff9a0914452d2400471ddece1a3a22865
data/.gitignore CHANGED
@@ -10,3 +10,4 @@ doc/*
10
10
  .yardoc
11
11
  TodoList.md
12
12
  spec/data/*.xls*
13
+ spec/data/workbook_listobjects.xlsx
data/Changelog CHANGED
@@ -2,7 +2,12 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
4
 
5
- ## [1.19] 2020-30-5
5
+ ## [1.20] 2020-31.-8
6
+
7
+ ### Added
8
+ - ListObject
9
+
10
+ ## [1.19] 2020-10-6
6
11
 
7
12
  ### Added
8
13
  - Workheet#values, each_rowvalue
@@ -11,7 +11,7 @@ It supports handling workbooks across Excel instances by keeping track of workbo
11
11
 
12
12
  Library references are supported.
13
13
 
14
- RobustExcelOle works by sending VBA methods via Win32OLE.
14
+ RobustExcelOle works by sending VBA methods via Win32OlE.
15
15
  Therefore, it runs on Windows only.
16
16
 
17
17
  == Features
@@ -20,17 +20,18 @@ RobustExcelOle supports
20
20
 
21
21
  - opening and processing workbooks across various Excel instances
22
22
  - standard tasks like opening, reading, writing, saving, closing workbooks
23
+ - dealing with simultanously happening user interactions
23
24
  - dealing with various cases of Excel and user behaviour
24
25
  - managing conflicts when opening workbooks (e.g. blocking or unsaved workbooks)
25
- - dealing with simultanously happening user interactions
26
26
  - workarounds for Excel bugs and JRuby bugs
27
27
  - availability of all VBA methods
28
- - availability of Excel constants (in form if Ruby constants: Excel constant.capitalize)
29
- - standard Excel file formats (.xlsx, .xls, .xlsm)
28
+ - availability of the Excel constants (in form if Ruby constants: Excel constant.capitalize)
29
+ - all standard Excel file formats (.xlsx, .xls, .xlsm)
30
+ - list objects
30
31
  - reopening workbooks after closing them
31
32
  - unobtrusively opening workbooks, i.e. opening and processing workbooks
32
- while preserving their status, e.g. saved status
33
- - reading and writing workbooks, worksheets, cells, ranges, rows, columns
33
+ while preserving their status, e.g. saved, readonly
34
+ - reading and writing workbooks, worksheets, list objects, ranges, rows, columns, cells
34
35
  - naming, adding, and copying ranges and worksheets
35
36
  - references to other Excel libraries
36
37
  - console for interactive mode
@@ -313,10 +314,37 @@ and set another value to that range.
313
314
 
314
315
  For more details about reading and writing contents of cells and ranges see {README_ranges}[https://github.com/Thomas008/robust_excel_ole/blob/master/docs/README_ranges.rdoc]
315
316
 
317
+ === Reading and writing list objects
318
+
319
+ We can define a list object (or table) from scratch.
320
+
321
+ table = ListObject.new(worksheet, "table 1", [1,1], 3,["Person","Amount"])
322
+
323
+ This command creates a list object in worksheet named "table 1", with upper left corner at position [1,1] (first cell), with 3 rows and the columns "Person" and "Amount".
324
+
325
+ A row in this table can be accessed with help of [], e.g.
326
+
327
+ table[1]
328
+
329
+ Now we can set and get the value of a cell of the table, e.g.
330
+
331
+ table[1].person = "John"
332
+ table[1].person
333
+ # => "John"
334
+
335
+ Likewise we can get a table with help of an existing Win32OlE table.
336
+
337
+ ole_listobject = worksheet.ListObjects.Item("Table 1")
338
+ table = ListObject.new(ole_listobject)
339
+
340
+ r4 = t4[1]
341
+ r4.person
342
+ # =>
343
+ r.person = "John"
316
344
 
317
345
  === More things
318
346
 
319
- You can convert some win32ole objects into a RobustExcelOle object.
347
+ You can convert some Win32Ole objects into a RobustExcelOle object.
320
348
 
321
349
  range = sheet.Names.Item("firstcell").to_reo
322
350
 
data/bin/reo CHANGED
@@ -1,61 +1,4 @@
1
- #!/usr/bin/env jruby
2
- # -*- mode: jruby -*-
1
+ @echo off
3
2
 
4
- require 'robust_excel_ole'
5
- include REO
6
- # include RobustExcelOle
7
- include General
3
+ irb -f -r ../lib/reo_console.rb
8
4
 
9
- require 'irb'
10
- require 'irb/completion'
11
- require 'irb/ext/save-history'
12
-
13
- ARGV.concat ['--readline',
14
- '--prompt-mode',
15
- 'simple']
16
-
17
- # 250 entries in the list
18
- IRB.conf[:SAVE_HISTORY] = 250
19
-
20
- # Store results in home directory with specified file name
21
- # IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history"
22
- IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.reo-history"
23
-
24
- # @private
25
- module Readline
26
- module Hist
27
- LOG = IRB.conf[:HISTORY_FILE]
28
- # LOG = "#{ENV['HOME']}/.irb-history"
29
-
30
- def self.write_log(line)
31
- File.open(LOG, 'ab') do |f|
32
- f << "#{line}
33
- "
34
- end
35
- end
36
-
37
- def self.start_session_log
38
- timestamp = proc { Time.now.strftime('%Y-%m-%d, %H:%M:%S') }
39
- # @private
40
- class <<timestamp
41
- alias_method :to_s, :call
42
- end
43
- write_log("###### session start: #{timestamp}")
44
- at_exit { write_log("###### session stop: #{timestamp}") }
45
- end
46
- end
47
-
48
- alias old_readline readline
49
- def readline(*args)
50
- ln = old_readline(*args)
51
- begin
52
- Hist.write_log(ln)
53
- rescue StandardError
54
- end
55
- ln
56
- end
57
- end
58
-
59
- Readline::Hist.start_session_log
60
- puts 'REO console started'
61
- IRB.start
@@ -1,4 +1,4 @@
1
- require '../robust_excel_ole/lib/robust_excel_ole'
1
+ require '../../robust_excel_ole/lib/robust_excel_ole'
2
2
  include REO
3
3
  # include RobustExcelOle
4
4
  include General
@@ -18,7 +18,7 @@ IRB.conf[:SAVE_HISTORY] = 250
18
18
  # IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.irb-history"
19
19
  IRB.conf[:HISTORY_FILE] = "#{ENV['HOME']}/.reo-history"
20
20
 
21
- IRB.conf[:PROMPT_MODE] = 'ert' #:SIMPLE
21
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
22
22
  #IRB.conf[:USE_READLINE] = true
23
23
  #IRB.conf[:AUTO_INDENT] = true
24
24
 
@@ -58,6 +58,5 @@ module Readline
58
58
  end
59
59
 
60
60
  Readline::Hist.start_session_log
61
- puts 'REO console started'
62
- IRB.start
63
-
61
+ puts 'REO console started: the changed one'
62
+ #IRB.start
@@ -14,6 +14,7 @@ require File.join(File.dirname(__FILE__), 'robust_excel_ole/workbook')
14
14
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/worksheet')
15
15
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/cell')
16
16
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/range')
17
+ require File.join(File.dirname(__FILE__), 'robust_excel_ole/list_object')
17
18
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/cygwin') if RUBY_PLATFORM =~ /cygwin/
18
19
  require File.join(File.dirname(__FILE__), 'robust_excel_ole/version')
19
20
 
@@ -98,7 +98,13 @@ class WIN32OLE
98
98
 
99
99
  # type-lifting WIN32OLE objects to RobustExcelOle objects
100
100
  def to_reo
101
- class2method = [{Excel => :Hwnd}, {Workbook => :FullName}, {Worksheet => :Copy}, {RobustExcelOle::Range => :Row}]
101
+ class2method = [
102
+ {Excel => :Hwnd},
103
+ {Workbook => :FullName},
104
+ {Worksheet => :Copy},
105
+ {RobustExcelOle::Range => :Row},
106
+ {ListObject => :ListRows}
107
+ ]
102
108
  class2method.each do |element|
103
109
  classname = element.first.first
104
110
  method = element.first.last
@@ -0,0 +1,129 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ module RobustExcelOle
4
+
5
+ class ListRow
6
+ end
7
+
8
+ # This class essentially wraps a Win32Ole ListObject.
9
+ # You can apply all VBA methods (starting with a capital letter)
10
+ # that you would apply for a ListObject.
11
+ # See https://docs.microsoft.com/en-us/office/vba/api/excel.listobject#methods
12
+
13
+ class ListObject < VbaObjects
14
+
15
+ attr_reader :ole_table
16
+
17
+ # constructs a list object (or table).
18
+ # @param [Variable] worksheet_or_ole_listobject a worksheet or a Win32Ole list object
19
+ # @param [Variable] table_name_or_number a table name or table number
20
+ # @param [Array] position a position of the upper left corner
21
+ # @param [Integer] rows_count number of rows
22
+ # @param [Variable] columns_count_or_names number of columns or array of column names
23
+ # @return [ListObject] a ListObject object
24
+ def initialize(worksheet_or_ole_listobject,
25
+ table_name_or_number = "",
26
+ position = [1,1],
27
+ rows_count = 1,
28
+ columns_count_or_names = 1)
29
+
30
+ if (worksheet_or_ole_listobject.ListRows rescue nil)
31
+ @ole_table = worksheet_or_ole_listobject
32
+ else
33
+ @worksheet = worksheet_or_ole_listobject.to_reo
34
+ @ole_table = @worksheet.ListObjects.Item(table_name_or_number) rescue nil
35
+ end
36
+ unless @ole_table
37
+ columns_count =
38
+ columns_count_or_names.is_a?(Integer) ? columns_count_or_names : columns_count_or_names.length
39
+ column_names = columns_count_or_names.respond_to?(:first) ? columns_count_or_names : []
40
+ begin
41
+ listobjects = @worksheet.ListObjects
42
+ @ole_table = listobjects.Add(XlSrcRange,
43
+ @worksheet.range([position[0]..position[0]+rows_count-1,
44
+ position[1]..position[1]+columns_count-1]).ole_range,
45
+ XlYes)
46
+ @ole_table.Name = table_name_or_number
47
+ @ole_table.HeaderRowRange.Value = [column_names] unless column_names.empty?
48
+ rescue WIN32OLERuntimeError => msg # , Java::OrgRacobCom::ComFailException => msg
49
+ raise TableError, "error #{$!.message}"
50
+ end
51
+ end
52
+
53
+ ole_table = @ole_table
54
+ @row_class = Class.new(ListRow) do
55
+
56
+ @@ole_table = ole_table
57
+
58
+ def initialize(row_number)
59
+ @ole_listrow = @@ole_table.ListRows.Item(row_number)
60
+ end
61
+
62
+ def method_missing(name, *args)
63
+ name_before_last_equal = name.to_s.split('=').first
64
+ column_names = @@ole_table.HeaderRowRange.Value.first
65
+ method_names = column_names.map{|c| c.underscore.gsub(/[^[\w\d]]/, '_')}
66
+ column_name = column_names[method_names.index(name_before_last_equal)]
67
+ if column_name
68
+ ole_cell = @@ole_table.Application.Intersect(
69
+ @ole_listrow.Range, @@ole_table.ListColumns(column_name).Range)
70
+ define_getting_setting_method(ole_cell,name.to_s)
71
+ self.send(name, *args)
72
+ else
73
+ super
74
+ end
75
+ end
76
+
77
+ def define_getting_setting_method(ole_cell,name_str)
78
+ if name_str[-1] != '='
79
+ self.class.define_method(name_str) do
80
+ ole_cell.Value
81
+ end
82
+ else
83
+ self.class.define_method(name_str) do |value|
84
+ ole_cell.Value = value
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ # accesses a table row object
91
+ # @param [Integer] a row number (>= 1)
92
+ # @return [ListRow] a object of dynamically constructed class with superclass ListRow
93
+ def [] row_number
94
+ @row_class.new(row_number)
95
+ end
96
+
97
+ end
98
+
99
+ private
100
+
101
+ def method_missing(name, *args)
102
+ if name.to_s[0,1] =~ /[A-Z]/
103
+ if ::ERRORMESSAGE_JRUBY_BUG
104
+ begin
105
+ @ole_table.send(name, *args)
106
+ rescue Java::OrgRacobCom::ComFailException
107
+ raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
108
+ end
109
+ else
110
+ begin
111
+ @ole_table.send(name, *args)
112
+ rescue NoMethodError
113
+ raise VBAMethodMissingError, "unknown VBA property or method #{name.inspect}"
114
+ end
115
+ end
116
+ else
117
+ super
118
+ end
119
+ end
120
+ end
121
+
122
+ # @private
123
+ class TableError < WorksheetREOError
124
+ end
125
+
126
+ Table = ListObject
127
+ TableRow = ListRow
128
+
129
+ end
@@ -1,3 +1,3 @@
1
1
  module RobustExcelOle
2
- VERSION = "1.19"
2
+ VERSION = "1.19.1"
3
3
  end
@@ -20,6 +20,7 @@ module RobustExcelOle
20
20
 
21
21
  before do
22
22
  @dir = create_tmpdir
23
+ @listobject_file = @dir + '/workbook_listobjects.xlsx'
23
24
  @simple_file = @dir + '/workbook.xls'
24
25
  @simple_save_file = @dir + '/workbook_save.xls'
25
26
  @different_file = @dir + '/different_workbook.xls'
@@ -39,6 +40,17 @@ module RobustExcelOle
39
40
 
40
41
  before do
41
42
  @book1 = Workbook.open(@simple_file)
43
+ @book2 = Workbook.open(@listobject_file)
44
+ end
45
+
46
+ it "should type-lift an ListObject" do
47
+ worksheet = @book2.sheet(3)
48
+ ole_table = worksheet.ListObjects.Item(1)
49
+ table = Table.new(ole_table)
50
+ table.Name.should == "table3"
51
+ table.HeaderRowRange.Value.first.should == ["Number","Person","Amount","Time","Date"]
52
+ table.ListRows.Count.should == 6
53
+ worksheet[3,4].Value.should == "Number"
42
54
  end
43
55
 
44
56
  it "should type-lift an Excel" do
@@ -0,0 +1,143 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require File.join(File.dirname(__FILE__), './spec_helper')
4
+
5
+ $VERBOSE = nil
6
+
7
+ include RobustExcelOle
8
+ include General
9
+
10
+ describe ListObject do
11
+
12
+ before(:all) do
13
+ excel = Excel.new(:reuse => true)
14
+ open_books = excel == nil ? 0 : excel.Workbooks.Count
15
+ puts "*** open books *** : #{open_books}" if open_books > 0
16
+ Excel.kill_all
17
+ end
18
+
19
+ before do
20
+ @dir = create_tmpdir
21
+ @listobject_file = @dir + '/workbook_listobjects.xlsx'
22
+ @book = Workbook.open(@listobject_file, :visible => true)
23
+ @sheet = @book.sheet(3)
24
+ end
25
+
26
+ after do
27
+ @book.close(:if_unsaved => :forget)
28
+ Excel.kill_all
29
+ rm_tmp(@dir)
30
+ end
31
+
32
+ describe "creating" do
33
+
34
+ context "with standard" do
35
+
36
+ it "should simply create a new table" do
37
+ table = Table.new(@sheet, "table_name", [1,1], 3, ["Person","Amount"])
38
+ table.Name.should == "table_name"
39
+ table.HeaderRowRange.Value.first.should == ["Person","Amount"]
40
+ table.ListRows.Count.should == 3
41
+ @sheet[1,1].Value.should == "Person"
42
+ end
43
+
44
+ it "should type-lift a Win32ole list object into a RobustExcelOle list object" do
45
+ ole_table = @sheet.ListObjects.Item(1)
46
+ table = Table.new(ole_table)
47
+ table.Name.should == "table3"
48
+ table.HeaderRowRange.Value.first.should == ["Number","Person","Amount","Time","Date"]
49
+ table.ListRows.Count.should == 6
50
+ @sheet[3,4].Value.should == "Number"
51
+ end
52
+
53
+ it "should type-lift a Win32ole list object into a RobustExcelOle list object with table name" do
54
+ ole_table = @sheet.ListObjects.Item(1)
55
+ table = Table.new(@sheet, "table3")
56
+ table.Name.should == "table3"
57
+ table.HeaderRowRange.Value.first.should == ["Number","Person","Amount","Time","Date"]
58
+ table.ListRows.Count.should == 6
59
+ @sheet[3,4].Value.should == "Number"
60
+ end
61
+
62
+ it "should type-lift a Win32ole list object into a RobustExcelOle list object with item number" do
63
+ ole_table = @sheet.ListObjects.Item(1)
64
+ table = Table.new(@sheet, 1)
65
+ table.Name.should == "table3"
66
+ table.HeaderRowRange.Value.first.should == ["Number","Person","Amount","Time","Date"]
67
+ table.ListRows.Count.should == 6
68
+ @sheet[3,4].Value.should == "Number"
69
+ end
70
+
71
+ it "should simply create a new table from a ole-worksheet" do
72
+ table = Table.new(@sheet.ole_worksheet, "table_name", [1,1], 3, ["Person","Amount"])
73
+ table.Name.should == "table_name"
74
+ table.HeaderRowRange.Value.first.should == ["Person","Amount"]
75
+ table.ListRows.Count.should == 3
76
+ @sheet[1,1].Value.should == "Person"
77
+ end
78
+
79
+ it "should type-lift a Win32ole list object into a RobustExcelOle list object with table name" do
80
+ ole_table = @sheet.ListObjects.Item(1)
81
+ table = Table.new(@sheet.ole_worksheet, "table3")
82
+ table.Name.should == "table3"
83
+ table.HeaderRowRange.Value.first.should == ["Number","Person","Amount","Time","Date"]
84
+ table.ListRows.Count.should == 6
85
+ @sheet[3,4].Value.should == "Number"
86
+ end
87
+
88
+ it "should type-lift a Win32ole list object into a RobustExcelOle list object with item number" do
89
+ ole_table = @sheet.ListObjects.Item(1)
90
+ table = Table.new(@sheet.ole_worksheet, 1)
91
+ table.Name.should == "table3"
92
+ table.HeaderRowRange.Value.first.should == ["Number","Person","Amount","Time","Date"]
93
+ table.ListRows.Count.should == 6
94
+ @sheet[3,4].Value.should == "Number"
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+
101
+ describe "getting and setting values" do
102
+
103
+ context "with new table" do
104
+
105
+ before do
106
+ @table = Table.new(@sheet, "table_name", [1,1], 3, ["Person","Amount"])
107
+ @table_row1 = @table[1]
108
+ end
109
+
110
+ it "should set and read values" do
111
+ @table_row1.person.should be nil
112
+ @table_row1.person = "John"
113
+ @table_row1.person.should == "John"
114
+ @sheet[2,1].Value.should == "John"
115
+ @table_row1.amount.should be nil
116
+ @table_row1.amount = 42
117
+ @table_row1.amount.should == 42
118
+ @sheet[2,2].Value.should == 42
119
+ end
120
+ end
121
+
122
+ context "with type-lifted ole list object" do
123
+
124
+ before do
125
+ ole_table = @sheet.ListObjects.Item(1)
126
+ @table = Table.new(ole_table)
127
+ @table_row1 = @table[1]
128
+ end
129
+
130
+ it "should set and read values" do
131
+ @table_row1.number.should == 3
132
+ @table_row1.number = 1
133
+ @table_row1.number.should == 1
134
+ @sheet[4,4].Value.should == 1
135
+ @table_row1.person.should == "Herbert"
136
+ @table_row1.person = "John"
137
+ @table_row1.person.should == "John"
138
+ @sheet[4,5].Value.should == "John"
139
+ end
140
+ end
141
+
142
+ end
143
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: robust_excel_ole
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.19'
4
+ version: 1.19.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - traths
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-10 00:00:00.000000000 Z
11
+ date: 2020-07-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -109,6 +109,7 @@ files:
109
109
  - lib/robust_excel_ole/cygwin.rb
110
110
  - lib/robust_excel_ole/excel.rb
111
111
  - lib/robust_excel_ole/general.rb
112
+ - lib/robust_excel_ole/list_object.rb
112
113
  - lib/robust_excel_ole/range.rb
113
114
  - lib/robust_excel_ole/range_owners.rb
114
115
  - lib/robust_excel_ole/robustexcelole.sublime-project
@@ -117,7 +118,6 @@ files:
117
118
  - lib/robust_excel_ole/version.rb
118
119
  - lib/robust_excel_ole/workbook.rb
119
120
  - lib/robust_excel_ole/worksheet.rb
120
- - lib/rubygems_plugin.rb
121
121
  - lib/spec_helper.rb
122
122
  - reo.bat
123
123
  - robust_excel_ole.gemspec
@@ -141,10 +141,12 @@ files:
141
141
  - spec/data/workbook_connected.xlsm
142
142
  - spec/data/workbook_linked.xlsm
143
143
  - spec/data/workbook_linked_sub.xlsm
144
+ - spec/data/workbook_listobjects.xlsx
144
145
  - spec/excel_spec.rb
145
146
  - spec/general_spec.rb
146
147
  - spec/helpers/create_temporary_dir.rb
147
148
  - spec/helpers/key_sender.rb
149
+ - spec/list_object_spec.rb
148
150
  - spec/range_spec.rb
149
151
  - spec/spec_helper.rb
150
152
  - spec/workbook_spec.rb
@@ -1,3 +0,0 @@
1
- Gem.post_install do
2
- puts "post_install called for gem"
3
- end