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

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

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

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

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

Q&A

解決済

2回答

13830閲覧

[GetObject]と[CreateObject]の使い方について

u_zu

総合スコア50

VBA

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

Access

Accessはマイクロソフトによるリレーショナルデータベース管理システムです。オブジェクト指向のアプリケーション作成に対応しており、テーブルや編集をはじめ、クエリ生成、入力フォーム作成、レポート作成など一通りの機能を備えています。

0グッド

0クリップ

投稿2018/11/25 03:13

前提・実現したいこと

ACCESSから既存のEXCELファイルを操作しようとしています。既存のEXCELファイルなので、
GetObjectからファイルを取得して、編集しようとしましたが、うまくいきません。
試しにCreateObjectからも色々試したのですが、よくわからなくなってしまいました。

おそらく、基本的なことがよくわかっていないと思いますが、よろしくお願いします。

発生している問題・エラーメッセージ

質問1
Private Sub Get_Test()プロシージャを実行すると、Test.xlsxはSheetが
一枚もない状態になってしまいます(EXCELを起動した時の状態?)

質問2 Private Sub Create_Test()プロシージャの場合

    GetObjectではなく、CreateObjectを使うと
Test1.xlsxは意図通りに編集され、保存もされますが、
エクセルプログラムが終了してくれません。

途中にある、objCreate.Application.Visible = True
を削除すると、エクセルプログラムが終了してくれます
(タスクマネージャーにもエクセルは無いです)。
visibleがtrueかfalseでプログラムが終了するかどうかが
左右されるのでしょうか?

エラーメッセージ

該当のソースコード

Private Sub Get_Test()

Dim objGet As Object

Set objGet = GetObject("C:\Test.xlsx")
objGet.Application.Visible = True

objGet.sheets("sheet1").range("A1") = "あいうえお"

objGet.Save

objGet.Close
Set objGet = Nothing
End Sub

Private Sub Create_Test()

Dim objCreate As Object
Dim appbook As Object
'Dim objGet As Excel.Application

Set objCreate = CreateObject("excel.application")
objCreate.Application.Visible = True

Set appbook = objCreate.Workbooks.Open("C:\Test.xlsx")

appbook.sheets("sheet1").range("A1") = "あいうえお"

appbook.Save

appbook.Close

Set appbook = Nothing

Set objCreate = Nothing
End Sub

VBA ソースコード

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

Office365
ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

質問1

ウィンドウが非表示になっているだけだと思われます(シートが1枚もないブックというのは通常作成できません)。
手作業であれば、「表示」タブの「ウィンドウの再表示」で表示できます。

VBAであれば以下の処理で、対象ブックのすべてのウィンドウを再表示できるでしょう。

vba

1Dim objGet As Excel.Workbook 2'... 3 4'注:objGet.IsAddinがTrueの時はobjGet.Windows.Countが0になるためこの方法では不可 5Dim win As Excel.Window 6For Each win In objGet.Windows 7 win.Visible = True 8Next win

質問2

Application.UserControlがTrueだと、ユーザーが操作中・操作する可能性がある、として自動終了しません。
とはいえこちらには頼らず TanakaHiroaki さんの回答のように明示的に終了する処理を追加した方が良いでしょう。


181127:コメントの内容に関して追記

Excelそのものを最前面に持ってくる方法

経験上、Excel2010ではExcel.ApplicationオブジェクトのVisibleプロパティをTrueにすることで最前面になりました。
しかし、Excel2013以降だとちょっと動作が怪しいことがありました。

そのため、Visibleプロパティの操作はExcelが非表示なら表示にする程度にとどめておき、
ウィンドウを最前面にするための処理であるAppActivateExcel.ApplicationオブジェクトのCaptionプロパティを渡した方がより無難だと思われます。

また、Excel関連オブジェクトであればApplicationプロパティからApplicationオブジェクトは取得できるため

vba

1Call VBA.AppActivate(objGet.Application.Caption)

でよいはずです。

VBAのAppActivateとWshShellのAppActivateの違い

両者は一部動作が異なるため、場合によっては使い分けることがあります(今回のケースではVBAのAppActivateの方がコードがシンプルになるので良いでしょう)。

