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

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

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

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

Q&A

解決済

4回答

13428閲覧

事前バインディングで「すでに開いているブック」を取得する方法は存在しますか?

komugi3333

総合スコア94

VBA

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

0グッド

1クリップ

投稿2019/04/21 16:07

知りたいこと

事前バインディングにて、「すでに開いているブック」を取得する方法は存在するのでしょうか?
もし存在するなら、「New」キーワードや「Open」「Add」メソッドなどのほかに、何かがあるのでしょうか?

無ければ、やはりGetObject関数を使うしかなく、その際「特に問題は無い。トラブルは起こらない。2重のバインディングになる?とかは考えなくていい。」、という理解でよろしいのでしょうか?

どうかお教えください。

質問した理由

ExcelVBA初心者なので、まだ事前バインディングと実行時バインディングの細かい動きなどを理解できていないのですが、例えば、Word等からExcelファイルを操作したい場合で考えてみますと・・・、

(01)例えば事前バインディングをしたときには・・・、

a:新規ファイルを作る→NewやAddメソッドで。
b:既存ファイルを開く→NewやOpenメソッドで。

・・・といったような形でWordなどからExcelファイルを操作できると理解しています。

(02)それに対して、実行時バインディングにしたときは・・・

c:新規ファイルを作る→CreateObject関数で。
d:既存ファイルを開く→GetObject関数で。

・・・というような認識でいます。

実行時バインディングでしたら、既存ファイルのうち、「すでに開いているブック」は、「GetObject関数」で取得できます。

そこで、「そういえば、事前バインディングのほうで ”すでに開いているブックを取得する ” っていう話は聞かないな。なぜだろう? もしGetObject関数でしかやれないなら、事前バインディングと実行時バインディングで2重にバインディングする、みたいなことになるのかしら?特にトラブったりがないなら別にそれでもいいのだけど・・・」と、ふと思ったので質問させていただきました。

もし『事前バインディングで ” すでに開いているブックを取得する ” 方法』があるなら知りたいです。

Webを色々と調べたり、ヘルプを探したりもしてみたのですが、自分にはわかりませんでした。

WordとExcelのファイルを1つずつ開いて、Wordから・・・、

VBA

1Dim bk01 As Object 2Set bk01 = Excel.Application.Workbooks.Open("Book1") 3bk01.Application.Visible = True 4

・・・のようにしてみましたら、マイドキュメントの「Book1.xlsx 」がさらに、開いただけでした。

よろしくお願いいたします。

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

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

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

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

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

guest

回答4

0

ベストアンサー

「CreateObject、GetObject は実行時バインディング、New が実行時バインディング」という理解がそもそも勘違いだと思います。
また、参照設定がしてあるかどうかも、事前バインディングと実行時バインディングとは関係ありません。

変数宣言時にオブジェクトの型が決まっているか、なんでも代入できるObject型で宣言しているかの違いです。

例えば、Excelに参照設定してあった場合、下記は実行時バインディングです。

vba

1 Dim app As Object 2 3 Set app = New Excel.Application 4 app.Visible = True 5 app.Workbooks.Open "C:\TEST\test.xlsx"

逆に、下記は事前バインディングです。(ただし、推奨できる書き方ではないらしい。)

vba

1 Dim app As Excel.Application 2 3 Set app = CreateObject(,"Excel.Application") 4 app.Visible = True 5 app.Workbooks.Open "C:\TEST\test.xlsx"

下記を読まれるといいかと思います。

4.4 アーリーバインディングとレイトバインディング - EXCEL-VBA開発講座

既に開いている Excel あるいは、WorkBook を取得する場合は、GetObject しかないと思います。
ただし、複数の Excel が開かれている場合、どの Excel を取得するかは不確定なので、やはり、あまり推奨できません。

私は以上のように理解しているのですが、深いところまで理解しているわけではないので、外している部分があるかもしれません。その場合は、ご指摘ください。

投稿2019/04/22 07:04

hatena19

総合スコア33620

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

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

komugi3333

2019/04/22 11:42

