質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

Q&A

2回答

6715閲覧

【Excelマクロ】シート切替時の表示位置取得

forestfield

総合スコア14

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

0グッド

0クリップ

投稿2016/05/10 05:40

編集2022/01/12 10:55

Excelでシートを切り替えた時に、表示位置が切替前シートと同じになるようにしたいです。
動作的には以下のコードで思い通りになったのですが、ちらつきがひどいです。
どうすればよいでしょうか。

'シートがアクティブになったとき Private Sub Workbook_SheetActivate(ByVal Sh As Object) '描画・イベント制限 Application.ScreenUpdating = False Application.EnableEvents = False '切替前シートのスクロール位置に移動 Application.Goto Sh.Cells(sBar_row, sBar_col), True '描画・イベント制限解除 Application.EnableEvents = True Application.ScreenUpdating = True End Sub 'シートが非アクティブになったとき Private Sub Workbook_SheetDeactivate(ByVal Sh As Object) '描画・イベント制限 Application.ScreenUpdating = False Application.EnableEvents = False '切替前シートをアクティブにする Worksheets(Sh.Name).Activate 'スクロール位置を取得 sBar_row = ActiveWindow.ScrollRow sBar_col = ActiveWindow.ScrollColumn '描画・イベント制限解除 Application.EnableEvents = True Application.ScreenUpdating = True End Sub

Workbook_SheetDeactivateの時点でシートは既に切り替わっていて、切替前画面をアクティブにしなければScrollRow、ScrollColumnは取得できず、ScreenUpdatingをFalseにしてもActivateでの画面切替は制御出来ていないようです。

使用用途は複数のExcelファイルをシート別に読み込み、差分を色分けして分かるようにする機能を作ったので、シートを切り替えた時にページ移動しなくて済むようにしたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

一応、以下の方法でアクティブシートを一瞬変更することによるチラツキをなくすことはできると思います。

VBA

1'Workbook_SheetActivateは不要 2Private Sub Workbook_SheetDeactivate(ByVal Sh As Object) 3 'イベント/描画の停止 4 Application.ScreenUpdating = False 5 Application.EnableEvents = False 6 7 '切替後シート 8 Dim newSheet As Worksheet 9 Set newSheet = ActiveSheet 10 '切替前シート 11 Dim oldSheet As Worksheet 12 Set oldSheet = Worksheets(Sh.Name) 13 14 '切替前シートからスクロール位置取得 15 oldSheet.Activate 16 sBar_row = ActiveWindow.ScrollRow 17 sBar_col = ActiveWindow.ScrollColumn 18 19 '切替後シートでスクロール位置移動 20 newSheet.Activate 21 Application.Goto newSheet.Cells(sBar_row, sBar_col), True 22 23 'イベント/描画の再開 24 Application.EnableEvents = True 25 Application.ScreenUpdating = True 26End Sub

ただ、これでもシートを切り替えた時点で(VBAでの制御外で)切替後シートをもともとの表示位置で描画してしまうので、その位置から切替元シートの位置に移動する再描画(チラツキ)は発生してしまいます。


≪追記≫
変更後シートが画面描画された後にSheetActivateイベントが発生するので、このイベントを使う限りは避けられないですよね。
Excelに画面スクロールイベントがあれば別の提案もできるのですが、それもないのでやはりなかなか難しいようです。

他の方法というと、あとはタイマーで監視して定期的にスクロール位置を保存するという方法くらいしか思い当たりません。

標準モジュールを作成し、以下を実装することでタイマー発生時のスクロール位置を全シートに反映することができます。
Workbook_OpenなどでSetTimerを呼び出してあげれば起動時からタイマーが開始されると思います。

VBA

1'標準モジュールに実装 2Private sBar_row As Long 3Private sBar_col As Long 4 5Public Sub SetTimer() 6 '開始時間(例えば現在時刻の2秒後) 7 tTimeSpan = Now + TimeValue("00:00:02") 8 'プロシージャが実行中の場合の待ち時間(1秒後に再実行) 9 tResumeWait = TimeValue("00:00:01") 10 'タイマーセット 11 Application.OnTime TimeValue(tTimeSpan), "SetScroll", TimeValue(tResumeWait) 12End Sub 13 14Private Sub SetScroll() 15 'イベント/描画の停止 16 Application.ScreenUpdating = False 17 Application.EnableEvents = False 18 19 Dim nowSheet As Worksheet 20 Set nowSheet = ActiveSheet 21 22 sBar_row = ActiveWindow.ScrollRow 23 sBar_col = ActiveWindow.ScrollColumn 24 25 For Each sht In ThisWorkbook.Sheets 26 '現在のスクロール位置をアクティブシート以外に適用 27 If sht.Name <> ActiveSheet.Name Then 28 'シート選択 29 sht.Activate 30 31 '各シートのセル選択状態を保存 32 Dim ac As Range 33 Set ac = Application.Selection 34 35 'スクロール移動 36 Application.Goto sht.Cells(sBar_row, sBar_col), True 37 38 'セル選択状態を復元 39 ac.Select 40 End If 41 Next 42 43 nowSheet.Activate 44 45 'イベント/描画の再開 46 Application.EnableEvents = True 47 Application.ScreenUpdating = True 48 49 '次回タイマーをセット 50 Call SetTimer 51 52End Sub

やはり個人的にはタイマーで常時監視というのは負荷が高そうで抵抗がありますが。。
参考までに。

投稿2016/05/10 06:51

編集2016/05/11 03:08
jawa

総合スコア3013

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

forestfield

2016/05/10 07:23

回答ありがとうございます。 確かにちらつきが少し収まりました。 しかし差分を色分けしている仕様上これでもまだシートの切り替わりが目立ってしまいます。 もはやVBAの制御外との事なのでどうしようも無いのでしょうか。。。
jawa

2016/05/11 03:09

一応、参考までに代案追記させていただきました。
guest

0

Open時に現在のシートの位置を記録 => 動かすたびに記録 => activateするたびに記録

で、すべての位置を把握していくのはいかがでしょうか。

もしくは、Activateにしなくてもシートにアクセスは出来るはずですが、それだと取れないでしょうか。

投稿2016/05/10 06:22

編集2016/05/10 06:26
sokha

総合スコア216

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

forestfield

2016/05/10 07:16

回答ありがとうございます。 質問文に使用用途を追記しましたが、シートの編集・クリックする事は恐らく少なくて、横にも縦にも長い表なのでカーソル移動も少ないかもしれません。 主な操作はスクロールバーでの移動とシート切替になると思います。 ですので「動かすたびに記録」が難しいと思います。 「activateするたびに記録」で対応したいのですが、うまい事ちらつきに対応出来ていない状態です。 「Activateにしなくてもシートにアクセスは出来る」 こちらはWorksheetオブジェクトの事だと思うのですが、ScrollRow・ScrollColumnはWindowオブジェクトのメンバのようでWorksheetオブジェクトは持っていませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問