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
>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 を多用したコードは、特に理由が無い限りは避けるべきでしょう。
> Form2.SetFocus
> ActiveForm.Text1.SetFocus
> Form2.SetFocus
> ActiveForm.ActiveControl.Text = "123"
済みません。上記は、
Form2.SetFocus
Screen.ActiveForm.Text1.SetFocus
Form2.SetFocus
Screen.ActiveForm.ActiveControl.Text = "123"
の意味です。
>変数宣言は New 無しで行い、後で変数に Set するようにした方が無難です。
どうもありがとうございます。
一応、Excelを参照して、魔界の仮面弁士さんが教えてくださったとおり、
>しかし、VBから操作した場合はそうではありません。
>たとえば、Excel が 2 つ開いていた場合、または複数のブックが
>開かれていた場合、上記は、どの Range を操作すればよいのか、
>曖昧になってしまいます。
と言われて訂正したところ、
無事2回目も動くことができました!ありがとうございます。
しかし無知なものでレイトバインドというのがよくわかりません。
変数宣言で As Object にして、後で中身をSetってことですか?
とりあえず、
Set EApp = New Excel.Application
にしたところ、ここでエラーが起きました。
ここをどう変えればいいのでしょうか?
自分の知識のなさには恥を知ります。
どうか心の許される限り、徹底的にお願いします。
Excelの宣言をしたあとに、CallでサブルーチンのExcelの設定(フォントとか)を呼んでいるんですが
同じエクセルの同じワークブックの同じシートを・・・
っていう宣言ってないんですか?
教えていただいたとおりにすると無事できました!
ワケのわからない質問に答えてくださいまして
どうもありがとうございました!
ツイート | ![]() |