こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

Excel VBA、ファイルのオープンについて

どうにも解決が付かず、困ってしまっています、どなたかご回答をお願いいたします。

デスクトップ上にAというフォルダがあり、その中に二つのファイルa.xls、b.xlsがあるとします。
今、a.xlsを開いて、その中に「データ入力表」というシートを作り、そこに入力したデータをマクロを貼り付けたボタン一つでb.xlsへデータ蓄積できるようにしようと考えています。蓄積データが大量になることが予想されるので、別ファイルとしたかったのですが、そうすると、何度もb.xlsにデータを転記する必要があるので、b.xlsはその都度開いたり閉じたりせずに開いたままにしておきたいわけです。
そこで、ボタンに貼り付けるマクロには、
・最初にデータ転記する時にb.xlsを開く
・以降のデータ転記時にはb.xlsは開いたままにする
ように、IF文で分岐を付けたいのですが、最初にファイルを開くのは
 Set wb = Workbooks.Open("b.xls")
で良いわけですが、「b.xlsを開いたままデータを転記する」場合がどうにもうまくいきません。
ファイルをオブジェクト変数にセットするように、
Set wb = Workbook("b.xls")
とすると「インデックスが有効範囲にありません」と怒られ、パスの設定か?と思い、
myDir.Workbook("b.xls")
とすれば「オブジェクトが必要です」
と断られてしまいます。
この、転記先となるb.xlsを開いたままデータを転記する場合には、オープンしてあるb.xlsはどうセットしたら良いのでしょうか?、というのが今回の質問です。

まだ初心者のため要点が掴みづらい文章となってしまい、お答えしにくいかとは思いますが、どなたかこの混迷状態をご理解頂けた方、ご返答を宜しくお願いいたします。

投稿日時 - 2005-03-27 19:15:04

QNo.1294669

困ってます

質問者が選んだベストアンサー

#3さんのつけたしになっちゃいますが、変数の使い方がきちんと分かっていれば、モジュールレベルの変数という方法もあると思います。 Public 変数だと、残し忘れがありますが、どちらでも良いと思います。

Dim wb As Workbook 'モジュールレベルの変数
Sub test_open()
'開ける時
If wb Is Nothing Then
 Set wb = Workbooks.Open("b.xls")
End If
End Sub

Sub Sheet_Copy()
'コピーするとき
If Not wb Is Nothing Then
 ThisWorkbook.Sheets(1).Cells.Copy wb.Sheets(1).Range("A1")
'ここは工夫してください。
End If
End Sub

Sub Test_Close()
'閉じる時(ユーザーが閉じてしまった場合に、エラー・トラップを入れておく)
On Error Resume Next
 If Not wb Is Nothing Then
  wb.Save
  wb.Close
 End If
Set wb = Nothing
End Sub

投稿日時 - 2005-03-27 21:26:19

お礼

ありがとうございました。
No.3さんとNo.4さんのご回答で、ようやくエラーの謎が解けました。変数のセットについてもう一度勉強し治してくる必要がありますね、ほんとうにご回答有り難うございました。

投稿日時 - 2005-03-27 23:02:55

ANo.4

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.5

No.3です。
No.4のWendy02さんの回答で何故エラーが出るのかお分かりですよね。

If wb Is Nothing を使うときは、オブジェクト変数wbは
モジュールレベルかパブリックレベルでないといけません。
そこを気付いてもらうためにわざとその説明を抜かしました。

この際に”変数の摘要範囲”をしっかりと理解するようにしてください。
プログラムを書くためには必須ですから。

投稿日時 - 2005-03-27 21:54:54

お礼

No.4さんへのお礼にも書きましたが、お二人のおかげでエラーの謎が解けました。本当にありがとうございました。
なかなか成書にも問題解決の糸口となるヒントが見つからず、付け焼き刃のプログラム書きではやはり基本的な部分、今回のような変数の適用範囲のようなエラーの解決には限界がありました。
おっしゃるとおり、もう一度基本的な変数の使用法に関して勉強しておかなければならないことを痛感させられました。
本当にご回答ありがとうございました。

投稿日時 - 2005-03-27 23:09:07

ANo.3

こんなんでも出来るのでは?

If wb Is Nothing Then
  Set wb = Workbooks.Open("b.xls")
End If

投稿日時 - 2005-03-27 21:10:35

お礼

ご回答有り難うございます。
これだと、やはりb.xlsを開いたままの状態でマクロを実行すると、「b.xlsはすでに開かれています。二重に開くと・・・」のアラートが出てしまいます。
これが出ないようにしたいんですけどね~・・・

投稿日時 - 2005-03-27 21:36:27

ANo.2

エラーは#1さんの回答で回避出来ると思います。

開くファイル名やパスが同じなら、サブルーチン化してあげるとか。
開いているブック内から b.xls を探して、あれば変数にセット、
無ければこのマクロが書かれたファイルと同じフォルダ内にある
b.xls を開いてセットします。

'--------------------------------------------
Sub Test()
Dim wb As Workbook
 Call BookOpenCheck(wb)
 MsgBox wb.Name
End Sub

'--------------------------------------------
Sub BookOpenCheck(wb As Workbook)
Dim twb As Workbook, Flg As Boolean
 Flg = False
 For Each twb In Workbooks
   If twb.Name = "b.xls" Then
     Set wb = twb
     Exit Sub
   End If
 Next twb
 If Not Flg Then
   Set wb = Workbooks.Open _
     (ThisWorkbook.Path & "\b.xls")
 End If
End Sub

投稿日時 - 2005-03-27 20:06:45

お礼

ご返答有り難うございます。
一度開いてあるファイルをもう一度オープンしようとするとエラーが出ますよね?最初にデータを転記した後はb.xlsは開いたままになっているので、次のデータを入力・転記する時には、b.xlsは開いたままになっていますからこの状態で(b.xlsをオープンせずに)変数にセットしたい、ということで、IF分岐を考えたのですが・・・
サブルーチンを使ってファイルを探してあれば変数にセット、というのは思いつきませんでした。大変参考になりました、ありがとうございました。

投稿日時 - 2005-03-27 20:43:13

ANo.1

>Workbook("b.xls")
Workbooks("b.xls")
かと思います

投稿日時 - 2005-03-27 19:44:37

お礼

ご返答ありがとうごじました。
初歩的ミスで申し訳ありませんでしたが、
Workbooks("b.xls")
と、"s"を入れてある状態で「インデックス範囲が有効範囲にありません」というエラーメッセージがでるのですね~・・・
どうしてこういうエラーが出るのかが・・・。

投稿日時 - 2005-03-27 20:22:48

あなたにオススメの質問