RubyでExcel操作メモ_010_ファイルの書き換え

ファイルの一部の文字列をExcelファイルから取得した
値で置き換える処理をメモしておく。
<前提条件>
チェック処理等を省いているので、
・ファイルが用意され、開かれていないこと。
Excelファイル内にA〜K列まで1行目から入力値があること
を前提条件としています。
<主な処理の流れ>
処理の概要としては
==============================
・置き換えファイルの準備
(copy.txtを元にpaste.txtを作成)

Excelファイルから値を取得

・置き換えファイルの更新
(paste.txtを更新)
==============================
となります。

#! ruby -Ks
require ‘win32ole’   #Excelデータの取得に使用
require ‘fileutils’  #ファイルのコピーに使用
require ‘kconv‘      #UTF-8への変換に使用
#########################################################
#
# ファイル編集用クラス
#
#########################################################
class FileCls
    #—————————————-
    # クラス定数
    #—————————————-
    COPYFILENAME       = ‘C:\\rb\\copy.txt’  #コピー元のファイル名
    PASTEFILENAME      = ‘C:\\rb\\past.txt’  #コピー先のファイル名
    CHKFILENAME        = ‘C:\\rb\\list.xlsx’ #データ取得するExcelファイル名
    CHKSHTNAME         = ‘TESTSHEET’         #データ取得するExcelシート名
   
    #—————————————-
    # クラス変数
    #—————————————-
    @@aryData     =
    @@intRow      = 1
   
    #—————————————-
    #  ExcelのセルNo取得用
    #—————————————-
    module Col
        COLA  = 1
        COLB  = 2
        COLC  = 3
        COLD  = 4
        COLE  = 5
        COLF  = 6
        COLG  = 7
        COLH  = 8
        COLI  = 9
        COLJ  = 10
        COLK  = 11
    end
   
    #—————————————-
    # 配列のインデックス取得
    # [Param]
    #   col:module「Col」の値を想定
    # [Return]
    #   デクリメントした値
    #—————————————-
    def self.getidx(col)
        retval = col – 1
        return retval
    end
   
    #—————————————-
    # Excelのセルデータ取得
    # [Param]
    #   book:取得元のExcelファイル
    # [Return]
    #   配列化したExcelデータ
    #—————————————-
    def self.getary(book)
        while book.sheets(CHKSHTNAME).Cells(@@intRow,1).Value != nil  do
            ary =

            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLA ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLB ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLC ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLD ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLE ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLF ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLG ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLH ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLI ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLJ ).Value
            ary << book.sheets(CHKSHTNAME).Cells(@@intRow,Col::COLK ).Value
            @@aryData << ary
            @@intRow += 1
        end
        return @@aryData
    end
   
    #—————————————-
    # ファイルのコピー
    #—————————————-
    def self.cpfile
        FileUtils.copy(COPYFILENAME,PASTEFILENAME)
    end
   
    #—————————————-
    # UTF-8変換
    # [Param]
    #   val:変換対象の文字列
    # [Return]
    #   UTF-8へ変換した文字列
    #—————————————-
    def self.chkNil(val)
        retval = ”
        if val != nil then
            retval = val.toutf8
        end


        return retval
    end
end
#########################################################
#
# 実行処理
#
#########################################################
#実行処理
begin
    #—————————————-
    # ファイルのコピー(copy.txt⇒past.txt)
    #—————————————-
    FileCls::cpfile
   
    #—————————————-
    # Excelファイルを開き、値を配列に保持
    #—————————————-
    app     = WIN32OLE.new(‘Excel.Application’)
    inbook  = app.Workbooks.Open( FileCls::CHKFILENAME)
    ary =  FileCls::getary(inbook)
    #—————————————-
    # 取得したデータ分繰り返す
    #—————————————-
    ary.each do |aryRow|
       
        #——————————
        # 変換文字列の設定
        #——————————
        settxt = ”
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLA) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLB) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLC) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLD) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLE) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLF) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLG) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLH) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLI) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLJ) ])  + “\n”.toutf8)
        settxt = settxt.concat(FileCls::chkNil(aryRow[FileCls.getidx(FileCls::Col::COLK) ])  + “\n”.toutf8)
       
        #——————————
        # 再変換用の文字を末尾に追加
        # 最後は変換用の文字は不要
        #——————————
        if aryRow != ary.last
            settxt = settxt.concat(‘RepArea’.toutf8)
        end
       
        #——————————
        # 更新対象ファイルのデータ取得
        #——————————
        file = File.open(FileCls::PASTEFILENAME,”r”)
        data = file.read
        file.close
       
        #——————————
        # テキスト内容を変換
        #——————————
        new_contents = ”
        new_contents = data.toutf8
        new_contents = new_contents.gsub(“RepArea”, settxt.toutf8)
       
        #——————————
        # ファイルの更新
        #——————————
        File.open(FileCls::PASTEFILENAME, “w”) do |f|
            f.write(new_contents)
        end
    end
