別のブックでユーザーフォームを起動する

作成元以外のブックでユーザーフォームを起動する方法について

Dim WithEvents Bkob As Workbook

Sub SetBook()
If Bkob Is Nothing Then
Set Bkob = zzzワークシート取得("テストシート").Parent
Else
Set Bkob = Nothing
End If
End Sub

Private Sub Bkob_Activate()
UserForm1.Show
End Sub

Private Sub Bkob_BeforeClose(Cancel As Boolean)
Unload UserForm1
Set Bkob = Nothing
End Sub

このコードは、ユーザーフォームを作成・保存しているブックのThisWorkbookモジュールの最上部にコピペしてください
※WithEventsは標準モジュールでは利用できません(エラーが発生します)

また、このコード中にzzzワークシート取得という関数を使用しています
これは開かれているブック全てのシートから引数に指定された文字列に完全一致するシートを取得する関数です
以下の記事にて公開・解説していますので、併せてそちらも確認・コピペしてください
コピペ先は本記事コードに連続して入力してもらって問題ありません

コードのコピーペーストの例
コードのコピーペーストの例

この画像のような感じで、連続してコピペしてもらって大丈夫です
もちろん関数の方だけ、標準モジュールに記載しても構いません
同じブック(プロジェクト)内であれば、どこでもOKです

使用場面

ユーザーフォームは作成したブックに依存しています
ユーザーフォームを開いた状態で、ブックを最小化するとフォームも一緒に最小化されます
また、別のブックをアクティブ状態にしたときはそのアクティブブックより背面に表示されます

ユーザーフォームを作成したブックではなく、別のブックで利用したい場面では通常の起動の仕方では出来ません

ブックのマクロの保存状態の確認
マクロの保存状態

この画像の様に、「TestBook.xlsx」にはマクロは保存されていません
そもそもマクロが有効なファイル形式ではありません
このブックに対してユーザーフォームを依存させたい訳です
そのユーザーフォームは「Wordpress.xlsm」に作成されています

よくある方法で、ブック自体を非表示にしてフォームだけを表示させる方法がありますが、この方法はExcel自体を非表示にすることで実現されます
この場合、表示処理を行う前に処理が強制終了した場合にExcelがバックグラウンドのプロセスに残ったままになってしまいます
かといって最小化をしてもフォームも引っ張られて、一緒に非表示になります
また、ウィンドウの位置をディスプレイ画面の外側に移動させたりする方法もありますが、これも上記同様で元に戻すコードの実行が必須になります

なによりこれらすべてに共通するのが、別のブックをアクティブにした時点でフォームは背面表示となり、なんの意味もなくなってしまう点です
この場合にはWinAPIによる画面の表示順の調整が必要になります
これは現在ではBit依存による対応が必要である点とMsgBox関数等のメッセージの前に表示されていた場合は操作不能のような状態になってしまいます

そこで利用するのが、例コードの流れになります
まずWithEventsを利用して、別のブックを取得させます
そのブックのActivateイベントでフォームのShowメソッドを実行します

こうすることにより、ユーザーフォームの依存先を処理作成のブック以外のブックにすることができます
処理自体は処理ブックに保存されていますが、実際にフォームを起動して処理を行うブックが別で指定できます

依存先が対象のブックになっているので、そのブックの最小化やアクティブ状態を共有することが出来ます

コード解説

この方法はWithEventsを理解することが必要ですので、理解できていない場合は以下の記事を確認してください

Dim WithEvents Bkob As Workbook

モジュールレベルの変数宣言を行っています
ここでWithEventsを利用することで、このオブジェクトにイベント処理を作成することが出来るようになります

通常WithEventsを利用する場合はクラスを使用しますが、このコードの様に代入する対象が1つと確定している場合は特に必要ありません
ただ標準モジュールには記載することが出来ないので、ユーザーフォームやThisWorkbookなどのオブジェクトモジュール内に作成します

この1行により、後続のイベント処理が有効になります

Sub SetBook()
If Bkob Is Nothing Then
Set Bkob = zzzワークシート取得("テストシート").Parent
Else
Set Bkob = Nothing
End If
End Sub

