robust_excel_ole 1.19.10 → 1.21

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: 614de074c7752061f3544fd8501eaa7c13e84be83540388886d33afedc1ae736
4
- data.tar.gz: e499ec767f61227f8256cb4b0779bb25bccdefe8bda26b28a59d60b48308cc47
3
+ metadata.gz: 7598173082d025a168f3c4e8021eb41c97fb1af36943e35cf2a812fcc0f39672
4
+ data.tar.gz: 2e1e0585da1b1369d323b218b0817f23679b71f99f637a269a6abf14673df615
5
5
  SHA512:
6
- metadata.gz: 5a4d5db7e4d68d2ab0cb7fae6dd589dbebbab6582a2b9a9583241cabd5af4d06632cf1b350fc503c3b444fab8acc0c394c2b74cd3dfc64d90c612c2b956c1611
7
- data.tar.gz: 47b6118c63a036db294f2cd15de8e05dd929b4553a25bc61176b0f8d57f5d7accf3be196b7c9d1ebae5f909ef51a2dd8ed784c40b340be07250f32dbf46e8f0c
6
+ metadata.gz: '09581d754af617dcbe58149087d78c0281e7aa1e6d5feb27f4b58a0b08a0cc5967d15398d85952174143a2e867133b2d1dbf352fd0656bc7488183c7edca94ab'
7
+ data.tar.gz: bc6c1bed4f9b3370a376b875fa5a4f64b690ef6df6da70efde30a5caa49447b32b28ba09864adcb4c0ca9ea861ddeb28b5af851e30db826e749c6c97cc0153de
data/Changelog CHANGED
@@ -2,7 +2,7 @@
2
2
  All notable changes to this project will be documented in this file.
3
3
 
4
4
 
5
- ## [1.20] 2020-12-07
5
+ ## [1.20] 2020-23-07
6
6
 
7
7
  ### Changed
8
8
  - using pry in console
@@ -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
@@ -77,10 +77,10 @@ Let's open a workbook.
77
77
 
78
78
  workbook = Workbook.open 'spec/data/workbook.xls'
79
79
 
80
- Now we have a Workbook object that wraps a WIN32OLE object. That is, you can send any WIN32OLE (VBA) method to it. See
80
+ Now we have a Workbook object that wraps a WIN32OLE object. That is, we can send any WIN32OLE (VBA) method to it. See
81
81
  https://docs.microsoft.com/en-us/office/vba/api/excel.workbook#methods.
82
82
 
83
- For example, you can determine the name of the workbook.
83
+ For example, we can determine the name of the workbook.
84
84
 
85
85
  workbook.Name
86
86
  # => "workbook.xls"
@@ -122,11 +122,11 @@ RobustExcelOle allows unobtrusively reading and modifying workbooks, i.e. access
122
122
  # do something
123
123
  end
124
124
 
125
- You can also create a new, empty workbook.
125
+ We can also create a new, empty workbook.
126
126
 
127
127
  Workbook.create('spec/data/new_workbook.xls', :visible => true)
128
128
 
129
- Moreover, you can open the workbook using a block, similar to, e.g., +File.open+.
129
+ Moreover, we can open the workbook using a block, similar to, e.g., +File.open+.
130
130
 
131
131
  Workbook.open('spec/data/workbook.xls') do |workbook|
132
132
  # do something
@@ -318,33 +318,139 @@ and set another value to that range.
318
318
 
319
319
  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]
320
320
 
321
- === Reading and writing list objects
321
+ === List Objects
322
+
323
+ === Creating List Objects
322
324
 
323
325
  We can define a list object (or table) from scratch.
324
326
 
325
- table = ListObject.new(worksheet, "table 1", [1,1], 3,["Person","Amount"])
327
+ table = ListObject.new(worksheet, "table 1", [1,1], 3,["Person","AmountSales"])
328
+
329
+ 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 "Amoun%tSales".
326
330
 
327
- 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".
331
+ Likewise we can get a RobustExcelOle list object with help of an existing WIN32OlE list object.
332
+
333
+ ole_listobject = worksheet.ListObjects.Item("Table 1")
334
+ table = ListObject.new(ole_listobject)
328
335
 
