アプリ版:「スタンプのみでお礼する」機能のリリースについて

いつもお世話になります。
VBA(Excel2007)の初心者です。

目的のファイルが開いていない時は開き、
既に開いている時は何もしない。
という処理をしたいと思い以下のコードを
書きました。

Dim wb As Workbook
Dim myfilename As String

For Each wb In Workbooks
If wb.Name = "予定表.xls" Then
Exit For
Else
myfilename = "\\___\__\予定表.xls"
Workbooks.Open Filename:=myfilename
End If
Next wb

実行したら何度もファイルを開こうとしてしまいます。
どこに問題があるのでしょうか?

ちなみにこれは"予定表.xls"のセルを参照したくて
ある処理の前に実行するつもりなのですが、
別のブックのセルを参照するときはやはり
そのブックを開かなくてはならないのでしょうか?

何卒よろしくお願いします。

A 回答 (5件)

こんにちは。



こんなスタイルになります。

'-------------------------------------------
Sub Test1()
  Dim Wb As Workbook
  Dim mPath As String
  Const FNAME = "予定表.xls" 'ファイ名
  mPath ="\\___\__ & "\" 'ディレクトリパス--'規定の場所は、Application.DefaultFilePath & "\"
  
  On Error GoTo Errhandler
   Workbooks(FNAME).Activate
  '------------------------------------------- ここから実際のプログラム
   Set Wb = Workbooks(FNAME)
   MsgBox Wb.Name & " " & Wb.ActiveSheet.Name
  
  Exit Sub
Errhandler:
  If Err.Number = 9 Then
    Workbooks.Open mPath & FNAME
    Resume Next
  End If
End Sub
    • good
    • 0

ループして、ワークブックが開いているのか調べる方法は、定石の基本形です。

私の書いているのは、それでは、つまらないので、ループしてロスをなくすために、こういう書き方をします。よほど、ループする方法とOn Error で開くの時間差は、開いているファイル数が多くなければ、それほど大きく違いありません。

また、On Error GoTo 0 は、あくまでも、On Error Resume Next と組み合わせて用いるものです。On Error GoTo ErrHandler とは、常識的にはセットでは用いません。

なお、以下の方法はあまり良い書き方ではありませんが、スクリプト型としては、こういう書き方もあります。ただ、こういう書き方は、読みにくくなるような気がします。メインの流れを見やすくするために、On Error GoTo ErrHandler という書き方をするわけです。
'-------------------------------------------

Sub Test2()
  Dim mPath As String
  Const FNAME = "予定表.xls" 'ファイル名
  mPath = "\\___\__ & " \ " 'ディレクトリパス"
  '-------------------------------------------
  On Error Resume Next
  Workbooks(FNAME).Activate
  If Err.Number > 0 Then
    Workbooks.Open mPath & FNAME
  End If
  On Error GoTo 0
  '-------------------------------------------
  'メインの処理
  MsgBox ActiveWorkbook.Name & " " & ActiveSheet.Name
End Sub

----------------------------------------
[エラー] を使用してマクロでハンドル エラーする方法
http://support.microsoft.com/kb/141571

この次のマクロでエラーが発生したときに、ErrorHandling プロシージャを使ってだった方法の例:
    • good
    • 1
この回答へのお礼

御礼が遅くなり申し訳ありませんでした。

難しくて中々内容が理解できませんで・・・。
1つの事を実現するにも色んな方法があるんですね。

とても勉強になりました。
この度はありがとうございました。

お礼日時:2009/12/09 11:49

エラートラップを書いているのは私のみですから、#3さんは、私宛に書いているようです。

一応、返事はしておきます。これは、基本的なことだと思います。

>On Error GoToにて例外をトラップするのは止めましょう。

基本的には、On Error GoTo 0 を使用するのは、On Error Resume Next に対するものです。しかし、エラーがなければ、そのまま順調に進むわけですから、On Error Goto ErrHandler で、一旦トラップを設けた以上は、それを外すということはありえません。

ここでは、もちろん、元のファイルがあるという前提になっています。

目的のファイルを実行しようとして、その目的のファイルがないから、エラーが発生したら、ファイルを開いて、元のコードに戻るというのが定石です。

ErrHandler のラベル移行に。もし、エラー値が残っている場合には、Err.Clear するべきかもしれませんが、On Error Goto 0 で、トラップを外すという意味がありません。もし、そうしたいなら、最初から、On Error Resume Next ~ On Error GoTo 0 とすべきです。

私の書いたコードの構造です。
'-------------------------------------------
On Error GoTo ErrHandler
 '目的のワークブックをActivate させて、エラーが発生するか試験させる
 '-------------------------------------------
 '実行プログラム 'エラーを修正したあとに、ここに飛ぶ
 'エラーがなければ、そのまま、以下に進んでいきます。
 Exit Sub '←ここで、実行ブログラムは終わりです。
ErrHandler:
 If Err.Number = 9 Then (9 ="インデックスが有効範囲にありません")
  'エラーが発生したら、目的のファイルを開き
 Resume Next 'エラーの発生した次の行に飛ぶ
 End If
'-------------------------------------------

もし、ファイルがないことを懸念するなら、このようにしますが、普通は必要ないと思います。もちろん、Dir を使わなければ、実行時エラーが発生して止まってしまいます。
'-------------------------------------------
Errhandler:
  If Err.Number = 9 Then
    If Dir(mPath & FNAME) <> "" Then
      Workbooks.Open mPath & FNAME
      Resume Next
    End If
  End If
'-------------------------------------------

だから、 If Err.Number = 9 Then (9=インデックスが有効範囲にありません) と、インデックス処理に対してのみに照準を合わせて、再び、別のエラーが発生した場合は、マクロ全体をエラーを排出せずに終わらせます。
    • good
    • 0

例外を起こさずに処理できるものに対して


On Error GoToにて例外をトラップするのは止めましょう。

例:

On Error GoTo ERROR_HANDLER
’ファイルオープン処理
ERROR_HANDLER:
’違うファイルオープン
On Error GoTo 0
    • good
    • 0

こんな感じで



Sub test()
Dim i As Integer

For i = 1 To Workbooks.Count
If (Workbooks(i).Name = "開きたいブック.xls") Then
Exit For
End If
Next

If (i > Workbooks.Count) Then Workbooks.Open Filename:="開きたいブック.xls"
End Sub
    • good
    • 0
この回答へのお礼

お礼が遅くなり申し訳ありません。

うまくいきました!
For each構文ではダメなのでしょうか。。。

この度はありがとうございました。

お礼日時:2009/12/07 10:01

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!