このプロシージャは、宣言した変数への代入と解放を行う処理です
オブジェクトが取得済みかどうかで分岐処理を行っています

単純に、取得されていれば解放して、取得されていなければ取得を行うものです
この取得処理を行う際に、別ブックのシートを指定することで処理ブック以外をこの変数に代入させることが出来ます

なお、取得関数に関しては記事に解説がありますのでここでは割愛します
この関数はWorksheetを返す関数で、取得を行いたいのはブックなので、Parentプロパティを使用して返されたWorksheetを含むブックを取得しています

このプロシージャをボタン等によりユーザーのタイミングで実行できるようにします
と、いうのもこの処理では対象のブックが存在する必要があります
ですが、イベント等の自動化を行ってしまうと、その取得のタイミングで対象ブックを開いていない可能性があるからです

Private Sub Bkob_Activate()
UserForm1.Show
End Sub

作成した変数のActivateイベント処理です
ここで指定のフォームを起動しています

Activateイベントなので、別のブックからこのブックへフォーカスが移動してきたときに発生することになります
このことからも処理用ブックで一度ボタン等の処理実行を行うことで、自然な流れで対象ブックでフォームを起動することが出来ます

また、ここでは割愛していますが、Showメソッドがアクティブになるたびに実行されると、表示位置が初期状態の場所に移動します
入力内容が失われることは無いので、気にしなければ大したことではないのですが、表示位置がリセットされることが気になる場合は、ここの処理でフォームが起動されているかの判定処理を入れておけばいいです
判定処理に関しては以下の記事を確認してください

Private Sub Bkob_BeforeClose(Cancel As Boolean)
Unload UserForm1
Set Bkob = Nothing
End Sub

作成した変数のBeforeCloseイベントです
ブックが閉じられる前に発生するイベントですが、この対象ブックが閉じられるということはフォーム表示処理が不要になることになるので、ここでフォームの終了と変数の解放を行っています

変数の解放は、処理用ブックでも行っているので2Way仕様ということになります
この解放は、処理用ブックの変数であるため、対象ブックを終了しても自動的に解放されることはありません
必ず明示的に解放を行っておきましょう

あと、当然ですが処理用ブックを閉じた場合はフォームも強制終了して処理の実行も不能になります
処理の仕様上あまり注意が必要とは思いませんが、間違って終了してしまわないように組み上げてください

使用するメリット

マクロ処理を作成していないブックに対して、自由に処理をユーザーが任意のタイミングで実行できることが最大のメリットだと思います

例えば同じフォーマットのブックに全てにフォーム処理を作成するのではなく、処理用ブックを1つ作成してそれを開いてから作業ブックを開くようにすればメンテナンス性も大きく向上します

また、作業用ブックにはマクロを保存する必要が無くなるのでマクロ無効の通常ブックとして扱うことが出来ます
場合によってはマクロを保存してはいけないブックも会社規定により存在するかもしれません
そんな場合でも、ユーザーフォームを利用した処理が利用できます

さらに、フォーム等の処理のメンテナンスを行った際に作業用ブックを上書きする必要が無いため、データの上書きを気にする必要もなくなります
そもそも処理用ブックにはデータが存在しないからです

今回の例では特定のブックに対しての依存先変更でしたが、WithEventsの変数をシート型にして特定のシートでのみ起動されるフォームとすることも可能です

Excel間でのフォームの表示問題なら、この方法で対応可能です
別のアプリ間での表示問題になると、やはりWinAPIを利用するしかなくなりますが、それはまた別の話になります

ユーザーフォームの依存先の変更は、比較的応用の幅が広いと思います
マウスホイールが利用できない等、使い勝手が少し時代遅れになってきたユーザーフォームですが、まだまだ使える場面が多いですね

最後に実際にこれらの処理を組み込んだ場合の動きの動画になります
コード解説が行われているわけでは無いので、参考程度に確認してください

コードを適用したときの実際の動きの動画です

ユーザーフォームの起動確認

ユーザーフォームの起動(読み込み)状態を確認する方法

If UserForms.Count <> 0 Then
'読み込みされたフォームの1番目のCaptionプロパティを取得
Debug.Print UserForms(0).Caption
Else: End If

