質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

1回答

41159閲覧

ExcelVBA、Bookを開かずデータを取得する方法

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

2クリップ

投稿2016/08/12 03:39

いつもお世話になっています。

今回は
「ExcelVBAで、Excelファイルを開かずにデータを取得する方法」
についてご質問いたします。

###前提条件・要望
0. 対象のExcelBookを開かずに、VBAでセルのデータ・存在するシート名一覧などを取得できる
0. 対象Bookはネットワーク上に置いてあり、複数のユーザが同時に開く・編集する可能性がある
0. 自他問わず対象Bookを開いていても、VBAから取得できるようにしたい

###現在の状況
Bookを開かずに値を取得する事は成功しました。
しかしVBAプログラムを持つExcelファイルを作業後閉じて再度開くと、
開かなかったはずの対象Bookが一緒に開かれてしまうという症状が出てしまいました。
オブジェクトの解放も問題なくできているはずですし、
そもそもExcelファイルが開いたときに何かをするマクロも入れていません。

###ソースコード
https://teratail.com/questions/37322
こちらの質問を参考に、Excel.Applicationを用いたプログラムを作成しました。
以下がソースコードになります。

'ネットワーク上の自分の親の親フォルダをカレントする
With CreateObject("WScript.Shell")
.CurrentDirectory = ThisWorkbook.Path & "...."
End With

'ファイル読み込みダイアログを開く。選択されたファイルのフルパスを取得する fn = Application.GetOpenFilename("ファイルフルパステキスト,*.xls?") '正常にファイルが選択されファイルパスを取得できていなければエラーフラグを立てる If fn = "False" Then ErroeFlag = True 'そうでなければ、選択ファイルをCreateObjectで生成する Else Set xlApp = CreateObject("Excel.Application") xlApp.Workbooks.Open fileName:=fn, ReadOnly:=True Set tergetBook = xlApp.Workbooks(Dir(fn)) End If

'エラーフラグが立っていなければ、取得作業を行う
If ErroeFlag = False Then

'取得作業

End If

'オブジェクトを解放する
Set xlApp = Nothing

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Workbookオブジェクトを開いたら、閉じなければいけません。
大雑把な流れとして、

VBA

1Dim xlApp as Excel.Application 2Dim xlWB as Excel.Workbook 3 4Set xlApp = CreateObject("Excel.Application") 5 6Set xlWB = xlApp.Workbooks.Open([ファイルのパスを指定]) 7 8' ・・・・・・開いたブックに対する処理 ・・・・・・・ 9 10' Excel ワークブックオブジェクトを閉じて解放 11xlWB.Close False ' 上書き保存せずに閉じる場合 12Set xlWB = Nothing 13 14' Excel アプリケーションオブジェクトを閉じて解放 15xlApp.quit 16Set xlApp = Nothing

こんな流れになります。
なお、この処理自体がExcel VBAで書いている場合、xlApp は省略可能です。
(すでに起動されているExcel上での処理となるため)

VBAを動かすExcelとは別にExcelアプリケーションを起動させる場合は上記のコード例のような書き方となります。

投稿2016/08/12 03:55

kaz.Suenaga

総合スコア2037

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kaz.Suenaga

2016/08/12 03:58

蛇足ですのでコメントで入れますが、「ブックを開かずに値を取得する」のは原理的に不可能です。 やれることは、「自動的に(バックグラウンドで)ワークブックを開き、処理後閉じる」です。 そのため、質問で上げられているコードでも実際にやっていることは、 - (アプリケーションとしての)Excelを起動する - 起動したExcelでWorkbookを開く - 処理 - アプリケーションを閉じる という処理を書いていますね。
退会済みユーザー

退会済みユーザー

2016/08/12 04:20

ありがとうございます。 修正をして、正常に動かすことができました。 「ファイルを開かずに中身を見ることはできない」 「ファイルの2重展開を避けるためにアプリケーションで開く」 この2つをしっかり覚えていこうと思います。
退会済みユーザー

退会済みユーザー

2016/08/15 01:51

追加報告をいたします。 回答では「xlAppでアプリケーションから開くのは省略可能」とありましたが、 省略して記述すると、ファイルの2重展開ができないことが分かりました。 省略せずに記述すると、既に開いているファイルを対象に取っても2重展開のマクロエラーが出ず、正常に動作しました。 おそらく ・同一アプリケーションで同名ファイルを開こうとすると、2重展開の判定がされる ・アプリケーションを別に定義(開く?)してアプリケーションごとにファイルを開くと、2重展開の判定がされない のだと思いますが、あくまで想像なので確信が持てません。 この考え方で合っているでしょうか?
kaz.Suenaga

2016/08/15 03:25

VBAでやれることは、基本的に手作業でやった際の動作と同じです。 Excelを(ファイルをダブルクリックではなく)スタートメニューから1つ起動した際、ファイルを開くで同一ファイルは開けませんよね。 (既に開いています、が出ますよね) その「Excel」が xlApp に当たります。 省略した場合は今扱っている(VBAを動かした)Excel上で操作する、となります。 そのためVBA内で扱うファイルのうち、すでにExcelで開いている可能性があるものがあるのであれば、たしかにxlApp を省略すると2重起動のアラートが出ると思います。 ただ、Excelの多重起動はそもそもバッティングした時の動作等の危険度は高いので、なるべくそのような状態が起こらないロジックを組む方が適切です。 例えば、既に開かれている場合で - そのブックは読み取りしかしないのであれば改めて開かない - 読み書きがあり得るのであれば、「警告を表示」「1度閉じて開きなおす」「処理のキャンセル」などの処理を加える といった仕様を考えた方がいいかと思います。
退会済みユーザー

退会済みユーザー

2016/08/15 04:28

ありがとうございます。 多重起動は作成依頼者様からの要望だったので、バッティングの危険性も踏まえて説得してみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問