[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『マクロによるシート切替について』(初心者)
Excel2003 WindowsXPを使用しています。 全文検索で下記のマクロを見つけて使わせて頂こうと 思っています。ボタンに登録して次のシートに切り替わって いきます。 Sub 右シートへ() '右隣のシートをアクティブにする ActiveSheet.Next.Activate END SUB 今回の質問ですが、最右のシートにきた時 次のシートがないのでマクロがエラーになります。 現在の対応策はこれも全文検索で見つけた On Error Resume Next ActiveSheet.Next.Activate という形にしてエラー発生時は何も処理をしない ようにしていますが、「最終シートです」とか「次の シートはありません」とかのMSGBOXを表示させたい と考えていますが、エラーが発生したらMSGBOXを 表示させる構文の書き方がわかりません。 どのように書けばいいでしょうか。 よろしくお願いします。 ------------
さらに全文検索をして解決策がありました。 Sub 右シートへ() '右隣のシートをアクティブにする On Error GoTo err1 ActiveSheet.Next.Activate Exit Sub err1: MsgBox "最終シートです" End Sub
にてエラー時MSGBOXを表示することができました。 エラー処理を他の構文に(マクロ)作って、起動していました。 同じ構文のなかにエラー処理を記述しなくてはいけない ことがわかりました。 (初心者)
VBAはシートをインデックス番号で表すことが出来ます。 「前から数えて ○番目のシート」 と言った感じです。
現在のシートが何番目のシートなのか 全部でシートが何枚有るのか それぞれ調べて、比較をすることでも メッセージボックスを表示させる事が出来ると思います。 Sub 右シートへ1() '右隣のシートをアクティブにする If ActiveSheet.Index = Sheets.Count Then MsgBox "最終シートです。" Else ActiveSheet.Next.Activate End If End Sub 左端かどうかを確認するには、「1」と比べると良いかもしれません。
また、インデックス番号を利用してシートを移動しても良いですね。 Sub 右シートへ2() '右隣のシートをアクティブにする If ActiveSheet.Index = Sheets.Count Then MsgBox "最終シートです。" Else Sheets(ActiveSheet.Index + 1).Activate End If End Sub ActiveSheet.Indexに加減算する数を変更すれば どこのシートにでもいけることになります。
二つ以上移動する場合は、移動できるかどうかの判定部分は 変更が必要になってきますが。。。
(HANA)
マクロは慣れていないと思いますが、 On Error Resume Next は 単にエラーを「無視する」ということなので、常用しない方が今後のためです。 内容が正しくなくとも、何の警告も出なくなります。
On Error Goto xxx は使い方次第で、正しく使えば有用とは思いますが、 今回のような内容でしたら、HANA さんが提示されたように条件判定をきちんとする よう心がけた方がよいと思います。 (Mook)
HANAさん、わざわざすみません。ありがとうございます。
両方の構文ともうまくいきました。
ちょっとわからないのですが宜しかったら教えてください。 今、EXCEL画面の下のシート名一覧は シート名を変更して 1番、2番、最終と3つのシートがあります コードの表示上では Micrososot excel obuject Sheet1 (1番) Sheet2 (2番) Sheet3 (最終) this workbook となっています。 教えて頂いた構文
>If ActiveSheet.Index = Sheets.Count Then を自分なりの言葉にしたいのですが シート名:最終にいる状態で ActiveSheet.Index ・・・今のシート番号(Sheet3)が Sheets.Count ・・シー総数(3)と同じなら という意味で 自分なりの覚え方にしたのですがそういうふうでいいでしょうか 手操作でシートの順番を 1番、最終、2番の順にしてもマクロはうまくいきます コードの表示上では Micrososot excel obuject Sheet1 (1番) Sheet2 (2番) Sheet3 (最終) this workbook のまま順番は入れ替わっていないのですが、シート名2番が最終(最右) にある状態でもうまくいくのはなぜでしょうか うまくいっているのに変な質問なのですが 自分なりの言葉で納得しよううとすると >If ActiveSheet.Index = Sheets.Count Thenはどういう説明になるの でしょうか。 ようするに ActiveSheet.Indexはどういう意味か ということかも しれませんが。よろしくお願いします。
Mookさん。おしゃる通りだと思いました。 そこで、ここでしっかり納得したいと思い質問をさせて頂きました。 質問を長々かいてしまってわかりにくいかもしれませんが
HANAさんの >VBAはシートをインデックス番号で表すことが出来ます。 >「前から数えて ○番目のシート」 >と言った感じです。
>現在のシートが何番目のシートなのか >全部でシートが何枚有るのか >それぞれ調べて、比較をすることでも >メッセージボックスを表示させる事が出来ると思います。 この部分がピンとこないというか、わからないのが現状です。
(初心者)
非表示シートがあるということも考慮して・・・・。
Sub test1() Dim sht As Object On Error Resume Next Set sht = ActiveSheet.Next Do Until sht Is Nothing Err.Clear sht.Select If Err.Number = 0 Then Exit Do Set sht = sht.Next Loop If sht Is Nothing Then MsgBox "最後のシートです" On Error GoTo 0 End Sub Sub test2() Dim sht As Object Set sht = ActiveSheet.Next Do Until sht Is Nothing If sht.Visible = xlSheetVisible Then sht.Select Exit Do End If Set sht = sht.Next Loop If sht Is Nothing Then MsgBox "最後のシートです" End Sub
test1は、On Error 〜を使った仕様。 test2は、使わない仕様です。
私は、この事象でエラートラップを利用した方法が特別問題があるとは 思いません。もちろん、On Errorを使わない方法に問題もありません。 この辺りは、どちらでもコードがわかりやすくなっていればよいと思っています。
一般論として、On Error ステートメントに関して・・・。
私がVBAでの仕事で On Error 〜 を使っていないブックなど きちんと確認はしていませんが、たぶん一つもない はずです。 そのくらい使用頻度の高いステートメントです。
ファイルI/Oに関するコードでは、間違いなく使いますしね!! よって、常用しないというより、正しい使い方を学ぶ ことをお勧めします。
Mookさんの投稿にある
>単にエラーを「無視する」ということなので
これに関しては、同感です!!
ichinose
シートインデックスは >>「前から数えて ○番目のシート」 を示します。
>コードの表示上では VBEのオブジェクトウィンドウ(左上の窓)に表示されている順番の事ですよね? 手作業でシートの順番を入れ替えても、並びは変わりませんね。
これは、(シート名)の前にある Sheet○ の名前でソートされて表示されています。
ですから、VBEの方を見るのではなく【エクセルのシートタブの並び】を見て下さい。 アクティブシートは、シートタブを数えた時、左から何番目にあるか。 = ActiveSheet.Index
と整理すると、納得が行きますか?
Micrososot excel obuject Sheet1 (1番) ←この間の並びで「何番目にあるか」 Sheet2 (2番) ←が分かるコードでは Sheet3 (最終) ←【ありません】。 this workbook
エクセルの方の |1番/2番/最終/ ↑ ↑ ↑ この並びで「何番目にあるか」です。
なので、シートを入れ替えた時も・・・・ |1番/最終/2番/ ↑ ↑ ↑ 「最終」シートは 2番目にあって(ActiveSheet.Index) シートは全部で 3番目まであるので(Sheets.Count) 一つ後ろのシートが選択できます。
「2番」シートは 3番目にあって(ActiveSheet.Index) シートは全部で 3番目まであるので(Sheets.Count) 一つ後ろのシートは選択できません。
(HANA)
HANAさん。たびたびすみません。ありがとうございます。 >エクセルの方の >1番 /2番 /最終/ > ↑ ↑ ↑ (1番目)(2番目)(3番目) >この並びで「何番目にあるか」です。
この説明よくわかりました。 構文(マクロ)を起動する際、今のシートが左から数えて 何番目にいるのかをActiveSheet.Indexっていうんですね。 今のシート名「最終」にいる場合ActiveSheet.Index=3 その番号とSheets.Count=シート総数(3)を確認して今のシートが 最右のシートだと 判断するということですね。 よくわかりました。 具体的な説明ありがとうございました。
ichinoseさん。 構文2つもご提示ありがとうございました。 非表示のシートを作っておいてtest1、test2両方ともに 表示しているシートの最右のシートでMsgBox "最後のシートです" が表示しました。 構文の中身はチョットチンプンカンプン(表現が古いかもしれませんが) ですが、出来る範囲で確認してみようと思います。 いずれにせよ、・・・を考慮して・・・というところが今後どのような 仕様にするのかという場面で必要になってくるんだなあということが すこしわかったような気がします。 ありがとうございました。(初心者)
解決後ですが、On Error ステートメントについてもう一つ・・・・。
>同じ構文のなかにエラー処理を記述しなくてはいけない 同じ構文------>同じプロシジャーだと思いますが、 私もそのとおりだと思いますし、今までもそのようにしていました、が・・・。
例として、割り算の計算で0で割る場合を取り上げます。 新規ブックの標準モジュールに
Sub 割り算() On Error GoTo 割り算err Dim 割られる数 As Long Dim 割る数 As Long 割られる数 = Application.InputBox("割られる数を入力してください", Type:=2) If TypeName(割られる数) <> "Boolean" Then 割る数 = Application.InputBox("割る数を入力してください", Type:=2) If TypeName(割る数) <> "Boolean" Then MsgBox 割られる数 & "÷" & 割る数 & " = " & (割られる数 / 割る数) End If End If On Error GoTo 0 Exit Sub 割り算err: MsgBox Err.Description End Sub
上記の割り算の実行で、割られる数として 1 割る数として、0を入力すると
仕様どおり 「0 で除算しました。」というメッセージが表示されます。
これを以下のようにプロシジャーを分割し、
Sub 割り算2() On Error GoTo 割り算2err Dim 割られる数 As Long Dim 割る数 As Long 割られる数 = Application.InputBox("割られる数を入力してください", Type:=2) If TypeName(割られる数) <> "Boolean" Then 割る数 = Application.InputBox("割る数を入力してください", Type:=2) If TypeName(割る数) <> "Boolean" Then Call 割り算計算(割られる数, 割る数) End If End If On Error GoTo 0 Exit Sub 割り算2err: MsgBox Err.Description End Sub '============================================================== Sub 割り算計算(ByVal ln1 As Long, ByVal ln2 As Long) MsgBox ln1 & "÷" & ln2 & " = " & (ln1 / ln2) End Sub
上記の割り算2を実行し、前回同様 割られる数として 1 割る数として、0を入力しても 「0 で除算しました。」というメッセージが表示されます。
つまり、プロシジャー 割り算計算 内の MsgBox ln1 & "÷" & ln2 & " = " & (ln1 / ln2)
の↑の箇所で発生したエラーが
別プロシジャー割り算2の
割り算2err: MsgBox Err.Description
上記のエラー処理ステートメントで処理されてしまっています。 私は、非常に不思議でした。
もっとも呼び出すプロシジャーがオブジェクトモジュールの場合は、きちんと エラーになりましたが・・・。
このことから、 >同じ構文のなかにエラー処理を記述 しなくてもエラー処理が可能になってしまうことがある ということになります。 On Error 〜 の使用方法としては、NGですが、
この現象を知らないと思わぬ動作になってしまう場合もあるので 記述しておきます。
ichinose
ichinoseさん。さらなる記述ありがとうございます。 まず、Sub 割り算 実行してみました。
割られる数:100 割る数:25 とすると 100÷25=4
割られる数:100 割る数:0 とすると 0で除算しました
割られる数:未入力 OK 型が一致しません
割られる数:未入力 キャンセル 割る数:未入力 キャンセル オーバーフローしました となりました。
ichinoseさんが説明されたいことの以前の段階で疑問がうまれて しまいました。 割られる数:100 割る数:25 とすると 100÷25=4
以外のMSGBOXは記述されていないのに エラーの入力というか0で割ったり入力なしでOK した場合も対応のMSGBOXが表示するのは 割り算2err: MsgBox Err.Description これが走ると上記のMSGBOXが表示すると考えてもいいでしょうか 全文検索で見ても探せなかったのですがいかがでしょうか まず、ここで疑問がうまれましたので教えてください。 (初心者)
挙動を確かめることも大切ですが、エラーの発生したときに処理内容を理解する方 がよいと思います。
VBA(VBSも)ではエラーが発生すると処理を中断しますが、これはエラーが発生したときの デフォルトの挙動で On Error Goto 0 を設定したのと同じ動作です。
自身でエラー処理をしたい場合は、処理先のルーチンを指定しますし、 On Error Resume Next でエラーを無視して、次の処理を進めます。
いずれの場合もエラーが発生した場合は、Err というオブジェクトに、エラーコードや エラーの説明が記録されます。 http://excelvba.pc-users.net/fol6/6_8.html http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_140_02.html のあたりを参照されると、詳しいことがわかるかと思います。
#なんでこういうところにMicrosoftのページが上がってこないんだろう。 #と思ったら、下の方にあったけど http://msdn.microsoft.com/ja-jp/library/cc344117.aspx #じゃぁなぁ・・・。 (Mook)
Mookさん、ありがとうございます。 http://excelvba.pc-users.net/fol6/6_8.html こちらの掲載の マクロの出力(MSGBOX)がわかりました。 こういうもの(オブジェクト)が用意されていることがわかりました。 これでichinoseご提示のマクロの違いの意味にかかれます。 ありがとうございました(初心者)
ichinoseさん。ご報告です。Sub 割り算() Sub 割り算2() 2つのタイプ 実行し確認しました。 同じようにできました。
Sub 割り算() では計算もエラー処理も1つのプロシージャのなかで やっていて、Sub 割り算2では入力の処理のみ実施し、実際の計算は 他のプロシージャにわたしていることがわかりました。 ありがとうございました。 On Error GoTo 0の意味がよくわらなっかたので調べました。 エラーの判定を標準処理にする場合はOn Error GoTo 0 と記述 とありましたのでそのまま納得しました。 ありがとうございました。(初心者)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.