ユーザーフォームの起動確認には、UserFormsコレクションを利用します
このコレクションは読み込みが実行されているユーザーフォームのコレクションになります
読み込みとはメモリ上に読み込みをされた状態なので、Showメソッドだけではなく、Loadメソッドが実行されて読み込まれた時点でコレクションに収まります

よくある起動確認でVisibleプロパティを利用することがありますが、これはあくまでも表示状態を表すプロパティですので、起動確認の目的では少しイメージが違います
なにより、ユーザーフォームのプロパティを取得しようとすると読み込みが実行されてしまいます
プロパティを取得したかっただけなのにInitializeイベントが実行され、処理を作成していた場合は実行されます
意図しないタイミングでフォームが読み込みを行う形になってしまいます

この状態でShowメソッドを実行しても、非表示状態から表示されただけの動きになってしまうので、非常に注意が必要です

そのため、フォームの起動確認にはUserFormsコレクションを利用してください
上記にあるようにこのコレクションは読み込みが実行されたものだけを対象としているので、Showメソッド含めて読み込みされていないフォーム判定が可能です

もちろん対象フォームのプロパティを取得するわけではないので、勝手に読み込みされることもありません

基本的に例コードの様にCountプロパティを利用する場面が多くなると思います
複数のフォームを同時起動して、かつその中でどのフォームだけの起動確認を行う場合は結構特殊な場面と思います

ほとんどは1つのフォームの起動確認を行う場合が多いです

コード解説

If UserForms.Count <> 0 Then

~~中略~~

Else: End If

IF文により判定を行います
Countプロパティは読み込まれたユーザーフォームの個数を返します
なのでこのプロパティが1以上を返せば、何らかのユーザーフォームが読み込まれていることが確認できます

上記にもあるように、ほとんどの場合は1つのユーザーフォームの起動確認を行う場面が多いので、このインデックス番号のフォームのプロパティを取得して判定を深堀りする必要は無いでしょう

'読み込みされたフォームの1番目のCaptionプロパティを取得
Debug.Print UserForms(0).Caption

取得が必要な場合は、ユーザーフォームの各プロパティをそのまま利用できます
インデックス番号は0から始まるので、0は確定で存在します
またCaptionプロパティや前述のVisibleプロパティも取得を行えます

実際の使用について

フォームを起動せずにコードを実行したときの動き
フォームを起動していない場合

この画像の動きはフォームを起動せずに実行した場合の動きになります
読み込みを実行していないため、Countプロパティが返す値は0となるためElseの処理が実行されます
今回は何も処理が無いので、何も起こりません

フォームを起動した状態でコードを実行したときの動き
フォームを起動した状態の場合

次にフォームを起動した状態でコードを実行しています
この状態であればCountプロパティは1を返すので、イミディエイトウィンドウに読み込みされたユーザーフォームの1番目(インデックス番号0)の表示文字列が出力されます

1つのユーザーフォームの起動確認を前提とすれば、Countプロパティが0か1かを判断すれば十分です

0なら起動されていない、1なら読み込みが実行されている
1で起動しているならVisibleプロパティで表示状態を確認しても良いでしょう
すでに読み込みされているので、プロパティを取得しても問題はありません

あとはこのIF分岐によって処理を組み込めば良いだけになります

主にこの判定処理に関しては、ユーザーフォームを自動的に起動・終了をさせるイベントや処理中にイベントの発生を容認する必要があるけど起動・終了イベントに影響が出てしまう等々の場合にユーザーフォームが起動されていれば、不要な処理は記事コードによって行わないようにする
そんな場合に使用します

最も多い場面が、自動終了させたい場合かもしれません
ExcelVBAの仕様で、Unloadステートメントを実行した場合に対象のユーザーフォームがそもそも読み込みをされていない場合Unloadという目的を達成するために、一度わざわざ読み込みを実行してからUnloadを行います

起動処理や終了処理が無い場合や、処理時間が一瞬なら大して問題は無いのですが、そうでない場合はユーザーにとっては非常に煩わしいです
注意が必要な運用方法です

埋め込みコントロール(ActiveX)の作成

ワークシートに直接コントロールを作成する方法の解説

