VB6.0よりExcelのシートにウィンドウ枠の固定を設定したく、
下記コードを作成しました。
しかし、1度目の実行は成功するのですが、続けて2度目の実行を行うと
ActiveWindow.FreezePanes = True ・・・① の個所で
「実行時エラー91:
オブジェクト変数またはWithブロック変数が設定されていません。」
と実行エラーが発生するか、もしくは、ウィンドウ枠の固定が設定されずに、表面上は実行が成功したかのようにみえます。
どうしたら上手くできるかご存知の方、教えて下さい。
よろしくお願い致します。
Private Sub Command1_Click()
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
'オブジェクトの設定
Set xlApp = CreateObject("Excel.Application")
Set xlBook = xlApp.Workbooks.Add
Set xlSheet = xlBook.Worksheets(1)
'ウィンドウ枠の固定の設定
xlSheet.Activate
xlSheet.Range("A5").Select
ActiveWindow.FreezePanes = True ・・・①
xlSheet.Range("A1").Activate
'ファイル保存
xlBook.SaveAs ファイル名
xlBook.Close
xlApp.Application.Quit
'オブジェクトの解放
Set xlApp = Nothing
Set xlBook = Nothing
Set xlSheet = Nothing
End Sub
ActiveWindow.FreezePanes = True ・・・①
ActiveWindowがオブジェクトとして宣言してないし、
オブジェクトの設定もしてないからでは?
たとえば、
Set xlApp = CreateObject("Excel.Application")
Set xlApp2 = CreateObject("Excel.Application")
のようにして、Excel を同時に 2 つ起動させた場合を想像してみてください。
その場合、
> Set xlBook = xlApp.Workbooks.Add
> Set xlSheet = xlBook.Worksheets(1)
などのコードは、「xlApp」を操作していることが明確ですが、
> ActiveWindow.FreezePanes = True
というコードは、xlApp と xlApp2、どちらを操作しているか不明瞭ですよね?
そのため、今回のような問題が生じてしまうわけです。
つまりこの場合は、
xlApp.Windows(1).FreezePanes = True
あるいは、
xlApp.ActiveWindow.FreezePanes = True
などといった書き方が必要になります。
(たとえ、Excel の起動数が 1 個だけだったとしても)
いきなり ActiveWindow から書き始めた場合、これが Excel VBA であれば、
「自分自身」を操作している事になりますので、特に問題とはならないのですが、
外部から制御する場合は、曖昧な記述となり、誤動作を引き起こします。
なお、参照設定を外した場合は、
xlApp.ActiveWindow.〜〜
と書く事はできても、
ActiveWindow.〜〜
と書く事ができなくなるので、問題を見つけやすくなります。
(コンパイル時に、VB が ActiveWindow を未定義変数と判断してエラー扱いになる)
返信ありがとうございます。
ActiveWindow.FreezePanes = Trueの文を
xlApp.ActiveWindow.FreezePanes = Trueとしたら、上手く実行できました。
親切丁寧な説明をして頂き、とても解りやすく勉強になりました。
ありがとうございました。
魔界の仮面弁士さんの説明で1つだけ
> なお、参照設定を外した場合は、
という箇所が解らないのですが、参照設定を外すとは、
[プロジェクト]メニューの[参照設定]の設定を外すということですか?
申し訳ありませんが教えて下さい。よろしくお願い致します。
> という箇所が解らないのですが、参照設定を外すとは、
>[プロジェクト]メニューの[参照設定]の設定を外すということですか?
そうです。その場合、
Dim xlApp As Excel.Application
Dim xlBook As Excel.Workbook
というコードは、
Dim xlApp As Object
Dim xlBook As Object
という書き方にする事になります。
ついでにもう一つ。
> xlApp.Application.Quit
これは、“Application”が冗長です。
参照先は同じなので、
xlApp.Quit
xlApp.Application.Quit
xlApp.Application.Application.Quit
xlApp.Application.Application.Application.Quit
などは、いずれも同じ結果となります。
返信ありがとうございます。
早速、実験してみました。
魔界の仮面弁士さんのおっしゃる通りの結果になり、
とてもいい勉強になりました。
本当にありがとうございました。
ツイート | ![]() |