- 日時: 2007/08/17 08:39
- 名前: 花ちゃん
- ***********************************************************************************
* カテゴリー:[エクセル][][] * * キーワード:マクロ,コード,プロセス,タスク,終了しない,解放されない * *********************************************************************************** ----------------------------------------------------------------------------------- マクロをVBのコードに変換する場合の注意事項 - 花ちゃん 2007/08/16 ----------------------------------------------------------------------------------- http://hanatyan.sakura.ne.jp/vbhlp/caution.htm http://hanatyan.sakura.ne.jp/vbhlp/ExcelErr.htm ここの[Excel & Word 関係]のところにも書いているのですが、何時まで経っても同様の質問 がありますので、敢えて、こちらの方にも書いておきます。
----------------- 魔界の仮面弁士 さんの投稿より抜粋 ------------------------------ http://hanatyan.sakura.ne.jp/logbbs1/wforum.cgi?mode=allread&no=781#782
Excel VBAの場合は、「自分自身」が持っているシートである事が明確なので、 上位のオブジェクト(ApplicationやWorkbookなど)の記述を省略できますが、 外部から制御する時は、省略できないのです。(Excelの起動数が1個であっても同様です)
上位オブジェクトの記述を省略しても、(参照設定を行っていれば)エラーにはなりませんが、 省略してしまうと、暗黙のうちに、Excelへの参照が内部で生成されてしまうため、 そのオブジェクトを、プログラムから解放できず、終了しない要因となります。 -----------------------------------------------------------------------------------
行の挿入・列の挿入等をマクロで記録してみますと下記のようになります。
Selection.EntireColumn.Insert '列の挿入 Selection.EntireRow.Insert '行の挿入
ここで、VBAのヘルプで Selection プロパティ を調べてみますと、対象が Application オブジェクト と Windows オブジェクト になっているのが解るかと思います。 従って、上記のコードをそのまま使用すれば、当然、上位オブジェクトを省略した記述になり オブジェクトを解放することが出来ず、プロセスが終了(タスク上に残る)しない事になります。
では、下記ではどうでしょう。 ----------------------------------------------------------- 列の挿入 - いし 2004/12/24-11:30 No.1354 http://hanatyan.sakura.ne.jp/logbbs1/wforum.cgi?mode=allread&no=1354&page=1410
列を挿入させたいのですが、次のコードで実行したところエラーが発生します。 「オブジェクトは、このプロパティまたはメソッドをサポートしていません」
Set objExcelApp = CreateObject("Excel.Application") objExcelApp.DisplayAlerts = False objExcelApp.Visible = False objExcelApp.Workbooks.Open FileName:=FileName, updatelinks:=False Set objExcelWkb = objExcelApp.Workbooks(Right(FileName, Len(FileName) - InStrRev(FileName, "\")))
(略) objExcelWkb.Worksheets(1).Columns("C:C").Select objExcelWkb.Worksheets(1).Selection.Insert Shift:=-4161 ←ここでエラー
見ての通りの実行時バインディングですが関係あるでしょうか? Excelでマクロ記録して流用しました。-4161のところは”xlToRight”になっていましたが そのままでは使えないようなので定数を入れました。 ----------------------------------------------------------- 回答例、
objExcelWkb.Worksheets(1).Range("c1").Activate objExcelWkb.Worksheets(1).Selection.Insert Shift:=xlToRight
c1とかc列の適当な所をActivateにすると大丈夫だと思います
----------------------------------------------------------- 一見すると、どちらも問題がないように見えますが、先のヘルプにも書いてある通り、 又、エラーメッセージの内容のように、「オブジェクトは、このプロパティまたは メソッドをサポートしていません」、即ち objExcelWkb.Worksheets(1) オブジェクトに Selection プロパティがありませんと言う事になります。
特に、今回のように参照設定せずに、実行時バインディングで使用された為に、自動メンバー 表示等の機能が使えなかった事にも一因はあるかと思いますが、対象オブジェクトを省略したり 間違えないように十分注意して下さい。 従って、正しくは、objExcelApp.Selection.Insert Shift:=-4161 のように書けば残る事は ありません。
そもそも、今回の場合、Selection プロパティ を使うのが目的ではなく、EntireRow プロパティ を使う事が目的なので、EntireRow プロパティ の対象オブジェクトを調べると Range コレクションになっているので、下記のように変換してやれば、Selection プロパティを 使用せずとも目的が達成できます。
変換前 Selection.EntireColumn.Insert '列の挿入
変換後 xlSheet.Range("E:E").EntireColumn.Insert
変換前 Selection.EntireRow.Insert '行の挿入
変換後 xlSheet.Range("5:5").Insert 又は、xlSheet.Range("B5").EntireRow.Insert
----------------------------------------------------------------------------------- マクロでは、オブジェクトを省略して書かれているもの(よく変換間違いをされているもの)を 下記に上げておきます。 ----------------------------------------------- 誤 Application.CentimetersToPoints Application では、どれを指しているのか特定できないので、NG!
正 xlApp.CentimetersToPoints のように明示して下さい。 ----------------------------------------------- 誤 ActiveSheet
正 xlBook.ActiveSheet 又は xlSheet のようにシート名を指定するようにして下さい ----------------------------------------------- 誤 ActiveCell
正 xlSheet.Activate や xlApp.ActiveCell のように明示して下さい。 ----------------------------------------------- 誤 Key1:=Range("C2")
正 Key1:=xlSheet.Range("C2") どのシートかを明示する事 ----------------------------------------------- 誤 xlSheet.Range(Cells(1, ・・・略
正 xlSheet.Range(xlSheet.Cells(1, ・・・略 ----------------------------------------------- 誤 Selection.ClearContents
正 xlSheet.Activate xlApp.Selection.ClearContents ----------------------------------------------- 以下投稿されたコードより抜粋(正解は上記参照)
誤 .Range(Selection, Selection.End(xlDown)).Select 誤 .Range(Selection, Selection.End(xlToRight)).Select 誤 Selection.Paste 'ここでエラーになります 誤 xlsSheet.Shapes("txtNendo").Select: Selection.Characters.Text = "年度です"
省略されて書かれているのは上記以外にもありますので、マクロを流用する場合は十分注意して そのまま、マクロをペーストするのではなく、VB上でインテリセンス機能等を活用しながら手入力 するようにして下さい。
------------------------------------------------------------------------- マクロとは関係ないのですが、下記のような投稿もありました。
'★エクセルオブジェクトの解放 excelApp.Quit 'Excelアプリケーションの終了 Set excelApp = Nothing 'アプリケーションオブジェクト解放 Set excelBook = Nothing 'ワークブックオブジェクト解放 Set excelSheet = Nothing 'シートオブジェクト解放
解放の順番が逆になっている場合が結構あります。
但し、VB6.0 の場合 上記で解放されないという事はありません。 実は、正しくExcel を扱っていれば、終了時の処理は、Excel を閉じるだけで、Excel のプロセス が残る事なくキチンと終了する事ができます。
====================================== 従って下記の終了処理は、 ====================================== '-------------------------------------------------------------- '保存時の問合せを非表示に設定 xlApp.DisplayAlerts = False 'Worksheet を名前をつけて保存します 'xlSheet.SaveAs xlFilePath 'オブジェクトを解放します Set xlSheet = Nothing xlBook.Close 'Book を閉じる Set xlBook = Nothing xlApp.Quit 'Quit メソッドを使って Excel を終了します。 Set xlApp = Nothing End Sub
======================================================== 下記のように書いてもExcel がキチンと解放されます。 (Set xlApp = Nothing のような関連付けを解除しなくても) ======================================================== '-------------------------------------------------------------- '保存時の問合せを非表示に設定 xlApp.DisplayAlerts = False 'Worksheet を名前をつけて保存します 'xlSheet.SaveAs xlFilePath xlApp.Quit 'Quit メソッドを使って Excel を終了します。 End Sub
但し、上記はあくまでもテスト例であってお薦めすることはできませんので当初のコードのような 終了処理を実施して下さい。
|