ご回答ありがとうございます。 大変、わかりやすいご説明をしていただき、ありがとうございました。 ご提示くださったWebページを読みつつ、ご提示のコードのほうも試してみて、もういっかいヘルプなどを読み直してみて、理解ができた気がします。 >CreateObject、GetObject は実行時バインディング、New が実行時バインディング」 >という理解がそもそも勘違い >変数宣言時にオブジェクトの型が決まっているか、 >なんでも代入できるObject型で宣言しているかの違いです。 >既に開いている Excel あるいは、WorkBook を取得する場合は、 >GetObject しかないと思います。 >ただし、複数の Excel が開かれている場合、 >どの Excel を取得するかは不確定なので、やはり、あまり推奨できません。 などとお教えいただき、とても納得しています。 まだちゃんと理解できていないかもしれませんが、でも「2重のバインディング」なんてことも考えなくてよくなり、すごくすっきりしました。 (01)オブジェクトの種類を明確に型の宣言をすると事前バインディング(=アーリーバインディング:ある意味、「コンパイル時」バインディング?) (02)Object型で宣言すると実行時バインディング(=レイトバインディング:文字通り、実行時バインディング?) 参照設定されていようがいまいが、Object型で変数宣言されれば、実行時バインディング(=レイトバインディング)で、ただ、事前バインディングをするには「参照設定」がなされていないと変数宣言でエラーになる。 なので、何も「別のアプリケーションやそれらのオブジェクトを操作する話」だけが「バインディングの話」ではない。 例えば「1つのExcelファイルの中」だけで普通に・・・、 Dim wb As Workbook とか Dim wb Ad Object、 あるいは、 Dim sht As WorkSheet とか Dim sht As Object、 あるいは、 Dim rng As Range とか Dim rng As Object、 ・・・などと書き分ける場合も「事前バインディング・実行時バインディング」の話になる。 これらの場合も、 (01)Workbook、WorkSheet、Range、など、型を明確に宣言すれば事前バインディングで、 (02)Object型で宣言すると実行時バインディング。 (違ってますでしょうか?) そして、「1つのExcelファイルの中」だけの話なら、最初から「Excel ×× Object Library」に参照設定はなされているわけだから、何もせずとも事前バインディングでオブジェクトの種類を明確にして変数宣言してもエラーにはならない。 ・・・と、そんな感じの理解でよいのかな・・・と思いました。 そうすれば、「2重にバインディングすることになる?」という心配は意味不明の最初から成立しない無意味な話、ということになりますから、そもそもそんな心配は要らないということになりそうです。 GetObject関数を使うことも、なんら問題ない、ということになりますよね。 ヘルプのCreateObject関数のところに、「As Object 節を使用してオブジェクト変数を宣言すると、任意の種類のオブジェクトへの参照を格納できる変数を作成できます。ただし、このような変数を使用してオブジェクトを操作する場合は、実行時バインディングが行われます。つまり、プログラムの実行時にバインディングが行われます。これに対し、事前バインディングは、プログラムのコンパイル時にバインディングが行われます。」と書いてあった意味が、ようやく理解できそうです。 結局、Web情報や書籍などの情報を、私が勝手に「勘違い」して理解していたことが、今回の疑問の原因というか、質問の答え、ということだったんですね。 すごく納得しました。 ほんとうにありがとうございました。
imihito

2019/04/22 13:17

> ただし、推奨できる書き方ではないらしい。 に関しては、リンク先の記載と自分の知識を合わせて推測すると、Excel や Word を取得する場合に限っては考えなくて良い話のようですね。 `CreateObject("Excel.Application")` で指定してる「"Excel.Application"」は レジストリ上では、VersionIndependentProgID、バージョンに依存しない ProgID として登録されています。 どういうことかというと、Windows 側で一番最新のものを探して取得するように動作します。 (逆にバージョンを厳密に指定する場合、例えば、Excel 2016 に限定して取得する場合は`CreateObject("Excel.Application.16")`と記述します。詳細はレジストリ参照) リンク先の記載は、該当の ProgID のものが複数インストールされている場合、参照設定しているものと最新のものが異なると型が一致せずエラーになることを示しているのだと思われます。 しかし、MS Office に関しては複数バージョンの同時インストールが出来ないようになっているはずなので、問題にはなりにくいと思われます。
hatena19

2019/04/22 13:57

Office2013以降は複数バージョンの同時インストールはできませんが、それ以前のバージョンとは同時インストールできますね。 以前は、Office2016 と Office2010 を同時インストールして使ってました。 その場合、参照設定で2010の方にチェックをいれておいて、CreateObject("Excel.Application")したらどうなるのだろうか。CreateObjectが最新のものを取得するなら、参照設定とバージョンが合わないので、エラーになるのだろうか。 どちらにしても事前バインディングの場合は、Newにしておけば安心ですね。
imihito

