2016/05/14
参考サイト:
ワークブックのオープン(既にあるワークブックを開く)は、Workbooks.Openメソッドで行います。
Workbooks.Open "C:\test.xls"
とすれば test.xls が開かれます。
ワークブックのクローズは、Closeメソッドで行います。
ActiveWorkbook.Close
のように記述します。
Workbooks.Open "C:\test.xls"
とすれば、test.xls が開かれて、それがアクティブワークブックになります。
C:\test.xls が存在しないときはエラーになります。
ワークブックを開いて、その第1ワークシートのA1に test と書き込むマクロを掲げます。
Sub Macro1()
Workbooks.Open "C:\test.xls"
Worksheets(1).Range("A1").Value = "test"
End Sub
エラーになるケースがもう一つあります。「既に開いているワークブックと同じ名前のブックを開こうとした場合」にエラーになります。
ここの事情には少しややこしい面があります。
既にC:\test.xls を開いているものとします。その上で、D:\MyFiles\test.xls を開こうとした場合、これはエラーになります。test.xls というワークブック名が同じだからです。ドライブ名やフォルダ名が違っていても、ワークブック名が同じだと駄目です。
Openメソッドには多くのパラメータがあります。名前だけあげると下のとおり。
FileName, UpdateLinks, ReadOnly, Format, Password, WriteResPassword,
IgnoreReadOnlyRecommended, Origin, Delimiter, Editable, Notify,
Converter, AddToMru, Local, CorruptLoad
ワークブックを保存するための SaveAsメソッドと共通するパラメータもいくつかありますが、いろいろ違いがあります。
SaveAsではワークブックのファイル形式(FileFormat)をかなり意識する必要がありました。xls, xlsx, xlsm などの違いに注意しなければなりませんでした。
それに対して、Openの方ではファイル名を test.xls, test.xlsx, test.xlsm などとしてやれば、ファイル名の拡張子に合わせたファイル形式でオープンされるようです。
主なパラメータに関して簡単な説明を掲げておきます。
読み取りパスワードを指定してオープンするケースを掲げておきます。
Sub Macro1()
Workbooks.Open FileName:="C:\test.xls", Password:="abc"
End Sub
ワークブックのクローズは Closeメソッドで行います。
ActiveWorkbook.Close
とすれば、アクティブワークブックを閉じることになります。
ただし、そのワークブックに変更が加えられていると、保存するかどうかを問い合わせるダイアログが出ます。
変更されているかどうかにかかわらず直ちにクローズしたい時は
ActiveWorkbook.Close False
とします。パラメータとして False を指定します。変更されている場合、その結果は失われます。
ワークブックを閉じる時に、合わせて保存もしたいという場合は、
ActiveWorkbook.Close True
のように True を指定します。すると、そのワークブックの名前(FullNameプロパティ)で保存されます。
別のファイル名で保存するなら、
ActiveWorkbook.Close True, "C:\test.xls"
のように第2パラメータでファイル名を指定します。
このとき、ファイル名の拡張子に注意して下さい。扱っているワークブックが xlsx形式(つまり最大列数が256でなく16384)の場合、拡張こを xls にすると、正しく読み込めないファイルになります。扱っている形式に合った拡張子にする必要があります。
ワークブックのオープンとクローズを行うマクロを登録します。
これまでと同様に、マクロには Control + j
というショートカットキーを割り当てます。Book1.xlsを開いてから、このショートカットキーを入力すると、次の処理が行われます。
今回、Book1.xlsは、マクロを登録するためだけに作成するものです。Book1.xlsそのものには何ら処理を加えません。
1# encoding: Windows-31J 2require "./exlap" 3 4macro_str = <<'EOS' 5Sub Macro1() 6 Dim TestFile As String 7 TestFile = ActiveWorkbook.Path & "\Book2.xls" ' テスト用ブックの名前 8 Workbooks.Open TestFile 9 Range("A2:B2").Value = Array("This is", ActiveWorkbook.FullName) 10 Range("A3").Value = "=NOW()" 11 Range("A3").NumberFormatLocal = "HH:MM:SS" 12 ActiveWorkbook.Close True 13End Sub 14EOS 15 16macro_name = "Macro1" 17Dir.glob("Book*.xls") {|fname| File.delete(fname)} 18xl = Exlap.new 19xl.opens("Book1.xls") do |wb| # Book1.xlsにマクロを登録 20 wb.macro_add(macro_str) 21 wb.Application.MacroOptions("Macro"=>macro_name, "ShortcutKey"=>"j") 22 wb.save 23end 24xl.opens("Book2.xls") do |wb| # テスト用のBook2.xlsを作成 25 wb.ss(1).Range("A1:C1").Value = "Test for", "Workbook", "Open" 26 wb.save 27end 28xl.quit
上のrubyスクリプトでは、Book1.xlsにマクロを登録する以外に、Book2.xls を作成しています。
今回のテーマがワークブックのオープンなので、オープンするためのワークブックを用意します。
前述のマクロと同じ処理を行うwin32oleのスクリプトは下のようになります。
先のマクロ登録用スクリプトでは、マクロを収納する入れ物として Book1.xls を設けましたが、今回はマクロを登録する訳ではないので Book1.xls のみを作成します。
スクリプトの前半で Book1.xls を新規に作成し(1行目に書き込む)、一度それをクローズします。
スクリプトの後半では、Book1.xlsを改めてオープンし、2行目と3行目に書き込んでからクローズします。その際、Book1.xlsを保存します。
1# encoding: Windows-31J 2require "win32ole" 3 4def fullpath(filename) 5 fso = WIN32OLE.new("Scripting.FileSystemObject") 6 return fso.GetAbsolutePathName(filename) 7end 8 9Dir.glob("Book*.xls") {|fname| File.delete(fname)} 10app = WIN32OLE.new("Excel.Application") 11wb = app.Workbooks.Add() 12ws = wb.Worksheets("Sheet1") 13ws.Range("A1:C1").Value = "Test for", "Workbook", "Open" 14wb.SaveAs(fullpath("Book1"), -4143) 15wb.Close 16 17test_file = fullpath("Book1.xls") 18wb = app.Workbooks.Open(test_file) 19ws = wb.ActiveSheet 20ws.Range("A2:B2").Value = "This is", wb.FullName 21ws.Range("A3").Value = "=NOW()" 22ws.Range("A3").NumberFormatLocal = "HH:MM:SS" 23wb.Close(true) 24app.Quit
同じ処理を行うexlapのスクリプトを掲げます。
Workbooks.Open の代わりに exlap独自のメソッド book_open を使っています。これは、新規のワークブックと既存のブックの両法を扱うことができます。
book_openのパラメータの与え方は、Workbooks.Open, Workbooks.Add と同じでかまいません。
指定したファイル名が既存のものであれば Workbooks.Open を実行し、存在しないファイルなら Workbooks.Add を実行します。
ワークブックのクローズは、wb.close を用いています。このメソッドのパラメータの与え方も VBAのCloseと同じです。
なお、2016年5月12日に exlapを更新してアップロードしました。新しいexlapでないと下のスクリプトがうまく動作しないので留意して下さい。
当シリーズのzip圧縮ファイルには、新しい exlap.rb, exl21.exe を同梱しました。
1# encoding: Windows-31J 2require "./exlap" 3 4Dir.glob("Book*.xls") {|fname| File.delete(fname)} 5xl = Exlap.new 6wb = xl.book_open("Book1.xls") 7wb.ss(1).Range("A1:C1").Value = "Test for", "Workbook", "Open" 8wb.save 9wb.close 10 11wb = xl.book_open("Book1.xls") 12ws = wb.ss 13ws.Range("A2:B2").Value = "This is", wb.FullName 14ws.Range("A3").Value = "=NOW()" 15ws.Range("A3").NumberFormatLocal = "HH:MM:SS" 16wb.close true 17xl.quit
ファイル選択ダイアログボックスを出して、オープンするワークブックをユーザーに選んでもらう方法、
それから、マクロにショートカットキーを割り当てる際に、ワークブックのオープンとの関連で経験したトラブルについて記します。
ファイル選択ダイアログボックスを出す方法を二つ紹介します。
ワークブックをオープンするやり方として、ダイアログボックスを出してユーザーにオープンするファイルを選択してもらうというのがあります。
Application.GetOpenFilename を用いると、それが実現できます。
このメソッドは、選択されたファイルの名前(文字列)をフルパスで返します。その返されたファイル名を Workbooks.Open に渡してやれば、ワークブックがオープンされます。
サンプルのマクロは下のとおり。
Sub Macro1()
Dim OpenFile As String
OpenFile = Application.GetOpenFilename("すべてのファイル(*.*),*.*")
MsgBox OpenFile & " を開きます"
Workbooks.Open OpenFile
End Sub
もう一つの方法は、Application.Dialogs を用いるものです。マクロ記述は下のとおり。
Sub Macro1()
Application.Dialogs(xlDialogOpen).Show
End Sub
上のマクロを実行すると、ファイル選択ダイアログボックスが出ます。そこで何らかのファイルを選択すると、それが直ちにExcelでオープンされます。
Application.GetOpenFilename の時のように Workbooks.Open を使わなくても、ワークブックがオープンされます。
なお、Application.Dialogs の戻り値は True, False のどちらかです。
ファイルが選択されてオープンに成功したときは True を返します。
ファイル選択ダイアログでキャンセルボタンが押され、何も選択されなかったときは False を返します。
Application.GetOpenFilename, Application.Dialogs のどちらも、Excelにとってのカレントフォルダからファイルを選択することになります。
Excelにとってのカレントフォルダとは、通常、ユーザーのドキュメントフォルダ(マイドキュメント)です。
ダイアログボックスの中でフォルダを別のところに移すことはできますが、別のフォルダを初期フォルダにしたい場合は ChDrive(ドライブの変更), ChDir(フォルダの変更)を利用するのが一般的でしょうか。
ただ、ドライブとフォルダを一気に変更することはできないようだし(つまり別々に変更しなければならない)、ダイアログボックス終了後にExcelのカレントフォルダを元に戻す処理も必要になり、なかなか面倒です。
そこで、Application.ExecuteExcel4Macro を使って kernel32 の呼び出しを行う方法を試してみます。マクロは下のようになります。
Sub Macro1()
Dim folder As String
folder = "D:\MyFile"
Application.ExecuteExcel4Macro("CALL(""kernel32""," & _
"""SetCurrentDirectoryA"",""JC"",""" & folder & """)")
Application.Dialogs(xlDialogOpen).Show
End Sub
上は、D:\MyFile というフォルダの下にExcelファイルがあるとの想定で書かれています。D:\MyFile\Book1.xls などがあるとの想定です。
Application.ExecuteExcel4Macro や kernel32 については、簡単に説明できないので省略しますが、あやしげな方法という訳ではないので「使えそうだ」と思われたら試してみて下さい。
関連のスクリプトをzip圧縮ファイルに同梱しておきます。Book1.xlsにマクロを組み込み、オープンのテスト用に Book2.xls, Book3.xls の二つを作成しておく、というスクリプトです。ユーザーが選択したファイルにちょっと書き込みをしてから、保存・クローズします。
同様の意味合いの win32ole, exlap のスクリプトも同梱しておきます。こちらは Book1.xls, Book2.xls の二つをオープンのテスト用として作成します。途中でファイル選択ダイアログが出ます。
ワークブックをオープンする際にシフトキーが押されているとマクロが動作しない、というのが仕様のようです。そのためだと思いますが、次のようなトラブルを経験しました。
当シリーズのスクリプトでは、以前、マクロに Shift + Control + U
というショートカットキーを割り当てていました。このショートカットキーを入力すればマクロが実行される、というようにしていた訳です。
ところが、Workbooks.Open が出てくるマクロがちゃんと実行されません。ワークブックのオープンまでは実行されるのですが、そこで中断されてしまい、先に進みません。
マクロの書き方がわるいのかとも思いましたが、Excelのメニューからマクロの実行を選んだときは正常に実行されます。
あれこれ調べたところ、シフトキーの押し下げを伴わないショートカットキーだと大丈夫であることが分かりました。
合わせて、Excelで使えるショートカットキーを改めて調べたところ、Control + U
と Shift + Control + U
には機能が割り当てられていることも発見(今更ですが)。
そこで、ショートカットキーとして Control + j
を割り当てるよう改めました。
これで、Workbooks.Open が出てくるマクロも、ショートカットキーから正常に実行できるようになりました。
マクロにショートカットキーを割り当てるときは、シフトキーの押し下げを伴わないものにするのが無難です。