329
- A row in this table can be accessed with help of [], e.g.
336
+ or
330
337
 
331
- table[1]
338
+ table = ole_listobject.to_reo
332
339
 
333
- Now we can set and get the value of a cell of the table, e.g.
340
+ Now we have a RobustExcelOle ListObject that wraps a WIN32OLE ListObject. So we can send any WIN32OLE (VBA) method to it. See
341
+ https://docs.microsoft.com/en-us/office/vba/api/excel.listobject#methods.
334
342
 
335
- table[1].person = "John"
336
- table[1].person
337
- # => "John"
343
+ A row in this table can be accessed with help of #[], e.g.
338
344
 
339
- Likewise we can get a table with help of an existing Win32OlE table.
345
+ row1 = table[1]
340
346
 
341
- ole_listobject = worksheet.ListObjects.Item("Table 1")
342
- table = ListObject.new(ole_listobject)
347
+ === Reading and setting values
348
+
349
+ Now we can set and get the value of a cell of the table with help of methods that are equal to or are underscored variants of the column names, e.g.
350
+
351
+ row1.AmountSales = 40
352
+
353
+ or
354
+
355
+ row1.amount_sales = 40
356
+
357
+ and
358
+
359
+ row1.AmountSales
360
+ # => 40
361
+
362
+ or
363
+
364
+ row1.amount_sales
365
+ # => 40
366
+
367
+ Special characters in the colare being ignored.
368
+
369
+ We can also read and set values in a whole row, e.g.
370
+
371
+ table.row_values(1)
372
+ # => ["John", 40]
373
+
374
+ or
375
+
376
+ table[1].values
377
+ # => ["John", 40]
378
+
379
+ and
380
+
381
+ table.set_row_values(1, ["Herbert", 80])
382
+ # => ["Herbert", 80]
383
+
384
+ or
385
+
386
+ table[1].set_values(["Herbert", 80])
387
+
388
+ If the number of given values is less than the number of cells in the row, only the first values are written. The remaining values keep their value.
389
+
390
+ Similarly, we can read and set the values in a whole column, e.g.
391
+
392
+ table.column_values("Person")
393
+ # => ["John", "Peter"]
394
+
395
+ and
396
+
397
+ table.set_column_values(1, ["Herbert","Paul"])
398
+
399
+ The column names we can get with help of
400
+
401
+ table.column_names
402
+
403
+ A column can be renamed.
404
+
405
+ table.rename_column("Person", "Enterprise")
406
+
407
+ or
408
+
409
+ table.rename_column(1, "Enterprise")
410
+
411
+ === Adding and Deleting rows and columns
412
+
413
+ We can add rows and columns, supplying optionally their name, the position and contents.
414
+
415
+ table.add_column("column_name")
416
+ table.add_column("column_name", 3)
417
+ table.add_column("column_name", 3, ["John", "Paul"])
418
+
419
+ table.add_row(3)
420
+ table.add_row(3, ["John", 40, 2, 2004])
421
+
422
+ Deleting columns and rows is done by
423
+
424
+ table.delete_column("column_name")
425
+ table.delete_row(3)
426
+
427
+ We can delete only the contents of a column
428
+
429
+ table.delete_column_values("column_name")
430
+
431
+ Similarly can delete only the contents of a row.
432
+
433
+ table.delete_row_values(2)
434
+
435
+ or
436
+
437
+ table[2].delete_values
438
+
439
+ Finally we can delete empty rows and columns.
440
+
441
+ table.delete_empty_rows
442
+ table.delete_empty_columns
443
+
444
+ === Finding values and sorting
445
+
446
+ You can find all cells containing a given value, e.g.
447
+
448
+ table.find_value(value)
449
+ #=> [#<Cell: (5,8)>#, #<Cell: (9,6)>#]
450
+
451
+ You can sort a table according to a given column and sort order, e.g.
343
452
 
344
- r4 = t4[1]
345
- r4.person
346
- # =>
347
- r.person = "John"
453
+ table.sort("Person", :ascending)
348
454
 
349
455
  === More things
350
456
 
data/bin/jreo CHANGED
@@ -1,3 +1,24 @@
1
- @echo off
1
+ #!/usr/bin/env jruby
2
+ # -*- jruby -*-
2
3
 