ActiveXコントロールとは、ユーザーフォームで扱うコントロールの事です

ここでは、そのコントロールをフォーム上ではなくワークシート上に作成する方法の解説を行います

ワークシートにコントロールを埋め込む

ワークシートにコントロールを作成する利点は、ワークシート自体を有効利用できる点にあります

例えば、フォームをブックを開くと同時に表示するような処理であった場合、シートに作成しておけばそもそもそんな処理を作成する必要はありません
さらに、特定のシートのみで動作させたいフォーム処理であっても、シートの判定がまったく必要なくなります

さらに、リストコントロールを使用しなくてもそこにワークシートがあるのでデータの展開も楽になります
あと地味に大きいのがマウスホイールで画面を移動できる点です

ユーザーフォームを必要としないように作成を行うことも可能になります

コントロールの作成方法

埋め込みコントロールの挿入ボタンの位置
コントロールの挿入ボタン

まずは、開発タブにある挿入ボタンを選択します

ここからコントロールを選択して追加していきます

表示された挿入できるコントロール一覧
挿入できるコントロール一覧

赤枠内に表示されたアイコン一覧が挿入できるコントロールになります
ユーザーフォームでの作業同様に、一覧にないコントロールは追加可能ですがPC環境に左右されるので、基本のコントロールのみで作成していきます

フォームコントロールについては後述します

今回はコマンドボタンを作成してみます

コントロールの作成方法
作成方法

作成するコントロールを選んだら、ワークシートに挿入します

この時の操作は図形作成要領と同じなので、難しくは無いはずです
大きさや位置は後で調整できるので適当にクリックするだけでもいいです

編集モードの終了方法
編集モードの解除

コントロールの追加モードになると、自動的にデザインモードという編集モードに切り替わります

この状態では、コマンドボタンをクリックしても選択されるだけです
挿入ボタンの隣にあるデザインモードボタンをクリックすることで編集モードを切り替えることが出来ます

デザインモードを解除すれば、コントロールを操作可能な状態になります
コマンドボタンをクリックすると、動作するようになっているはずです

ただ、このままでは何も起きませんので処理を作成します

コードやプロパティの表示方法
コード作成方法

コントロールを編集する場合は、デザインモードをクリックして有効にします

その状態で、コントロールの右クリックメニューを開きます
その中にある赤枠内のコードの表示を選択してください

作成されたイベントとプロパティの表示状態
作成された状態

すると、VBEの画面に切り替わりコントロールの既定イベントが作成されます

また、その際にプロパティウィンドウに表示されているのが、作成したコントロールのプロパティです
ここを変更すれば、作成したコントロールの細かい設定変更が可能です
プロパティ設定はユーザーフォームのものとほぼ同じなので、そちらを参考にしてください

また、このイベントプロシージャはユーザーフォームではユーザーフォームモジュール内に作成していました
これはシートのコントロールのイベントになりますので、シートモジュール内に作成されることになります

それ以外はユーザーフォームでの作成方法と同じです
オブジェクトボックスから選んで、プロシージャボックスからイベントを選択する流れになります

ワークシート上にコントロールを作成した時点で、オブジェクトボックスで選択可能になりますので、上記のような右クリックメニューから実行しなくてもVBEの画面から作成することも可能です

フォームコントロールとActiveXコントロールについて

ちなみに、ActiveXコントロールの上に「フォームコントロール」というコントロールがあり挿入できる種類も同じものがあります

こちらは、簡易版と思ってもらっていいです
簡易版なので、作成してセルとの連携を簡単に設定できます
スクロールバーの数値設定なども書式設定から行えるので手軽に作成できます

ただ、簡易版ですので設定が簡単な分出来ることは少なくなっています
色の変更なども行えませんし、なによりイベントの利用が出来ません
コントロールの最大利点のイベントが利用できず、マクロ登録による単一マクロしか対応できませんのであえて使う理由がほぼありません
比較的すぐに限界を感じると思います

それに、ActiveXコントロールはユーザーフォームと同じように作成できるので、慣れやすいのも優位性があると思います

Zoomプロパティ

Zoomプロパティは、各コントロールの表示倍率の設定です。使用時の注意点も