具体的には、対象のウィンドウが見つからなかったときに、VBAのAppActivateはエラーが発生します。
対してWshShellのAppActivateは、成功・失敗を返り値として返します。

ウィンドウが表示されるまで待機する、的な処理をしたい場合にはWshShellのAppActivateが適しているということになります。

投稿2018/11/25 04:58

編集2018/11/27 14:43
imihito

総合スコア2166

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

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

u_zu

2018/11/25 05:52

どうもありがとうございます。おっしゃる通り、非表示になっていました。こんなことがあるんですね。 質問2の方もなるほどです。
u_zu

2018/11/25 11:54

示していただいたソースに少々難があるようです。。。
u_zu

2018/11/25 12:40

objGet.Parent.Windows(1).Visible = True を挿入したらちゃんと表示されました。。。
imihito

2018/11/25 12:45

指摘ありがとうございます、修正しました。 `objGet.Parent.Windows(1)`ではApplicationオブジェクトのWindowsを参照するため「Excelのすべてのウィンドウのうち1番目(最前面)にあるもの」になってしまいます。 objGet.Windows.Item(1)~とするとそのブックのウィンドウについての操作になります。
u_zu

2018/11/25 13:08

早々のご連絡 ありがとうございます。 勉強になります。どこでこのような知識を得るのですか? (書籍とかには無いですよね?) objGet.Windows.Item(1)~ として確かにできました。 一つ、参考までに教えて頂きたいのですが、私が最初に書いた、
u_zu

2018/11/25 13:09

objGet.Parent.Windows(1).Visible = True の前に、 objGet.Application.Visible = True を入れると、この一文でvisibleになるからウインドウの最前面にくる、と考えることは可能なのでしょうか?(いろいろテストしたらできたので。。。)
imihito

2018/11/25 14:46

GetObject絡みのWindowの動作は実体験です。 `objGet.Application.Visible = True`を入れた場合は「Windows(OS)内の全てのウィンドウで最前面になる」で「Excelの管理しているウィンドウのうち最前面かどうか」とは少し違った話になります。 `(Workbook).Activate`をすれば、属しているExcelのウィンドウの中でそのブックのウィンドウを最前面に持ってくることはできます。 また、Excel2013以降では`Application.Visible`が`True`の時に再度Trueにすると意図しない挙動になることがあったので注意が必要です(代替:`AppActivate`)
u_zu

2018/11/26 13:16

どうもありがとうございます。なるほど、AppActivateを使う、というのはちょっと気が付かなかったです。wshですね。VBAでも使えますね。 Dim objWshShell object Set objWshShell=CreateObject("Wscript.Shell") objWshShell.AppActivate"book1" みたいな感じで。
u_zu

2018/11/26 13:17

>また、Excel2013以降では`Application.Visible`が`True`の時に再度Trueにすると意図しない挙動に>なることがあったので注意が必要です(代替:`AppActivate`) このAppActiveというのは、visible=trueのときじゃないと作動しないですね(テストしました。考えてみれば当たり前ですね、見えないものをアクティブにはできないですね)
u_zu

2018/11/26 13:44

ベストアンサーを付けると解決積みになるんですね
TanakaHiroaki

2018/11/26 14:31 編集

解決済みのところすみませんが、 VBAで対象のExcelファイルを最前面にする記述は以下のようになると思います。 (記述を何度か修正しました。) Call VBA.AppActivate(objGet.Parent.Application.Caption)
u_zu

2018/11/26 21:18

TanakaHiroakiさん どうもありがとうございます。あとでテストしてみます。 色々分からないことだらけです。。。何か気づかれたらなんでも教えてください。
u_zu

2018/11/27 13:38

AppActivate (objGet.Parent.Application.Caption) で取得できますね。
u_zu

2018/11/27 21:37

imihitoさん どうもありがとうございます。勉強になります。
guest

0

質問2について回答します。
Excelを終了させる処理を追加してはどうでしょうか。

VBA

1appbook.Close 2 3objCreate.Quit 'Excelを終了 4 5Set appbook = Nothing

投稿2018/11/25 04:32

TanakaHiroaki

総合スコア1063

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

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

u_zu

2018/11/25 05:51

どうもありがとうございます。できました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問