2019/04/22 22:56

指摘ありがとうございます。 少し前まで複数バージョンの同時インストール出来たのですね、最近の印象で間違ったことを書いてしまっていました。ありがとうございます。
komugi3333

2019/04/23 02:37

teratailって解決済みでもコメントできるんですね!すごい。 私もおふたりのやりとりが大変 勉強になりました。 ありがとうございます。
guest

0

VBA

1Option Explicit 2 3'★ツール→参照設定でMicrosoft Excel *.* ObjectLibraryに 4' チェックを入れておいて下さい。 5Sub test() 6 Dim AppExcel As Excel.Application 7 Dim b As Excel.Workbook 8 9 If GetExcel(AppExcel) = False Then 10 MsgBox "エクセルが開いていません。" 11 Exit Sub 12 End If 13 14 15 For Each b In AppExcel.Workbooks 16 Debug.Print b.Name 17 Next 18End Sub 19 20Function GetExcel(ByRef xlApp As Excel.Application) As Boolean 21 On Error Resume Next 22 Set xlApp = GetObject(, "Excel.Application") 23 On Error GoTo 0 24 If xlApp Is Nothing Then Exit Function 25 GetExcel = True 26End Function

こんな感じですかね?

----------<追記>------------

VBA

1Sub test() 2 Const cBName As String = "Book1" '開いているブック名 3 Dim wb As Excel.Workbook 4 5 If Word.Application.Tasks.Exists(cBName) Then 6 'Set wb = Excel.Workbooks(cBName) 7 Set wb = GetObject(, "Excel.Application").Workbooks(cBName) 8 End If 9End Sub

Word VBA だと、指定のブックが開いているかどうかは簡単に確認出来ますが、
Set wb = Excel.Workbooks(cBName)
とやっても新しくエクセルが起動しますね^^;
WindowsのAPI関数でウィンドウのハンドルを探したらよさそうですが、
GetObject関数を使うのが簡単そうですかね。。。。。

投稿2019/04/22 04:41

編集2019/04/24 13:27
mattuwan

総合スコア2136

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

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

komugi3333

2019/04/22 04:55

早速のご回答、ありがとうございます。 ご提示いただいたコードを試してみましたが、今回の質問としましては、 Function のほうの Set xlApp = GetObject(, "Excel.Application") というところで、GetObject関数を使わずに、何か方法はないのだろうか?というところが疑問でした。 すでに「参照設定」しているのだから、もし自分の勉強不足でまだ知りえていないメソッドか何かがあるのなら、GetObject関数を使わなくても「すでに開いているExcelファイルの取得」ができるのでは?と思いました。 すでに「事前バインディング」しているのに、なぜ「実行時バインディング」と呼ばれる方法で、いわば「2重にバインディングしないといけないのか?」が疑問でした。 私自身が、『 バインディングという言葉に囚われすぎで考えすぎ。参照設定した上でCreateObject関数やGetObject関数を使っても、メモリ等には何の影響もなく異常終了も無い 』ということでしたら、そのように理解しようと思っているのですが、Web上にそういうことに関する文献が見当たらなかったのと、私自身の勉強不足もあって知らないだけかも、と思い、質問させていただいた次第です。
komugi3333

2019/04/22 04:56

最初の質問が具体的ではなくて申し訳ございませんでした。
mattuwan

2019/04/23 03:32

>GetObject関数を使わなくても「すでに開いているExcelファイルの取得」ができるのでは? そもそも、 エクセルが起動しているか? エクセルでブックを開いているか? は、違う話だと思いますが、 なんだかごっちゃに話をされてるのが気になります。 開いているブックは、エクセル君に聞けばいいので、 起動しているはずのエクセル君を捕まえるのが、 今回のテーマでしょうか? それと、もう一つ、 これは、ワードVBA限定の話でしょうか? それとも一般論の話でしょうか? 一般論には興味がありませんが、 WordVBAの話なら、も少し、なにか情報がないか突っ込んで探してみようかと思いますが、その辺りどうなんでしょうか? 今日は時間が無いので、しばらく時間がかかるかも知れませんし、 いい情報が見つからなければコメントを書くことすらできませんが。。。 何か見つかればたぶん書くと思います。
komugi3333

2019/04/23 13:54