'100%表示にする
UserForm1.Zoom = 100

「Zoom」プロパティは、フォーム内の表示倍率の設定です
初期値は100になっています
これは%表示と考えてもらっていいです

設定できる範囲が「10~400」の間に決まっています
元々の10分の1から4倍の大きさにまで、拡大縮小が出来るようになっています

Zoomが100の時の表示
初期値100の表示状態
Zoomが50の時の表示
50に設定した表示状態
Zoomが200の時の表示
200に設定した表示状態

以上の画像の様に、同じフォームの同じサイズのコントロールでも大きな違いが生まれます
なにより、見やすさを向上させるためのプロパティと思ってください

表示の乱れについて

このプロパティの難点が文字列がコントロールの表示領域からはみ出してしまうことがあることです

Zoomの数値によって文字列がはみ出している
labelの文字列がはみ出している状態

画像を確認してください、これは元は上記の画像と同じものです
赤枠内のlabelコントロールの表示文字列の最後の「n」がはみ出して消えてしまっています
これはコントロールのサイズの単位と文字列のサイズの単位が違うため、Zoomプロパティの数値を1ずつ動かしていくと必ずどこかで発生します
文字サイズが影響するため、文字の種類によっても差があります

なので、自動調整で文字列がはみ出す場合はいかんともしがたいです

このプロパティを主に使用するのは、フォームのサイズ調整に合わせて、各コントロールの表示も整える場合に使用します
フォームの自動サイズ調整については以下の記事で解説しています

解説にもありますが、いかんせん表示が乱れることがあるのが困っちゃう
困っちゃうのであんまり普段は使わんですねぇ

Tagプロパティ

Tagプロパティは追加情報を設定するプロパティです。設定するコード

'フォームの追加情報の設定
UserForm1.Tag = "追加情報"

「Tag」プロパティは追加情報を設定できます

これ自体は、設定してもなんの意味もないプロパティです
なんの意味もないということは、他に影響を与えないと言い換えれます

これはそのプロパティ値で、処理を行う為に使用します

タグという名前の通り、なんらかの判定に使用します
例えば、このプロパティに「グループA」という文字列を入力しておいて、そのグループごとに処理を実行するようなことを行えます

また、処理中の一時的なデータの保持にも使用できます
加工前の文字列をプロパティに代入しておき、加工後の文字列を出力後、Tagプロパティから加工前の文字列を取得する、というようなことも出来ます

使用方法は多岐にわたりますので、いろいろな使用方法を考えてみてください

StartUpPositionプロパティ

StartUpPositionプロパティでフォームの初期表示位置を設定できます

「StartUpPosition」プロパティは、UserFormが表示される初期位置の設定です
基本的には初期表示位置なのでデザインウィンドウで設定します

「0 – 手動」は、初期位置を設定しません。この場合LeftプロパティとTopプロパティの設定値により表示位置が調整されますそれらのプロパティを使用して任意の位置に表示するにはこの設定にしておく必要があります

「1 – オーナーフォームの中央」は、Excelのウィンドウの中央に表示されます。Excelの位置によって表示位置が変更されます。マルチディスプレイで表示する場合に便利な設定です

「2 – 画面の中央」は、そのままの意味で画面の中央に表示します

「3 – Windows の既定値」は、画面の左上にぴったりくっついた場所に表示されます。Leftプロパティなどで位置調整を行っていない「手動」と同じ場所に表示されますので、あまり使いません
また、Leftプロパティなどを設定していても左上の表示位置は変わりません

フォームの初期表示位置設定の位置図
フォームの初期表示位置図

この画像が、各設定で表示される場所です
ピンクがフォームで、設定により場所が変わります

緑色がExcelのウィンドウです、UserFormのオーナーは基本Excelなのでその中央になるので、Excelの位置によって変化します

グレーが画面全体のウィンドウです、その中央に画面の中央に設定したフォームです
初期設定では、この位置設定になっています

コードで変更する場合

Private Sub UserForm_Initialize()

'フォームの初期表示を手動で表示する
Me.StartUpPosition = 0

End Sub

上記のコードを使用すれば、表示位置を変更して表示させられます
ですが上記にもあるように、初期表示位置なのであまり動的に変更する場面が少ないと思いますのでここで解説します