3
- jruby ../lib/reo_console.rb
4
+ require 'pry'
5
+ require 'robust_excel_ole'
6
+
7
+ include REO
8
+ include General
9
+
10
+ puts 'REO console started'
11
+ puts
12
+
13
+ # some pry configuration
14
+ Pry.config.windows_console_warning = false
15
+ Pry.config.history.should_save = true
16
+ Pry.config.color = false
17
+ #Pry.editor = 'notepad' # 'subl', 'vi'
18
+ #Pry.config.prompt =
19
+ # [
20
+ # ->(_obj, _nest_level, _) { ">> " },
21
+ # ->(*) { " " }
22
+ # ]
23
+
24
+ pry
data/bin/reo ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- ruby -*-
3
+
4
+ require 'pry'
5
+ require '../robust_excel_ole/lib/robust_excel_ole'
6
+
7
+ include REO
8
+ include General
9
+
10
+ # some pry configuration
11
+ Pry.config.windows_console_warning = false
12
+ #Pry.config.history_save = true
13
+ Pry.config.color = false
14
+ #Pry.editor = 'notepad' # 'subl', 'vi'
15
+ #Pry.config.prompt =
16
+ #[
17
+ #->(_obj, _nest_level, _) { ">> " },
18
+ #->(*) { " " }
19
+ #]
20
+
21
+ hooks = Pry::Hooks.new
22
+
23
+ hooks.add_hook :when_started, :hook12 do
24
+ puts 'REO console started'
25
+ puts
26
+ end
27
+ Pry.start(nil, hooks: hooks)
@@ -1,21 +1,24 @@
1
1
  require 'pry'
2
- require 'robust_excel_ole'
2
+ require '../robust_excel_ole/lib/robust_excel_ole'
3
3
 
4
4
  include REO
5
5
  include General
6
6
 
7
- puts 'REO console started'
8
- puts
9
-
10
7
  # some pry configuration
11
8
  Pry.config.windows_console_warning = false
12
- Pry.config.history.should_save = true
9
+ #Pry.config.history_save = true
13
10
  Pry.config.color = false
14
11
  #Pry.editor = 'notepad' # 'subl', 'vi'
15
12
  #Pry.config.prompt =
16
- # [
17
- # ->(_obj, _nest_level, _) { ">> " },
18
- # ->(*) { " " }
19
- # ]
13
+ #[
14
+ #->(_obj, _nest_level, _) { ">> " },
15
+ #->(*) { " " }
16
+ #]
20
17
 
21
- pry
18
+ hooks = Pry::Hooks.new
19
+
20
+ hooks.add_hook :when_started, :hook12 do
21
+ puts 'REO console started'
22
+ puts
23
+ end
24
+ Pry.start(nil, hooks: hooks)
@@ -2,6 +2,7 @@
2
2
 
3
3
  module RobustExcelOle
4
4
 
5
+ # @private
5
6
  class Bookstore < Base
6
7
 
7
8
  def initialize
@@ -24,6 +24,16 @@ module RobustExcelOle
24
24
  @ole_range = @ole_range.MergeArea.Item(1,1) if @ole_range.MergeCells
25
25
  end
26
26
 
27
+ # @private
28
+ def to_s
29
+ @ole_range.Name.to_s
30
+ end
31
+
32
+ # @private
33
+ def inspect
34
+ "#<Cell:" + " (#{@ole_range.Row},#{@ole_range.Column})" + ">#"
35
+ end
36
+
27
37
  private
28
38
 
29
39
  # @private
@@ -10,28 +10,35 @@ module General
10
10
  ::CONNECT_EXCEL_JRUBY_BUG = IS_JRUBY_PLATFORM && true
11
11
  ::RANGES_JRUBY_BUG = IS_JRUBY_PLATFORM && true
12
12
 
13
+ NetworkDrive = Struct.new(:drive_letter, :network_name) do
14
+
15
+ def self.get_all(drives)
16
+ ndrives = []
17
+ count = drives.Count
18
+ (0..(count - 1)).step(2) do |i|
19
+ ndrives << NetworkDrive.new( drives.Item(i), drives.Item(i + 1))
20
+ end
21
+ ndrives
22
+ end
23
+
24
+ end
25
+
13
26
  @private
