方法はいくつかありますが,最も簡単・確実だと思われる方法について紹介します.
背景
Excel ファイルにおいて,内容を削除する意図で取り消し線や斜め罫線を使用することは良くあるかと思います.
例えば次のような感じ.
これらの表記は,人間からすると削除するという意図は伝わってくるのですが,ファイルをプログラムで処理する場合にはちょっと厄介です.そこで,それらの表記を踏まえてセルの内容を取得するスクリプトを作ってみました.
スクリプト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#!/usr/bin/env ruby # -*- coding: utf-8 -*- require 'win32ole' def get_norm_text(cell_range) case cell_range when ->v{ v.Borders(ExcelConst::XlDiagonalDown).LineStyle != ExcelConst::XlLineStyleNone } # 右下がり斜め線 return "" when ->v{ v.Borders(ExcelConst::XlDiagonalUp).LineStyle != ExcelConst::XlLineStyleNone } # 右上がり斜め線 return "" when ->v{ v.Text.length == 0 } # 空欄 return "" when ->v{ v.Font.Strikethrough } # セル全体が打ち消し線 return "" end text = cell_range.Text char_list = [] (1..(text.length)).each do |i| char = cell_range.Characters(i, 1) # 打ち消し線が設定されていない文字のみを拾う # NOTE: Characters(i, 1).Text は,セルの内容が文字ではない場合にこける. # 特に書式設定されていると Value の型は文字列になる一方, # Characters(i, 1).Text はこけるので厄介. char_list.push(text.chars[i-1]) if (char.Font.Strikethrough != true) end return char_list.join('') end class ExcelConst end begin excel = WIN32OLE.new("Excel.Application") WIN32OLE.const_load(excel, ExcelConst) excel.DisplayAlerts = false fso = WIN32OLE.new('Scripting.FileSystemObject') book = excel.Workbooks. Open({ FileName: fso.GetAbsolutePathName('./sample.xlsx'), ReadOnly: true }) range = book.sheets[1].Cells[1,1].CurrentRegion range.Rows.each do |row_range| row_range.columns[1].each do |cell_range| puts "BEFORE: #{cell_range.Value}\tAFTER: #{get_norm_text(cell_range)}" end end book.Close({ SaveChanges: false }) ensure excel.Quit end |
get_norm_text という関数が取り消し線をハンドリングする部分です.
冒頭に掲載した内容の sample.xlsx ファイルに対して上記のスクリプトを実行すると,以下の出力が得られます.BEFORE が普通にセルの値を取得した場合で,AFTER が get_norm_text を使った場合です.後者の場合,取り消し線や斜め罫線が設定された部分が削除されていることが分かるかと思います.
1 2 3 4 5 6 7 8 |
BEFORE: 通常セル AFTER: 通常セル BEFORE: 部分ABC的にDE取りF消し線 AFTER: 部分的に取り消し線 BEFORE: セル全体に対して取り消し線 AFTER: BEFORE: セルに対して斜め罫線(右上がり) AFTER: BEFORE: セルに対して斜め罫線(右下がり) AFTER: BEFORE: セルに対して斜め罫線(両方) AFTER: BEFORE: 2015-07-18 00:00:00 +0900 AFTER: BEFORE: 123956 AFTER: 12356 |
解説
処理のポイントは,Characters によってセルの内容を一文字づつ取得している部分です.これを使うと,文字毎の書式を取得できるため,簡単に取り消し線が設定された文字を削除することができます.
なお,これ以外の方法としては,Value の引数に xlRangeValueXMLSpreadsheet を指定し,セルを内容を XML 形式で取得して処理するやり方が考えられます.しかし,次の点であまりお勧めではありません.
- XML パーサーが必要
- セルの書式設定がどのような XML に変換されるのかの仕様が不明
特に 2番目の点に関しては,Excel のバージョンアップ等によって影響を受けることも考えられるため,避けた方が良いですね.
参考文献
- Range プロパティ (Excel)
- Range オブジェクトのリファレンスです.Excel ファイルを読み書きするスクリプトを書く際は,ここを熟読するのが一番.
コメント