このプロパティは、初期表示位置なので表示されてから設定を変更しても意味はありませんので、表示前に設定を変更する必要があります

なので、メモリ上に読み込まれて表示前に発生するInitializeイベントに記載します

またリファレンスにもあるような、メモリ上に読み込みをしてプロパティを変更してから表示させる方法もあります

ただ、このコードの注意点として手動とWindowsの既定値の設定が切り替わりません
自分の環境のExcel2010でしか試していませんが、デザイン画面で手動にして、コードでWindowsの既定値の設定にしても手動のままです
逆も同様でした、それ以外の設定には切り替わります

まあ、使用場面の少なさからあまり影響は無いと思いますが・・・

画面の表示位置について

画面の表示位置とは、案外重要な要素です

入力補助などのフォームで、フォームの起動を繰り返すような場合に毎回表示位置をタイトルバーをドラッグして移動させるのは面倒です
特にマルチディスプレイを使用している場合に、毎回メインからサブへ移動させるというような動きは非常に面倒です

なので、最終的に完成したときにはこのプロパティから表示位置を調整するようにします

なお、表示位置を保存して前回と同じ場所に表示する処理は以下の記事で解説しています

ShowModalプロパティ

ShowModalプロパティは、フォーム表示中にExcelや別のフォームの操作を可能にするかを設定します

「ShowModal」プロパティはUserFormを表示している間に、UserForm以外の操作を可能にするかを設定できます
処理中に変更することはできませんので、コードはありません

Trueに設定すると、他の操作は不可となります
Falseに設定すると、他の操作が可能となります

この設定は、UserForm単体で処理を実行する場合以外に使用します
入力補助などでもワークシート操作を可能にしたり、複数のUserFormを同時に使用する場合に使用します
Trueに設定している場合は、フォームを終了するか非表示状態にすることで他の操作を可能な状態に戻すことが出来ます

なお、Excelの操作は出来ませんがVBEの操作は可能です

上記にもあるように、この設定はデザインウィンドウで行います
処理の途中で変化させることはできません
Showメソッドを実行する際に、引数に「vbModeless」を指定することでプロパティのFalseと同じ設定にして起動することが可能です

その際の処理の動きに注意点がありますので、以下の記事で解説しています

ScrollTop・ScrollLeftプロパティ

ScrollTop・ScrollLeftプロパティはスクロール移動値の設定です、これを使えばフォーム内移動が行えます

'高さの表示位置の変更
Me.ScrollTop = 50
'横の表示位置を変更
Me.ScrollLeft = 50

「ScrollTop」プロパティはスクロールの高さ位置の設定
「ScrollLeft」プロパティはスクロールの横位置の設定

これら2つのプロパティは、スクロール位置の調整数値です
「0」というのが、スクロールしていない状態になるので、最左上の位置になります
ここからスクロールの動いた分が、これらのプロパティ設定になります

初期値で数値を指定しておけば、広大なフォームだったとしても初期表示位置を指定できます
なお、このプロパティはデザイン画面でスクロールバーを動かした時点で自動的に数値が入力されるので、この画面で調整する場合は数値の入力は必要ありません

ある程度の広さを持ったフォームを作ってしまうと、どこに何があるか分かりにくくスクロールして目的のコントロールを探すことになります
そんなときに、ボタンなどでこのプロパティで位置調整を行えば利便性が上がります

'Frame1を左上に移動
Me.ScrollTop = Frame1.Top
Me.ScrollLeft = Frame1.Left

このコードを実行すると、フォームにあるFrame1コントロールの左上を表示領域の左上に合わせます
ただ、この数値と実際のフォームサイズの差が範囲内でなければ移動しきれず中途半端な位置になります

ようは、Webページでもよくあるページ内リンクと同じような役割を持たせられます
このサイトではトップページにそのページ内リンクがあります

どうしても、広い領域のフォームが必要になった場合は、こういったプロパティを活用してユーザーが迷子にならないようにフォームを作成しましょう

ScrollHeight・ScrollWidthプロパティ

ScrollHeight・ScrollWidthプロパティはフォームのサイズを超える領域の高さと横幅の設定です

