ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

EXCEL VBAコミュの【質問】特定の拡張子のファイルをエクセルで開いた時に実行したい

  • mixiチェック
  • このエントリーをはてなブックマークに追加
初めて書込みさせていただきます。
目的的には「メモ帳からのデータ読み込みについて」というトピックともややかぶる面があるのですが、本質的な不明点が異なるので別トピックを立てさせていただきます。

私はよくカンマ区切りで作られたファイル、すなわちCSVファイルを開くのですが、拡張子がCSVではありません。
そのため、その種のファイルを開くたびに
  「データ」→「区切り位置」
を行ってデータをセルに読み込んでいます。
たいした作業ではないのですが、あまりに頻繁にその種のファイルを開くため、その作業を自動化したいと考えています。

つまり、ある拡張子のファイルをEXCELで開くと、自動的に「区切り」を行うようにしたいのです。
「区切り」の部分は多分できますが、「ある拡張子のファイルをEXCELで開くと自動的に実行する」という事をどうコードで表していいのかがわかりません。
そもそもどこにコードを書いていいかわかりません。
なにとぞご指導、ご指摘のほどよろしくお願いします。

コメント(14)

Excelマクロは基本的に、Excelブック、つまりxlsファイルに
含まれるものです。カンマ区切りのテキストファイルに
マクロを記述するというのは根本的にできないことだと思います。

特定の拡張子のファイルを起動しようとするというのは
Excelそのものの動作になるので、アドイン開発することに
なると思います。
アドイン開発には有料の開発環境が必要なり
しかもExcelVBAよりもはるかに煩雑で難易度が高い知識が
必要になると認識しています。

Excelで拡張子がcsvのファイルを開くとどんな方法でも
「列のデータ形式」が『G/標準』になってしまい、
先頭0の数字項目が自動で数値と認識され、先頭の0が
なくなってしまい困ることがあります。

以前、マクロを書いたことがあるんですが

Public Sub OpenCommaSeparateFile()
  Dim fileName As Variant
  Dim fieldInfoArray() As Variant
  Dim i As Long

  fileName = Application.GetOpenFilename()
  If fileName = False Then
    Exit Sub
  End If
 
  For i = 0 To 255
    ReDim Preserve fieldInfoArray(i)
    fieldInfoArray(i) = Array(i + 1, xlTextFormat)
  Next
 
  Application.Workbooks.OpenText fileName:=CStr(fileName), _
    DataType:=xlDelimited, _
    TextQualifier:=xlDoubleQuote, _
    Comma:=True, _
    FieldInfo:=fieldInfoArray

End Sub

こんな感じだったと思います。
このマクロを含んだExcelブックを作って、
このマクロを起動してカンマ区切りのテキストファイルを
開いていました。
でも、この方法でも、拡張子がcsvだと列の型は自動判定に
なってしまいます。

サンプルは例ですので十分に検証して参考にしてください。
>キヨシさん
ごもっともなご指摘ありがとうございます。
説明が足りませんでしたが、僕が研究につかっているソフトでは、CSV形式の入力ファイルを元にいろいろな計算を行って、結果をファイルに出力します。
出力ファイル名は「入力ファイル名.mot」となります。入力ファイル名は「入力ファイル名.csv」ですから、出力ファイルの拡張子をかえようとしてもすでにそのファイル名が存在するのでできないのです。「.」より前の部分はその後の処理の関係で変えられない事情があります。
そういうわけでリネーム作戦は使えません。

またワンアクション作戦ですが、普通に区切りをおこなっても2,3のアクションでできます。
そこをゼロにするところに、VBAを作る喜びがあると思いませんか?
マイナーな拡張子ですので、ぜひとも自動実行にしたいと思います。
>平野レミファさん

EXCEL本体をいじるアドイン作成には有料ソフトが必要なんですね。
きっと個人で買うには高いのでしょうね。
ちょっと調べてみます。
サンプルも参考にさせていただきます。
ありがとうございました。
マクロだけならできるみたいです。

アドインブックというものがあるみたいです。
今知りました。
アドインブックはExcelのVBAのみで作成可能のようなので、
無料でできそうです。
ただ、ファイルを開いたあとのタイミングしか検出きない
感じですので、motを開く直前に処理するみたいなことは
できないかもしれません。

