ブックやシートの選択を含めてセル選択をする

Application.Goto メソッドを使うと、セルの選択と同時にブックやシートも自動で切り替わり、複数の場所への移動処理をまとめて実行できます。

'「Book1」の「Sheet1」の A2 セルを選択する
Application.Goto Workbooks("Book1").Worksheets("Sheet1").Range("A2")

ブックやシートの選択をセルの選択と同時に行うには、Application.Goto メソッドを使用します。
このメソッドでは、セルを指定すると 同時にブックやシートもアクティブ化されます

Range オブジェクトの Select メソッドでもセル選択は可能です。
しかし、アクティブではないブックやシートのセルを指定するとエラーが発生します

メソッドの書式

引数(太字は必須引数)
Goto Reference, Scroll

Referenceには移動先のセルを指定します。
ブックやシートも合わせて指定することで、その範囲までを同時にアクティブにできます。
また、この引数を省略した場合は、メソッド実行時点でのセル範囲が自動的に指定されます。
この動作については、以下の記事で詳しく解説しています。

Scroll は、移動先のセルの表示に関する設定です。
この引数に True を指定すると、セル範囲の左上を表示範囲の左上に合わせます
省略した場合は False が指定されるため、移動先が画面内にある場合は画面がスクロールしません。

コード解説

Application.Goto Workbooks("Book1").Worksheets("Sheet1").Range("A2")

このコードは、別のブックにある特定シートのセルを選択するためのものです。
例では、Book1 の Sheet1 にある A2 セルをアクティブにしています。

ブック間のセル選択の移動
別のブックのシートのセルへ移動する

画像の動きを確認してください。
特にシートタブの部分に注目してみてください。

シートタブの見出しが変わっているのが分かると思います。
ここから、アクティブブックが別のブックへ切り替わったことが確認できます。
その後、A2 セルが選択状態になっていることが分かります。

Application.Goto Worksheets("Sheet1").Range("A2")

このように、ブックを指定せずにシートを指定すれば、アクティブブック内でシート間の移動が可能です。
さらに、シートの指定も行わず Range のみを指定した場合は、アクティブシートのセルを選択します。

Application.Goto Range("B3"), True

2つ目の引数である Scroll に True を設定したコードです。
シートの指定をしていないため、アクティブシート上のセルが選択されます。

指定セルを左上に合わせて表示する

画像の動きを確認してください。
A1 セルから B3 セルへ選択が移動しています。

ウィンドウ上ではセルがスクロールしていないため、パッと見では分かりにくいのですが、B3 セルが画面左上に表示されています。

表を作成した後、その表を画面内にきれいに収めて表示したい場合などに便利です。
ただし、通常の処理ではウィンドウ上の動きが分かりにくいため、使用する機会はあまり多くないかもしれません。

表示位置を指定セルに移動する

選択セルを変えずに画面だけ移動したいときに便利なShowメソッドの使い方と注意点

'A10000セルを画面内にスクロール表示
Range("A10000").Show

処理の終了時に、特定のセル位置を画面内に表示しておきたい場面があります。
そんなときに便利なのが 「Show」メソッド です。

このメソッドを使うと、指定したセルがウィンドウ内に収まるように自動でスクロールされます。
ただし、セル自体は選択状態にはならない点に注意が必要です。

「選択セルはそのままにしておきたいけれど、画面だけ移動させたい」というケースで特に有効です。
一方で、画面内のどの位置に表示するかまでは指定できないという制約があります。
また、指定セルがすでに画面内にある場合はスクロールが発生しないため、その点も押さえておきましょう。

コードの動き

メソッドの動きの確認
コード実行時の動き

実際にコードを実行してみると、動作のイメージがよりつかみやすくなります。
画像の動きを確認してください。
A10000セルを表示状態にすると、画面がスクロールされてセルが中央付近に表示されます。
その際、選択セルはA1のままで、選択範囲が移動していないことも確認できます。

また、このメソッドを使用する際の大きな注意点として、画面更新を抑止している場合は無効になることが挙げられます。
画面更新を抑止した状態でA1セルを対象に実行しても画面は変化しません。
抑止を解除してから再度実行すると、正常に画面がスクロールされます。

処理後に画面を移動させたいケースは多いため、通常は大きな問題にはなりませんが、画面更新を抑止する処理を組み込んでいる場合は、解除してから実行するように注意してください。

ただし、前述のとおり「Show」メソッドでは、指定セルが画面内のどこに表示されるかを細かく制御できません。
そのため、どうしても指定セルを特定の位置に表示させたい場合はApplication.Gotoメソッドの使用をおすすめします。
このメソッドであれば左上位置に限定されますが、表示位置を指定できます。
さらに、Offsetプロパティやスクロール操作を組み合わせれば、思い通りの表示状態を作成できます。

