tagCANDY CGI VBレスキュー(花ちゃん) - VBレスキュー(花ちゃん)の投稿サンプル用掲示板 - Visual Basic 6.0 VB2005 VB2010
VB2005用トップページへVBレスキュー(花ちゃん)のトップページVB6.0用のトップページ
VBレスキュー(花ちゃん)の投稿サンプル用掲示板
     サンプル投稿用掲示板  VB2005 〜 用トップページ  VB6.0 用 トップページ
マクロをVBのコードに変換する場合の注意事項(VB6.0 基本編) ( No.14 )  [親スレッドへ]
日時: 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

但し、上記はあくまでもテスト例であってお薦めすることはできませんので当初のコードのような
終了処理を実施して下さい。



 [スレッド一覧へ] [親スレッドへ]