ここが参考になりそうです。
http://www.geocities.jp/dgscs970/_homepage2/lesson/lesson4.html
http://www.asahi-net.or.jp/~ef2o-inue/haifu/sub06_030.html

まだあきらめるには早そうです。
なんとなくできたので書いてみます。

まず、クラスモジュールを作ります。
クラス名をAppEventにしました。

Option Explicit

Public WithEvents App As Application

Private Sub App_WorkbookOpen(ByVal wb As Workbook)
  OpenTextFile wb
End Sub

次に標準モジュールを作りました。
標準モジュールの名前は何でもいいです。

Option Explicit

Public ObjAppEvent As New AppEvent
Public EventControl As Boolean

Public Sub OpenTextFile(wb As Workbook)
  Dim fileFullPath As String
  Dim fieldInfoArray() As Variant
  Dim i As Long

  fileFullPath = wb.FullName
 
  If Mid(wb.Name, Len(wb.Name) - 3, 4) = ".mot" And EventControl Then
    EventControl = False
 
    wb.Close
   
    For i = 0 To 255
      ReDim Preserve fieldInfoArray(i)
      fieldInfoArray(i) = Array(i + 1, xlTextFormat)
    Next
   
    Application.Workbooks.OpenText _
      Filename:=fileFullPath, _
      Comma:=True, _
      FieldInfo:=fieldInfoArray
 
    EventControl = True
  End If
 
End Sub

「列のデータ形式」をすべてテキストに変えていますが、
この辺は好きに変えてください。

ThisWorkBookに以下を書きます。
アドインブックの起動時の処理です。

Option Explicit

Private Sub Workbook_Open()
  Set ObjAppEvent.App = Application
  EventControl = True
End Sub

ThisWorkBookのプロパティ「IsAddin」をTrueにします。

最後にこのブックを保存しますが、アドインブックとして
保存します。
保存時に「ファイルの種類」に『Microsoft Office Excel アドイン』を
選びます。

後は適当にExcelの新規ブックを開いて[ツール]→[アドイン]を
クリックして作成したアドインブックを[参照]ボタンで選んで
チェックします。

ただ、一度motファイルを開いた後に動く処理なので、
「テキストファイルウィザード」が表示して、『完了』ボタン
を押さないと動作してくれません。

サンプルも微妙ですが参考になればと思います。

ちょっと思ったんですが、ファイルを開いたことを
検出してmotファイルの開き方を制御するよりも、
motファイルを開く用のボタン&処理をアドインブックに
作ったほうがいいような気がしました。
どの拡張子をどのアプリケーションで動かすかの設定は
Windowsの設定で可能ですので。