'フォームの表示領域の高さを増やす
Me.ScrollHeight = Me.Height + 50
'フォームの表示領域の横幅を増やす
Me.ScrollWidth = Me.Width + 50

「ScrollHeight」プロパティはフォームの表示領域の高さの設定
「ScrollWidth」プロパティはフォームの表示領域の横幅の設定

これら2つの数値をフォームのサイズより大きな数値に設定することで、スクロールにより作成したフォームのサイズ以上の表示領域を扱うことが出来るようになります

なお、この設定を行っても表示領域自体は拡張されますが、スクロールバーは表示されません
スクロールバーの表示設定も合わせて行っておきます
(表示設定の記事はこちらから)

これらのプロパティをフォームサイズを超える数値にすることで、画面に収まりきらないコントロールを配置することが出来ます

基本的にはデザイン画面のプロパティウィンドウで設定を行います
デザイン画面で設定すれば、その画面でスクロールさせて実際の動きを確認できるのでこちらで行ってください

コード中に設定するには、例コードのように数値を設定する形になります

表示外という領域を作成する注意点

この表示領域の拡大に関しては初期表示ではどこに何があるかわからない状態です
この状態ではユーザーにとっては少しわかりづらいフォームになってしまうので、このプロパティを使用する場合は、デザインを特に意識してください

画面スクロールすることで、他のコントロールがあることや目的のコントロールがどの位置にあるかを分かり易くするデザインは工夫が必要です

そして、VBAの弱点の1つでもありますが、マウスのホイールは使用できません
なので、マウス操作になれていればスクロールバーの上でホイールで移動させようとするのは無意識の操作です

これが行えないので、少し使っている人にはわずらわしく感じる可能性がありますので正直あまり多用しないほうがユーザーにはやさしいかなと思います

ScrollBarsプロパティ

ScrollBarsプロパティはスクロールバーの表示設定を行います。各表示設定のコード

'フォームに縦横のスクロールバーを表示
Me.ScrollBars = fmScrollBarsBoth
'フォームに横のスクロールバーを表示
Me.ScrollBars = fmScrollBarsHorizontal
'フォームに縦のスクロールバーを表示
Me.ScrollBars = fmScrollBarsVertical
'フォームのスクロールバーを非表示
Me.ScrollBars = fmScrollBarsNone

「ScrollBars」プロパティは、コントロールの領域を移動させるスクロールバーを表示するかの設定です

スクロールバーの表示設定の動き
スクロールバーの表示を変更

UserFormとFrame・MultiPageコントロールが指定可能です

このプロパティはあくまでも表示の設定になりますので、範囲外の有無には関係ありませんが、範囲外があってもこのプロパティで表示設定を行っておかないと、その範囲外を移動することが出来ません

このプロパティは、KeepScrollBarsVisibleプロパティも表示する設定になっておかないと表示されません
(KeepScrollBarsVisibleプロパティの記事はこちら)

範囲外がどれだけあるかによって、この設定は変更してください
面倒であれば、「fmScrollBarsBoth」(縦横表示)の設定で構いません
範囲外が無かったとすると、移動のスクロールが出来ないのでそれはそれで範囲外が無いことをユーザーに知らせることが出来ますので

TextBoxとRefEditコントロールについて

TextBox・RefEditコントロールにもこのプロパティが存在します

このプロパティを表示設定にしても、この2つのコントロールはスクロールバーが表示されません

この2つは入力内容がはみ出た時に初めて表示されるためです
なので、この2つにはKeepScrollBarsVisibleプロパティが存在しません
入力内容による自動判定になります

横のスクロールバーの場合は、文字列がコントロールの横幅を超えてはみ出すと表示されます
この際WordWrapプロパティがFalseになっていなければ表示されません
このプロパティで折り返しの表示がされると、横にはみ出すことがなくなるからです

縦のスクロールバーが改行を行うことで表示されます
なので、MultiLineプロパティをTrueに設定しておく必要があります
このプロパティでコントロール内で改行が有効になるためです

上記のことから、この2つのコントロールでのプロパティ設定は動的な判断になりやすいので3つのプロパティを駆使して、作成を行ってください