> なんだかごっちゃに話をされてるのが気になります。 これは大変申し訳ございませんでした。 私が「そもそも事前バインディングと実行時バインディング」のことを間違って理解していたために、そのような「いろいろなことがごっちゃに」質問してしまいました。すみませんでした。 >起動しているはずのエクセル君を捕まえるのが、今回のテーマでしょうか? 「バインディング」のことを 以下のように誤って理解していたため、「起動しているはずのエクセルを捕まえるのがテーマ」であるかのような質問もしてしまいました。 もしかしたらご迷惑をおかけしてしまったかもしれず、もしそうでしたら大変申し訳ございません。 ●実行時バインディング =参照設定は必要なく、 新規ブック作成はCreateObject関数+Addメソッドしか使えない。 既存ファイルオープンはGetObject関数しか使えない。 すでに開かれているファイルは「GetObject(,"××.Application")」で取得できる ●事前バインディング =参照設定を行い、 新規ブック作成は New ××.Application+Addしか使えない。 (=CreateObject関数は使えない。) 既存ファイルオープンは New ××.Application+Openしか使えない。 (=GetObject関数は使えない。) すでに開かれているファイルは何で開く? 上記のように間違った理解をしていたため、「起動しているはずのエクセルを捕まえる」ということが「事前バインディング」の場合と、「実行時バインディング」の場合と、「別々に2つ、存在するのではないか?なら事前バインディングのほうは?」とまったく的外れな疑問を抱いてしまいました。 なおかつ、「事前バインディング」と「実行時バインディング」を同時に行うと「2重になってエラーが出るのでは?」というこれもまったく的外れで無意味な疑問を抱いてしまいました。 そしてその2つが気になっていたため、また、自分の勘違いが hatena19さんのご指摘を受けるまではなかなか抜けたかったため質問のテーマがごっちゃになってしまいました。 >これは、ワードVBA限定の話でしょうか? >それとも一般論の話でしょうか? 一般論での話となります。 WordからExcelを起動することでテストしていましたが、AccessからExcel操作することも考えていましたので・・・。 >WordVBAの話なら、も少し、なにか情報がないか突っ込んで探してみようかと そのように言ってくださってありがとうございます!! でも多分ですが、私の「バインディングに対する理解のし間違い・勘違い(恥)」が原因でしたのと、また、Word限定のお話でもないものですから、これ以上は mattuwanさんの貴重なお時間を奪うことになってしまうと思いますので、今回は、ここでいったん、ひと段落とさせていただければと思います。 mattuwanさんに教えていただいたコードも、とても参考になり、今後も私も使えるので本当にありがたかったです。 感謝しています。
mattuwan

2019/04/24 13:34

趣味で掲示板を巡り、勉強するテーマを探しているだけですので、 お気遣いなく。 興味深い質問があれば勉強し、 一応の結果あるいは結論が自分なりに得られれば、 横槍を入れているだけです^^; なので、「知っておきたい。」とか、 「知っておかなければいけない。」というような、 一般論には興味がないのでご了承くださいませませ。
komugi3333

2019/04/24 16:14

はい!承知いたしました! それで、早速ですがご提示いただいたコードですが・・・、 > Tasks. で、なんだこれは?となって、 「Exists」をヘルプを調べつつローカルウィンドウで Tasksの中身を見てみたら、「こんなことができるのかあ~」とびっくりしてしまいました。 For EachでTaskを調べたらなんかいっぱい出てきました。 すごいです! こんな風に何が起動してるのかも調べられるんですね。 もう、私にとってはまったく未知の領域です・・・。 >WindowsのAPI関数でウィンドウのハンドルを探したらよさそうですが、 そういうことになるんですね。 そちらもさらに、私にとっては未知の領域ですが・・・ 昔わけもわからずにAccessにて、WebからのコピペでプロセスID?かなにかを調べるようなことはしたことはありますが、多分それと似たようなことなんですよね? 確かにそれを思いますと、GetObject関数を使うほうがやりやすいです。 そこまで調べて頂いて本当にありがとうございました。 自分の中で、「GetObject関数で行けばいい!」、と迷いが消えました。 ありがとうございます! お恥ずかしい話ですが、 >GetObject(, "Excel.Application").Workbooks(cBName) という書き方(.Workbooks(cBName)が)も、すごく参考になってしまいました! なるほど!今まで全然気が付かなかった・・・と・・・。 VBAはAccessもExcelも初心者レベルから脱してないので、大変参考になります。 本当に貴重なお時間をありがとうございました。 大変勉強になりました。(^^)m( _ _ )m
guest