アドイン使う以外にも、バッチファイル+マクロでも
できそうです。
>> CCS−ありす(多分) 氏
私が前述してることを思いつきましたって言われても(汗

>> このとき起動オプションでマクロが実行できるかどうかは
オープンイベントで可能ですね。
>平野レミファさん
わざわざコードまで作っていただき、ありがとうございます。
実際やってみましたが、ちゃんと開いた時に区切れていました。
ありがとうございました。
 
ついでにコードの内容についてご質問してもよろしいでしょうか?
CLASSモジュールを使うような複雑なものは作った事がないので、理解しきれません。せっかく作っていただいたので、ただそれを使うだけでなく、原理まで理解しておきたいのです。

まずCLASSモジュールについてです。
そもそもCLASSモジュールを、「いろいろ宣言・定義をするところ」程度にしか理解してない段階で質問するのも失礼かと思いますが、
  Public WithEvents App As Application
はどういう宣言をしているのでしょうか?This Workbookに
  Set ObjAppEvent.App = Application
と記述しているのでプロパティの宣言ですか??しかし「= Application」の意味もわからないのでわかりません。

また実行の流れもよくわかりません。
?まず起動時にThis Workbookに書かれたWorkbook_Open()が最初に実行される。
?そうするとCLASSモジュールにかかれた内容のイベントに反応するようになる。
?ファイルを開くと、イベントに反応してApp_WorkbookOpenが実行される。
これであっているでしょうか?

最後に、さらに細かい内容についてです。クラスモジュール内の
 Private Sub App_WorkbookOpen(ByVal wb As Workbook)
では、「wb」というワークブックを引数としていますが、どこにもApp_WorkbookOpenに値を渡しているような箇所はありません。「As Workbook」とすればそれは「開こうしているワークブック」のことであるとVBAがわかってくれるのでしょうか?

ここが個人レッスンの場でないことは承知していますが、気になってこの時間まで眠れないのです。
どうかご教授ください。お願いします。
ちょっと、最近この流れがあまりに多すぎて気になって
いました。(質問→コードを書く)

ですが、初心者に対してこれをやるとアッキーさんのように
コードは教えてもらったけど意味がわからない状況に陥ります。

今回は指摘されてますが、多くの場合はできたからいいやで
終わってしまいます。初心者に対して、コードを提示するのが
親切なことか、もう一度良く考えてみてください。

>> アッキー 氏
細かく分からないことが分析できているのであれば調べるのは
そんなに難しくないと思います。
Webで調べても分からないようであれば、本を読んだ方がいい
かもしれませんね。
えーっと、僕もWebのサンプルを見て書いてみたので、
詳しい解説はできません。僕の解釈を書きますのでご理解の
一助となればと思います。

まず、クラスを作ったわけですが、「ファイルを開いた」という
Excelそのもののイベントを検出したいので作りました。
AppEventというクラスを作ったわけですが、この中に
『App』というパブリックの変数を宣言しました。
この変数の型はApplicationです。コレはVBAの最上位の
オブジェクトで、Excelそのもの(VBA?)です。
コレでExcelのイベントを検出できそうですが、
まだ宣言の状態で、空です。インスタンス化されていない状態です。
インスタンス化は後でします。

>  Public WithEvents App As Application
> はどういう宣言をしているのでしょうか?
とありますが、『App』の宣言にWithEventsをくっつけています。
Applicationオブジェクトのイベントを検出したいので、
くっつけています。
そうすると、『WorkbookOpen』イベントのサブプロシージャを
書いてイベント処理を行うことができました。

実際の処理は標準モジュールに書きました。
ここではさっき作ったクラスを型にした変数を宣言しています。
  Public ObjAppEvent As New AppEvent
です。
標準モジュールでパブリックの変数を宣言をしているので
このマクロ全体から参照することができます。
さらに、Newしているので、この段階(マクロの起動)で
『ObjAppEvent』はインスタンス化されています。

では『ObjAppEvent』(『AppEvent』)の『App』変数は
いつインスタンス化されるかというと、このブックの
『ThisWorkbook』の『Open』イベント時に、
「Application」を代入してやっと、『App』の
インスタンス化ができました。

> また実行の流れもよくわかりません。
とありますが、概ねあっていると思います。
ただ、0番目として標準モジュールの
  Public ObjAppEvent As New AppEvent
の処理が走っていると僕は考えています。

最後の『wb』の件ですが、ExcelのWorkbookOpenイベントが発生すると
Private Sub App_WorkbookOpen(ByVal wb As Workbook)に
Excelが(あるいはApplication)が、開いたワークブックを
wbパラメータに渡します。こんな風に解釈しています。

断片的な説明を並べてしまいましたが
僕が説明できるのはコレくらいです、間違いが
あるかもしれませんが今後の勉強で修正していって
ください。

最後に、サンプルでは『ThisWorkbook』の『Open』イベント時に
処理を行っていますが、『AddinInstall』というイベントがあるそうです。
こっちのほうがなんだかよさそうな気がします。

『AddinInstall』というイベントに変えたバージョンも
サンプルを書こうと思いましたが、疲れちゃったので
書きませんでした。すみません。
>平野レミファさん
丁寧なご解説ありがとうございました。
これを機会に、クラスなど上級なテクニックの方にも手を伸ばしていきたいと思います。
また作っていただいたアドインを元に、自分で応用を考えてさらに便利なEXCEL環境を作っていきたいと思います。自信がでてきたら配布などもしてみたいと思います。
本当にありがとうございました。

ログインすると、みんなのコメントがもっと見れるよ

mixiユーザー
ログインしてコメントしよう!

EXCEL VBA 更新情報

EXCEL VBAのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。