Excel操作を2回してもエラーが起きないようにするには?

解決


ろぺ  2005-11-01 20:55:29  No: 127207

VB6 SP6    ORACLE 10g  Office 2000

初めての投稿です。
初心者で質問の内容、ソースの不十分などがあるかもしれませんが
どうかご教授お願いいたします。

概要:
エクセルにSQLで抽出したデータを書き込みたい。

状況:
1回目はエクセルに書き込めますが2回目は書き込めません。

エラー:
実行時エラー'1004'
'Range'メソッドは失敗しました:'_Global'オブジェクト

未熟な私は何をどうしたらいいのかわかりません。
何が原因かも考えたり、ネットで探してみましたがよく理解できませんでした。

以下にソースを載せます。よろしくお願いします。

Dim ssTEST      As Object                      'セッション
Dim dbTEST      As Object                      'データベース
Dim sSQL        As String                      'SQL文
Dim dsTEST      As OraDynaset                  'ダイナセット
Dim LX          As Long             'カウンタ
Dim EApp        As New Excel.Application       'エクセルの宣言
Dim eBook       As Workbook                    'ブックの宣言

Private Sub Command1_Click()

    sSQL = "" _
            & " SELECT [データ] FROM [テーブル] " _
            & "  ORDER BY [データ] "
            
    Set dsTEST = dbTEST.CreateDynaset(sSQL, 4)

    LX = 1
    Set eBook = EApp.Workbooks.Add
    
    '*****1行目のフォントサイズを18に設定******
    Range("A1:D1").Select                       '*  ←ここでエラー
    With Selection.Font                         '*
        .Size = 18                              '*
    End With                                    '*
    '*********************************************
    
    '*******セルのBとDの列の幅を5に設定**********
    Columns("B:D").Select                       '*
    Selection.ColumnWidth = 5                   '*
    '*********************************************
    
    Do Until dsTEST.EOF
        eBook.Worksheets(1).Range("A" & LX) = dsTEST.Fields("[データ]").Value
        LX = LX + 1
        dsTEST.MoveNext
    Loop
    
    'ダイナッセットの開放
    Set dsTEST = Nothing
    eBook.Close
    EApp.Quit
    Set EApp = Nothing
    Set eBook = Nothing
End Sub


魔界の仮面弁士  2005-11-01 21:42:39  No: 127208

>1回目はエクセルに書き込めますが2回目は書き込めません。
大抵は、コーディング上のミスにより、暗黙のExcelオブジェクトが
生成されてしまう事が原因です。

Excelへの参照設定を外し、レイトバインドのコードに変更してみてください。
その際、コンパイルエラーが出るようであれば、そこに原因があります。

> Dim EApp        As New Excel.Application       'エクセルの宣言
間違いではありませんが、これは止めておきましょう。
変数宣言と同時にNewを使うことは、あまり推奨されません。

変数宣言は New 無しで行い、後で変数に Set するようにした方が無難です。

> Range("A1:D1").Select                       '*  ←ここでエラー
ここに問題(の一つ)があります。
# レイトバインドの場合、上記はエラーになりますので、Excelの場合は
# 参照設定しない方が、この手のエラーを事前に見つけやすくなりますよ。

Excel VBA の場合は、単に Range("A1") と書いた場合、それが
現在作業中のワークシート上の A1 位置を示すことになります。

しかし、VBから操作した場合はそうではありません。
たとえば、Excel が 2 つ開いていた場合、または複数のブックが
開かれていた場合、上記は、どの Range を操作すればよいのか、
曖昧になってしまいます。

この場合は、
  Range("A1").Value = "12345"
ではなく、
  eBook.Worksheets(1).Range("A1").Value = "12345"
のような表記を使うようにしましょう。

その後のコードにある Selection や Columns も同様です。
きちんと、どのオブジェクトのメンバなのかを明示しましょう。

それから、Select メソッドを呼び出してから、Selection にて
アクセスするような表記も避けましょう。

Selection 経由の操作というのは、VB で言えば、
  Form2.Text1.Text = "123"
の一行で済むコードを、
  Form2.SetFocus
  ActiveForm.Text1.SetFocus
  Form2.SetFocus
  ActiveForm.ActiveControl.Text = "123"
のように書いているような物です。

処理が曖昧になりますし、フォーカス移動の分だけ低速になりますので、
Selection を多用したコードは、特に理由が無い限りは避けるべきでしょう。


魔界の仮面弁士  2005-11-01 21:44:51  No: 127209

>  Form2.SetFocus
>  ActiveForm.Text1.SetFocus
>  Form2.SetFocus
>  ActiveForm.ActiveControl.Text = "123"

済みません。上記は、

  Form2.SetFocus
  Screen.ActiveForm.Text1.SetFocus
  Form2.SetFocus
  Screen.ActiveForm.ActiveControl.Text = "123"

の意味です。


ろぺ  2005-11-01 22:09:00  No: 127210

>変数宣言は New 無しで行い、後で変数に Set するようにした方が無難です。
どうもありがとうございます。

一応、Excelを参照して、魔界の仮面弁士さんが教えてくださったとおり、

>しかし、VBから操作した場合はそうではありません。
>たとえば、Excel が 2 つ開いていた場合、または複数のブックが
>開かれていた場合、上記は、どの Range を操作すればよいのか、
>曖昧になってしまいます。

と言われて訂正したところ、
無事2回目も動くことができました!ありがとうございます。

しかし無知なものでレイトバインドというのがよくわかりません。
変数宣言で As Object  にして、後で中身をSetってことですか?
とりあえず、
Set EApp = New Excel.Application
にしたところ、ここでエラーが起きました。
ここをどう変えればいいのでしょうか?
自分の知識のなさには恥を知ります。
どうか心の許される限り、徹底的にお願いします。


ろぺ  2005-11-01 22:58:18  No: 127211

Excelの宣言をしたあとに、CallでサブルーチンのExcelの設定(フォントとか)を呼んでいるんですが
同じエクセルの同じワークブックの同じシートを・・・
っていう宣言ってないんですか?


ろぺ  2005-11-02 00:39:29  No: 127212

教えていただいたとおりにすると無事できました!
ワケのわからない質問に答えてくださいまして
どうもありがとうございました!


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加