0

事前バインディングとやらは何の話をしているのかはわかりませんが、Workbooksコレクションには開いているブックが含まれています。
例えば次のようなコードを実行すると、開いているブックの一覧が取得できます。

VBA

1For Each wb In Workbooks 2 Debug.Print wb.Name 3Next

取得の仕方はSetです。
hoge.xlsxというブックが存在していたとしたら、

VBA

1Set bk = Workbooks("hoge.xlsx")

投稿2019/04/21 23:42

ttyp03

総合スコア16996

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

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

komugi3333

2019/04/22 04:06

早速のご回答、ありがとうございます。 事前バインディングとは、VBEの「ツール→参照設定」でDLLやOCXにチェックを入れている、という意味で良いと思うんですが、今回の質問としましては・・・、 (A)「1つのExcelアプリケーション」から「別のExcelファイル」をつまり、複数開いて操作する、 という想定ではなくて、 (B)WordやAccessなどの別のアプリケーションから、「すでに開いているExcelファイル」を取得する、 という状況を想定してのものでした。 最初の質問がしっかりしていなくてすみませんでした。 一般的には、(B)の場合、GetObject関数を使うようですが、ふと、『 事前バインディング=「Microsof Excel ×× Object Library」に参照設定していた場合、既にそうしているのだから、GetObject関数を使わなくても、「すでに開いているExcelファイルを取得する」ということができるのではないか?』と想像したのです。 それで、ご提示して頂いたコードを、 ・WordとExcelのそれぞれ既存ファイルを1つずつ開き、 ・WordのVBA側から「Microsof Excel ×× Object Library」に参照設定してから 試してみたのですが、やはりダメでした。 Sub test() Dim wb As Object For Each wb In Workbooks Debug.Print wb.Name Next End Sub エラーは出ませんでしたが、ローカルウィンドウで確認しましたところ、SETしてもオブジェクト変数wbには何も入りませんで、ループされずにコードが終了いたしました。 かといって、自分の試したコードは、やはり、すでに開いているのと同じExcelファイルが、別のExcelアプリケーションウィンドウにて、独立して開いてしまいます。
ttyp03

2019/04/22 04:21

参照設定でできる意味は、CreateObjectでこう書いていたものが、 Set xls = CreateObject("Excel.Application") こう書けるということです。 Set xls = New Excel.Application で、開いているブックが取得できるかやってみましたが、Workbooksコレクションには入っていませんでした。 外部からは参照できない可能性がありますが、何か手段があるか調べてみます。
komugi3333

2019/04/22 04:23

あ、すみません。補足です。 「(B)の場合、GetObject関数を使う・・云々・・・」というのが「実行時バインディング」で、例えばWordやAccessから「すでに開いているExcelファイル」をオブジェクトとして取得するのに、一般的には使いますよね。 でもそうすると、たとえはすでに参照設定をしていた場合、「2重のバインディングとなり、異常終了したりしないのだろうか?」ということが疑問になりした。 以前、AccessからExcelを開くときも、何も知らなかったので、Excelへの参照設定をしたうえで(事前バインディングもしたうえで)、CreateObject関数やGetObject関数を使って(実行時バインディングで)Excel操作してしまっていたのですが、そのときは異常終了などはしなかったのですが、ほんとうに、安易にそういう方法を使ってよかったのかどうか?というところが今回の疑問の発端です。 『 たとえ、 ” 事前と実行時の2重のバインディング ” のような感じになったとしても、特にメモリには影響は無く、異常終了などはしない』ということなのでしたら、よいのですが、もし何らかの不具合が発生する可能性があるなら、見直さないといけないな、と思った次第です。 Web上にはそのようなことに関することが書かれたページを見つけることができませんでした。
komugi3333

2019/04/22 04:23

恐れ入ります。お時間とらせてしまってすみません。
komugi3333

2019/04/22 04:26

急いではいませんので、お手すきのときで結構です。恐れ入ります。
komugi3333

2019/04/22 04:42