Application.Gotoメソッドについては、以下の記事で詳しく解説しています。

環境依存文字を入力する

ChrWで環境依存文字を入力し、AscWでUnicodeコードポイントを取得する方法を解説。VBAで「?」になる原因と注意点も紹介します。

'Unicodeから文字入力
ActiveCell = ChrW(9451)
'Unicodeの文字コードを取得
Debug.Print AscW(ActiveCell.Text)

VBAで扱えない環境依存文字について

Windowsや使用しているアプリケーションの環境によっては、正しく表示・入力できない「環境依存文字」が存在します。
これらの文字は、フォントや文字コードの違いによって利用できない場合があり、VBAで扱う際にも注意が必要です。

VBAでサポートされていない環境依存文字
取得できない文字

環境依存文字は、PCやアプリケーションの環境によって表示できたりできなかったりする文字です。
たとえば、画像のように「11」を変換した際に候補として出てくる特殊な文字は、別のPCではそもそも存在しない場合があります。これが環境依存文字の典型例です。

さらに厄介なのは、VBAが認識できない環境依存文字が存在するという点です。
画像の文字をアクティブセルに入力し、その値をイミディエイトウィンドウへ出力しようとすると、実際には「?」が返されてしまいます。

これは、VBAの文字コード体系にその文字が存在しないため、正しく表現できないことが原因です。
PC上では表示できていても、VBA側では文字として扱えず、結果的に「?」へ置き換えられてしまいます。
まさに扱いづらい困った存在といえるでしょう。

そのため、ワークシートにこの文字を入力しようとして「?」を指定しても、当然ながら「?」が入力されるだけで、元の環境依存文字を再現することはできません

コード解説

そこで活用するのが、ChrW関数です。

ActiveCell = ChrW(9451)

ChrW関数は、Unicodeのコードポイントを指定して該当する文字を返す関数です。
このコードを実行すると、アクティブセルに画像で示した環境依存文字が入力されます。

VBA自体はその文字を正しく扱えないため、イミディエイトウィンドウへ出力すると「?」に置き換えられてしまいます。
しかし、ワークシートに出力する場合は問題なく文字が表示されます。

また、VBAの内部メモリ上ではUnicodeのコードポイントとして保持されているため、変数に代入して扱うことも可能です。

ただし、Unicodeが定義するコードポイントは非常に多く、すべてを掲載することは現実的ではありません。
そのため、必要な文字コードは都度調べて指定する必要があります

Debug.Print AscW(ActiveCell.Text)

AscW関数を使うと、指定した文字のUnicodeコードポイントを取得できます。
この関数は、引数に渡した文字列のうち、先頭の1文字に対応するUnicodeコードポイントを返します。

AscW関数で環境依存文字のコードを調べ、そのコードをChrW関数へ渡すことで、ワークシートへ正しく入力することが可能になります。

環境依存文字は本来あまり使用が推奨されませんが、「㈱」のように実務で便利なケースもあり、使いたくなる場面は少なくありません。

なお、Mac版ExcelのVBAはUnicodeの扱いがWindows版と異なるため、AscW関数で環境依存文字のコードを取得できない場合があります
特殊文字や外字では常に「?」として扱われることが多く、正しいコードを取得できない点に注意が必要です。

補足:ChrW / AscW が扱えない文字(サロゲートペア)について

環境依存文字とは別に、VBAでは扱えない文字として「サロゲートペア文字」があります。
これは、画像のような絵文字などのようにU+10000 以上のコードポイントを持つ文字のことです。
なお、変換候補と実際の入力結果に差が出ているのは、フォントやIMEの仕様によるもので、環境依存文字とは別の問題です。

VBAのChrW関数は0〜65535(U+FFFF)までのコードポイントしか扱えないため、サロゲートペア文字を正しく生成することはできません。
また、AscW関数で取得しようとしても、サロゲートペアの片側だけが返されるため、正しいコードポイントを取得できません。

そのため、絵文字などのサロゲートペア文字は、VBAでは基本的に扱えない点に注意が必要です。

テーブル機能で抽出したデータだけ選択状態にする

'対象のテーブルと列を指定(1つ目のテーブルの1列目)
With ActiveSheet.ListObjects(1).ListColumns(1)
    .Range.AutoFilter 1, "=002*"  '列数は1行上と同じにする:フィルタ条件(002から始まる文字列)
    .Range.SpecialCells(xlCellTypeVisible).Select  '可視セルのみの選択
    ActiveSheet.ShowAllData  'フィルタの全解除
    
    'フィルタ条件一致有無の判定(集計行がある場合は3にする)
    If Selection.Cells.Count >= 2 Then
        '選択をデータ範囲のみにする
        Intersect(.DataBodyRange, Selection).Select
        '抽出データがある場合の処理
    Else
        '抽出データがない場合の処理
        Debug.Print "抽出データなし"
    End If