#例外処理
rescue Exception => e
    puts’rescue’
    puts e.message
    puts e.backtrace.inspect
#共通処理
ensure
    inbook.save
    inbook.close(true)
    app.quit
end

以下、処理メモ
文字コードの変換>
文字コードを「Shift-JIS」ではなく、「UTF-8」で保存したかったため、

require ‘kconv

の「kconv」で「〜.toutf8」を使用して変換処理を行っている。
また、空文字「”」に対して「〜.toutf8」を行なうとエラーが発生するため、
空文字以外に対してのみ、UTF-8への変換処理を行っている
Rubyの例外処理>
Rubyでは

begin
ここには通常処理を記載
rescue 例外の型=>変数
ここには例外発生処理を記載
ensure
ここは必須処理を記載
end

という書き方をする。
<ファイルの更新タイミング>
本来であれば、ファイルへの更新は最後に1度だけにしたかったが、
Excelファイルを纏めている処理を長く繰り返すと、
メモリエラーが発生したため、
Excelの行ごとにファイルへの更新処理を行っている。
<書き込みファイルのオープン、クローズ>
更新対象ファイルのデータ取得として

#——————————
# 更新対象ファイルのデータ取得
#——————————
file = File.open(FileCls::PASTEFILENAME,”r”)
data = file.read
file.close

という処理と

#——————————
# ファイルの更新
#——————————
File.open(FileCls::PASTEFILENAME, “w”) do |f|
f.write(new_contents)
end

をわけ、2度にわたり開いたり、閉じたりを行っているが、
書き込みモードでファイルをオープンした際のファイル内の
値の取得方法がわからなかったため、
「読み込みモード」と「書き込みモード」でそれぞれの
処理を分けている。
※1度で実施する方法がわかれば、別途、追記等を行う

RubyでExcel操作メモ_009_ライブラリの使用

Excel操作からはずれてしまうが、
Rubyの各種ライブラリを利用する際のメモ。
FileUtilsを利用するときを例として記載。
Rubyのドキュメントを見ていくことになる。
Module: FileUtils (Ruby 1.9.3)
処理の先頭に対象クラファイルの読み込みを
require ‘fileutils’
のように記載します。
FileUtilsクラスは
「fileutils.rb」
となっており、ローカルのファイルを調べると、
C:\Ruby22\lib\ruby\2.2.0
に実際の上記ファイルが存在し、
処理の中身を見ることができます。
それ以外に関しては、リファレンスを見ながら
パラメータを設定して使ってあげることになります。
必要であれば、処理自体も見ることができるので、
ソースを見て理解していってもよいかもしれません。
Rubyのソース>

require ‘fileutils’
class FileCls
 COPYFILENAME       = ‘C:\\rb\\cp.txt’
 PASTEFILENAME      = ‘C:\\rb\\pst.txt’
 def self.cpfile
  #copy_file(COPYFILENAME,PASTEFILENAME)
  FileUtils.copy(COPYFILENAME,PASTEFILENAME)
 end
end
FileCls::cpfile

RubyでExcel操作メモ_007_シートの削除

Rubyから「win32ole」というのを使って、
色々と操作できるようなので、
使ってみたときのメモを残していく。

今回はシートの削除。

 

Rubyのソース>

#! ruby -Ks
require ‘win32ole’

class FileCls
    INFILENAME    =  ‘C:\\rb\\file.xlsx’
    CHKNAME       =  ‘shtname’
   
    @@aryData     = []
   
    def self.getary(book)
        book.sheets.each do |sht|
            @@aryData << sht.name
        end
        return @@aryData
    end
   
    def self.existname(name)
        @@aryData.each do |shtname|
            if shtname == name then
                @@aryData.delete(name)
                return true
            end
        end
        return false
    end