14
27
  def network2hostnamesharepath(filename)
15
28
  network = WIN32OLE.new('WScript.Network')
16
29
  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
30
+ drive_letter, filename_after_drive_letter = filename.split(':')
31
+ drive_letter = normalize_drive_letter(drive_letter)
32
+ network_drives = NetworkDrive.get_all(drives)
33
+ network_drive = network_drives.find{ |d| d.drive_letter == drive_letter }
34
+ return filename unless network_drive
35
+ return network_drive.network_name + filename_after_drive_letter
33
36
  end
34
37
 
38
+ def self.normalize_drive_letter(drive)
39
+ drive.upcase.end_with?(':') ? drive : "#{drive}:"
40
+ end
41
+
35
42
  # @private
36
43
  def absolute_path(file)
37
44
  file[0,2] = './' if ::EXPANDPATH_JRUBY_BUG && file =~ /[A-Z]:[^\/]/
@@ -44,11 +51,12 @@ module General
44
51
  def canonize(filename)
45
52
  raise TypeREOError, "No string given to canonize, but #{filename.inspect}" unless filename.is_a?(String)
46
53
  filename = network2hostnamesharepath(filename)
47
- normalize(filename).downcase
54
+ normalize(filename).downcase if filename
48
55
  end
49
56
 
50
57
  # @private
51
- def normalize(path)
58
+ def normalize(path)
59
+ return unless path
52
60
  path = path.gsub('/./', '/') + '/'
53
61
  path = path.gsub(/[\/\\]+/, '/')
54
62
  nil while path.gsub!(/(\/|^)(?!\.\.?)([^\/]+)\/\.\.\//, '\1')
@@ -90,9 +98,19 @@ class Array
90
98
  end
91
99
  end
92
100
 
101
+ def find_each_index find
102
+ found, index, q = -1, -1, []
103
+ while found
104
+ found = self[index+1..-1].index(find)
105
+ if found
106
+ index = index + found + 1
107
+ q << index
108
+ end
109
+ end
110
+ q
111
+ end
93
112
  end
94
113
 
95
-
96
114
  # @private
97
115
  class WIN32OLE
98
116
 
@@ -103,7 +121,7 @@ class WIN32OLE
103
121
  class2method = [
104
122
  {Excel => :Hwnd},
105
123
  {Workbook => :FullName},
106
- {Worksheet => :Copy},
124
+ {Worksheet => :UsedRange},
107
125
  {RobustExcelOle::Range => :Row},
108
126
  {ListObject => :ListRows}
109
127
  ]
@@ -113,7 +131,7 @@ class WIN32OLE
113
131
  begin
114
132
  self.send(method)
115
133
  if classname == RobustExcelOle::Range && self.Rows.Count == 1 && self.Columns.Count == 1
116
- return Cell.new(self)
134
+ return Cell.new(self, self.Parent)
117
135
  else
118
136
  return classname.new(self)
119
137
  end
@@ -164,6 +182,31 @@ class ::String
164
182
  word
165
183
  end
166
184
 
185
+ def delete_multiple_underscores
186
+ word = self
187
+ while word.index('__') do
188
+ word.gsub!('__','_')
189
+ end
190
+ word
191
+ end
192
+
193
+ def replace_umlauts
194
+ word = self
195
+ word.gsub!('ä','ae')
196
+ word.gsub!('Ä','Ae')
197
+ word.gsub!('ö','oe')
198
+ word.gsub!('Ö','Oe')
199
+ word.gsub!('ü','ue')
200
+ word.gsub!('Ü','Ue')
201
+ #word.gsub!(/\x84/,'ae')
202
+ #word.gsub!(/\x8E/,'Ae')
203
+ #word.gsub!(/\x94/,'oe')
204
+ #word.gsub!(/\x99/,'Oe')
205
+ #word.gsub!(/\x81/,'ue')
206
+ #word.gsub!(/\x9A/,'Ue')
207
+ word
208
+ end
209
+
167
210
  # taken from http://apidock.com/rails/ActiveSupport/Inflector/constantize
168
211
  # File activesupport/lib/active_support/inflector/methods.rb, line 226
169
212
  def constantize # (camel_cased_word)