ちなみになのですが、GetObject関数で「すでに開いているExcelファイルを取得する場合」は、次のような感じで取得しています。 (イ)ガワ(アプリケーションウィンドウ)側から取得する場合 Dim xlApp As Object Dim wb As Object Set xlApp = GetObject(, "Excel.Application") Set wb = xlApp.Workbooks("すでに開いているファイルのファイル名部分のみ") Debug.Print wb.Name (ロ)ブック側から取得する場合 Dim xlApp As Object Dim wb As Object Set wb = GetObject("D:\1\1.xlsx") Set xlApp = wb.Application Debug.Print wb.Name Debug.Print xlApp.Name すでに「参照設定」をした場合は、もしかして、これ以外にも方法があるのだろうか?どうなのだろうか?、知りたいと思いました。
komugi3333

2019/04/22 04:43

すみません。訂正です。 Set wb = GetObject("D:\1\1.xlsx") は Set wb = GetObject("すでに開いているExcelファイルのフルパス") ということでした。
ttyp03

2019/04/22 04:54

参照設定の意味は先ほどのコメント通りで、Excel.Applicationというのをユーザー定義型としてVBAが認識できるか否か程度の違いと思います。 CreateObjectでExcelオブジェクトを取得して処理しても、動きとしては何ら変わりありません。 「事前バインディング」という言葉にあまりこだわらないほうがいいかもしれません。
ttyp03

2019/04/22 04:55

質問ですが、(イ)ガワ(アプリケーションウィンドウ)側と(ロ)ブック側というのはそれぞれどういう意味でしょうか? 同じブックのマクロ内で、複数個所からExcelを操作しているということでしょうか?
komugi3333

2019/04/22 05:15

>(イ)ガワ(アプリケーションウィンドウ)側と(ロ)ブック側 あ、いえ、これはすでに開いているExcelファイルを取得する場合、そのExcelファイルに対して、2つのアプローチ方法がある、という意味で、TPOによって使い分けることができる、という意味で書かせていただきました。 ヘルプを読むと、GetObject関数は、 a:「第一引数を省略すると、第二引数で指定したオブジェクト(クラス)がアクティブならそれを取得する」 b:「第一引数でフルパスを指定した場合は、それが開かれていなければ、それを開きつつ取得し、すでに開いていればそれをそのまま取得する」 というような感じで書いてあったので、 a:は(イ)に通ずるもので、「第一引数を省略して、第二引数で ” Excel.Application ”をクラス名として指定すれば、ガワがオブジェクトして取得できるので、あとはOpenでもAddでも好きなものを使ってシートを開けばいい。すでに開いているファイルならそのガワを親オブジェクトにして、ファイル名でオブジェクトとして取得できる」と理解しています。 b:は、(ロ)に通ずるもので、「起動されるのはブックだけれども、それに関連づいたアプリケーションで開く」みたいな感じでヘルプにあったので、ガワではなくブック主体なんだなと勝手に理解して、そのように使えるんだと理解しています。 Web情報もそのような形だったので、そんな風な理解でいます。 自信はないのですが、現状、そう勝手に解釈している・・・ということで書かせていただきました。
komugi3333

2019/04/22 05:19

>「事前バインディング」という言葉にあまりこだわらないほうがいいかもしれません。 このお言葉をいただけて、なんだかほっとしているというか、とても納得できてきました。 このサイトで多くのご回答が無いということは、考えすぎなのかな、と思えてきました。 ありがとうございます。 もう少し待って、何もなければ、質問を閉じようと思います。 ほんとうにありがとうございます。
komugi3333

2019/04/22 05:31

あ、ガワとは「外殻」「外郭」という意味で使っています。 2010以前は MDI で、私にはアプリケーションウィンドウが「ガワ」に見えていたので・・・。テキトーな言葉遣いですみません。
ttyp03

2019/04/22 05:34

結局のところ、Word内で同じExcelブックに対する処理が複数個所あるという認識で正しいでしょうか。 (Excelで直に開いているブックをWordで参照する、ではない)
komugi3333

2019/04/22 06:03