end

app     = WIN32OLE.new(‘Excel.Application’)
app.DisplayAlerts = false
inpath  = FileCls::INFILENAME
inbook  = app.Workbooks.Open(inpath)
aryName = FileCls::getary(inbook)

if FileCls::existname(FileCls::CHKNAME) then
    aryName.each do |name|
        inbook.sheets(name).delete
    end
end

inbook.save
inbook.close(true)
app.quit

 

処理的には指定のシート名以外のシートは

すべて削除する処理を行っている。

 

先頭の宣言、

#! ruby -Ks

は日本語を扱うための記載。

 

また、削除時にファイルの更新を行う際、

確認ダイアログの表示を行いたくないので、

app.DisplayAlerts = false

とアラートの表示を止めている。

 

RubyでExcel操作メモ_006_テキストファイルの値をコピー

Rubyから「win32ole」というのを使って、
色々と操作できるようなので、
使ってみたときのメモを残していく。

ホントにちょっとしたことだけど、

今回はテキストファイルの値をコピー。

 

Rubyのソース>

require ‘win32ole’

class FileCls
    INFILENAME        = ‘C:\\rb\\in.txt’
    SETFILENAME       = ‘C:\\rb\\set.xlsx’
 
     @@aryData = []
 
    def self.getary
    File.open(INFILENAME).readlines.each do |line|
       @@aryData << line
    end
    return @@aryData
    end
end

app       =  WIN32OLE.new(‘Excel.Application’)
inpath   =  FileCls::SETFILENAME
in          =  app.Workbooks.Open(inpath)
row       =  1

FileCls::getary.each do |value|
    in.sheets(1).Cells(row,1).Value = value.chomp!
    row  += 1
end

in.save
in.close(true)
app.quit

  

<テキストファイルの中身>

まぁ、これは何でもよいのだが、

 適当に複数行テキストファイルを作っておく。

textrow1
textrow2
textrow3
textrow4
textrow5
textrow6
textrow7

 

セルA1~A7に順にテキストファイルの内容が

コピーされるようになっている。

RubyでExcel操作メモ_005_セルの背景色/文字色の変更

Rubyから「win32ole」というのを使って、

色々と操作できるようなので、
使ってみたときのメモを残していく。

ホントにちょっとしたことだけど、

今回はセルの背景色の変更。

 

Rubyのソース>

 require ‘win32ole’

class FileCls
    INFILENAME         = ‘C:\\rb\\in.xlsx’
    NAME_RED          = ‘RED’
    NAME_BLACK      = ‘BLACK’
    NAME_WHITE      = ‘WHITE’
    NAME_GREEN     = ‘GREEN’
    NAME_BLUE        = ‘BLUE’
    NAME_YELLOW   = ‘YELLOW’
    IDX_BLACK           = 1
    IDX_WHITE           = 2
    IDX_RED               = 3
    IDX_GREEN          = 4
    IDX_BLUE             = 5
    IDX_YELLOW       = 6
 
    def self.getcoloridx(name)
        case name
            when NAME_RED then
                return IDX_RED
            when NAME_WHITE then
                return IDX_WHITE
            when NAME_GREEN then
                return IDX_GREEN
            when NAME_BLUE then
                return IDX_BLUE
            when NAME_YELLOW then
                return IDX_YELLOW
           else
               return IDX_BLACK
          end
    end
end

app      =  WIN32OLE.new(‘Excel.Application’)
inpath  =  FileCls::INFILENAME
in         =  app.Workbooks.Open(inpath)

in.sheets(1).Cells(1,1).Interior.ColorIndex = FileCls::getcoloridx(FileCls::NAME_YELLOW)
in.sheets(1).Cells(1,1).Font.ColorIndex = FileCls::getcoloridx(FileCls::NAME_YELLOW)
inbook.save
inbook.close(true)
app.quit

 

背景色:CellsのInterior.ColorIndex

文字色:CellsのFont.ColorIndex

で変更できる。

 

また、 ColorIndexのプロパティに関しては、

ColorIndex Property

 に載せられている下記の画像がわかりやすい。