End With

このコードを使用すると、テーブル機能でフィルタをかけていない状態でも、フィルタを適用した際に抽出されたデータのみを選択状態にすることができます。

さらに、抽出結果が存在するかどうかの判定も行っています。
このコード単体では「選択する」だけなので、その後に選択範囲を処理するためには、この判定が必要となります。

コード実行時の実際の動き

主な使用場面としては、テーブル内のデータのうち提出や集計に不要なデータを削除したり、必要なデータを転記したりする場合です。
フィルタをかけた状態を維持せずに、対象データだけを選択できるようになります。

この処理では仕様として、可視セル選択時に必ず見出しセルが選ばれるようになっています。(集計行がある場合は集計行セルも選択されます。)
これは、抽出条件に一致するデータが存在しない場合に可視セル選択でエラーが発生するのを避けるためです。
エラー処理を組み込むよりも、必ず選択セルが存在するようにしてエラーを回避する方が分かりやすいと考えています。
ただし、そのままではデータ範囲外のセルまで選択されてしまうため、一致するデータがある場合にはデータ範囲外のセルを選択から除外するようにしています。

コード解説

'対象のテーブルと列を指定(1つ目のテーブルの1列目)
With ActiveSheet.ListObjects(1).ListColumns(1)

・・・

End With

ここでは、アクティブシートにある1つ目のテーブルの1列目のセル範囲を With に指定しています。
これにより、見出しや集計列を含めた列全体のセル範囲を With ブロック内で使用できるようになります。

この処理の性質上、同じシートに複数のテーブルがあることは想定していませんが、対象となる列が必ずしも1列目とは限りません。
その場合は「ListColumns(1)」の数字部分を任意の列番号に変更すれば問題ありません。
また、見出し名を文字列で指定することも可能ですが、その場合は見出しが変更されないように使用者へ注意を促す必要があります。

    .Range.AutoFilter 1, "=002*" '列数は1行上と同じにする:フィルタ条件(002から始まる文字列)
    .Range.SpecialCells(xlCellTypeVisible).Select  '可視セルのみの選択

1行目では、抽出条件を指定しています。
最初の引数「1」は、フィルタを適用する列番号の指定です。処理としては、直前の行にある「ListColumns(1)」の数字と同じものを指定してください。
次の引数「”=002*”」が具体的な条件で、ここでは「002」で始まる文字列を抽出対象としています。
この部分を任意に変更することで、他の条件を設定することも可能です。
なお、条件の指定方法には、他にもさまざまなパターンがあります。

2行目では、可視セルを選択状態にしています。
抽出結果の可視セルが対象となるため、抽出条件に一致するセルとテーブル範囲の列全体が選択状態になります。

ActiveSheet.ShowAllData  'フィルタの全解除

ここでは、かけたフィルタを全て解除しています。
このコードは、フィルタがかかっていない状態で実行するとエラーになる点に注意が必要です。
ただし、処理上は「フィルタがかかっていない」という前提がないため、エラー処理を入れる必要はありません。
詳しくは以下の記事で解説しています。

ちなみに、処理をステップ実行で確認すると分かりますが、この時点では画面上の選択状態と実際の選択セルに違いが生じます。
これは画面更新が行われていないために発生する現象です。

その後のセル選択によって画面更新が行われるため処理上は問題ありませんが、もし処理を変更して画面更新が行われなくなる場合には、画面更新のコードを1行追加することで対策できます。

'選択状態の画面更新(処理上は不要でOK)
'Application.ScreenUpdating = True

具体的には、このコードを直後に挿入するだけで画面更新が行われます。

    'フィルタ条件一致有無の判定(集計行がある場合は3にする)
    If Selection.Cells.Count >= 2 Then
        '選択をデータ範囲のみにする
        Intersect(.DataBodyRange, Selection).Select
        '抽出データがある場合の処理

ここでは、フィルタ条件に一致するデータが存在するかどうかを判定しています。
仕様上、見出しセルは必ず選択されるため、選択セルの個数が2以上であれば条件一致のデータが存在すると判断します。
逆に選択セルが1個のみの場合は、条件に一致するデータがなかったと判断します。
なお、集計行があるテーブルでは選択セルが1つ増えるため、条件式の「2」の部分を「3」に修正してください。

抽出条件に一致するデータが選択されている場合は、実際の選択範囲とデータ範囲を Intersect メソッドで突き合わせ、データ範囲のみを選択状態にしています。
この後は、選択状態のセルに対して必要な処理を作成してください。

    Else
        '抽出データがない場合の処理
        Debug.Print "抽出データなし"
    End If

ここでは、抽出条件に一致するデータが存在しなかった場合の処理を作成します。
特に処理が不要であれば、この部分の追加処理は省略して構いません。
また、例コードにあるイミディエイト出力も削除して問題ありません。