>Excelで直に開いているブックをWordで参照する すみません。ちょっと私がちゃんと ttyp03さんの書かれた意味を理解できていないかもしれませんが、このケースを想定しています。 普通に ・Excelのファイルアイコンをダブルクリックして開いて、 ・Wordもダブルクリックでファイルを開いて、 ・そのWordのほうから、Excelのファイルをオブジェクトとして取得・操作する、 というケースです。 >Word内で同じExcelブックに対する処理が複数個所ある はい。「Word内で同じExcelブック」ということが、「ダブルクリックで開いたワードファイルから、ダブルクリックで開いたExcelファイルをオブジェクトとして取得・操作する」という意味でしたらそのとおりです。 「すでに開かれているExcelファイルがあるなら、念のためにそれを先に全部閉じておく」、といった処理にも使えるなと思いました。 また、少し前に「Excelブックに対する処理が複数個所あるという」ケースでなら、それをいっぺんに終わらせるコードを書くことになると思うのですが、それをやるのに、どうやらExcel(WordもAcceeも)には、「事前バインディング」と「実行時バインディング」というものがある・・・ということを学びました。 それは以前から自分も「AccessからのExcelファイルを扱う操作」で(その言葉を知らないで)すでにやっていたのですが、その際に、『参照設定をしつつ、GetObject関数、も使っていたので、今はいいけどいつかどこかで異常終了しないか?』と心配になった、という次第です。 でもそう心配することないようでしたら、問題が起こってから考えればいいかと、今は考えています。 本当はWordではなくAccessからで使いたいと思っていたのですが、Wordでも同じかなと思って質問ではWordで・・・と書いてしまいました。 一番気になったのは、バインディングということを2重に行ってしまって異常終了なので不具合が出ないか?というところでした。 (今まで何の疑問も無くそうしてきてしまっていたので) もしほかに正しい方法があるなら、知りたいと思い質問をさせて頂きました。 でも、ttyp03さんに「バインディング という言葉にとらわれなくてもよいのでは?」と言っていただき、そうしようと思っています。
ttyp03

2019/04/22 06:30

Excelで開いているブックをWordからも操作する、ということですね。 結局のところ、Word側でExcelオブジェクトを取得してもWorkbooksコレクションにはオープン済みのブックの情報は含まれてこないようです。 なので、Word側でOpenしてあげないとダメみたいです。 あくまでもそのオブジェクトごとに情報を持っているようです。 こんな感じのコードで確認できます。 Set xls1 = New Excel.Application Set xls2 = New Excel.Application xls1.Workbooks.Open "hoge.xlsx" Debug.Print "xls1" For Each wb In xls1.Workbooks Debug.Print wb.Name Next Debug.Print "xls2" For Each wb In xls2.Workbooks Debug.Print wb.Name Next Excelオブジェクトを2つ作って、1の方でオープンします。 1の方のWorkbooksには入ってますが(当然)、2の方のworkbooksには入っていませんでした。
komugi3333

2019/04/22 07:06

コードのご提示、ありがとうございます。 一度、動かしてみまして、ローカルウィンドウでも見てみました結果、動きは理解できました。 >Word側でOpenしてあげないとダメみたいです。 はい。こちらも理解できます。 いろいろと確認作業をして頂いてありがとうございます。 例えば xls2 のほうに、既にダブルクリックして開いているExcelファイルを「CreateObject関数以外」で Setできないのかな、と思ったわかなのですが、そのようなメソッドなり関数なりなんなりが、今のところ見つからないので、ひとまずはこれまでどおり、CreateObject関数を使ってみようと思います。 ほんとうにありがとうございます。
guest

0

(01)オブジェクトの種類を明確に型の宣言をすると事前バインディング(=アーリーバインディング:ある意味、「コンパイル時」バインディング?)

(02)Object型で宣言すると実行時バインディング(=レイトバインディング:文字通り、実行時バインディング?)

バインディングの話は、別アプリケーションやそのオブジェクトの操作の話ではなく、変数の宣言の仕方やコンパイル時か実行時かの違いの話、ということで、『Web情報や書籍などの情報を、私が勝手に「勘違い」して理解していたことが、今回の疑問の原因というか、質問の答え 』という結論に達することができ、とてもすっきりしました。

まだ完全には理解できていないかもしれませんが「2重のバインディング」ということも考えずに済み、CreateObject関数なども今までどおり使えることがわかり、ありがたいです。

皆さんからたくさん、コードも教えていただき、全部、1行ずつ、実行して色々と考えることができました。ありがとうございました。

みなさん全員に、自分にとってはとってもよいことをたくさん教えていただいたので、全員にベストアンサーを送りたい気持ちですが、考え方の過ちを教えてくださった hatena19さんをベストアンサーにさせて頂きたいと思います。

皆さま、ほんとうにありがとうございました。

投稿2019/04/22 12:06

komugi3333

総合スコア94

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問