f:id:shevhome:20150907131300p:plain

RubyでExcel操作メモ_004_ファイル作成/保存

Rubyから「win32ole」というのを使って、
色々と操作できるようなので、
使ってみたときのメモを残していく。

ホントにちょっとしたことだけど、

今回は新規ファイルを作り、

旧ファイル⇒新ファイルへの値コピー。

 

Rubyのソース>

require ‘win32ole’

class FileCls
 INFILENAME  = ‘C:\\rb\\in.xlsx’
 OUTFILENAME  = ‘C:\\rb\\out.xlsx’
end

app = WIN32OLE.new(‘Excel.Application’)
inpath  = FileCls::INFILENAME
outpath = FileCls::OUTFILENAME
inbook  = app.Workbooks.Open(inpath)
outbook  = app.Workbooks.add

outbook.sheets(1).Cells(1,1).Value = inbook.sheets(1).Cells(1,1).Value

inbook.save
inbook.close(false)
outbook.saveAs(outpath)
outbook.close(false)
app.quit

 

元のファイルの更新はsaveメソッドでよかったけれど、

ファイル名指定で更新するならsaveAsメソッドを使います。

これでとりあえず、ファイル内容の簡易コピーができます。

RubyでExcel操作メモ_003_VBAメソッドの呼び出し

Rubyから「win32ole」というのを使って、
色々と操作できるようなので、
使ってみたときのメモを残していく。

ホントにちょっとしたことだけど、
今回はVBAの関数の呼び出し。

個人的にはこれが一番やりたかった。

 

Rubyのソース>

require ‘win32ole’

app = WIN32OLE.new(‘Excel.Application’)
path = ‘C:\\rb\\test.xlsm’
book = app.Workbooks.Open(path)

book.sheets(2).Select

book.sheets(2).setData

book.save
book.close(false)
app.quit

 

VBAのソース>

Public Sub setData()
    ActiveSheet.Cells(3, 3).Value = “呼び出されました”
End Sub

(注意)Rubyから呼び出せるように「Public」にすること。 

 

 VBAのソースを呼び出すので、

念のためにファイルの拡張子も「xlsm」で試してみた。

とりあえず、これで呼び出せたので、

あとは、RubyVBAをそれぞれ、

どの部分まで処理を 分担させるかかな。

 

まぁ、どっちかだけでってなると、VBAの方が、

やっぱり、Visual  Basic Editorを使える分、

なれているのもあるけど、そっちが楽だと感じてしまう。

 

しかし、Rubyに触れる良い機会なので、

もうちょっといじってみようかと思う。

 

 

RubyでExcel操作メモ_002_シート/セルの操作

Rubyから「win32ole」というのを使って、

色々と操作できるようなので、

使ってみたときのメモを残していく。

 

ホントにちょっとしたことだけど、

今回はシートを選択、セルへの文字設定。

ただ、これだけ。

 

require ‘win32ole’

app = WIN32OLE.new(‘Excel.Application’)
path = ‘C:\\rb\\test.xlsx’
book = app.Workbooks.Open(path)
book.worksheets(1).cells(1,1).Value = ‘testA2’
book.worksheets(‘sheet3’).cells(1,1).Value = ‘TestSheet3-A1’
book.worksheets(2).Select
 
book.save
book.close(false)
app.quit

 

基本はVBAと同じ。

「Book」⇒「Sheet」⇒「Cell」の順にみていく。

 

RubyでExcel操作メモ_001_開く/閉じる

Rubyから「win32ole」というのを使って、
色々と操作できるようなので、
使ってみたときのメモを残しておく。
ホントにちょっとしたことだけど、
今回はファイルを開いて閉じる。
ただ、これだけ。
<ソース>

require ‘win32ole’
app = WIN32OLE.new(‘Excel.Application’)
path = ‘C:\\rb\\test.xlsx’
book = app.Workbooks.Open(path)
book.save
book.close(false)
app.quit

プロフィール

学ぶパンダ

初心者向けにプログラミング学習や

就職・転職に向けた情報を発信

独学向け(勉強方法)
独学向け(プログラミング)
独学向け(Webデザイン)
独学向け(javaScript)
独学向け(PHP/Laravel)
独学向け(Ruby/Rails)