Sub ステートメント (Visual Basic)

Sub プロシージャを定義する名前、パラメーター、およびコードを宣言します。

構文

[ <attributelist> ] [ Partial ] [ accessmodifier ] [ proceduremodifiers ] [ Shared ] [ Shadows ] [ Async ]
Sub name [ (Of typeparamlist) ] [ (parameterlist) ] [ Implements implementslist | Handles eventlist ]
    [ statements ]
    [ Exit Sub ]
    [ statements ]
End Sub

指定項目

  • attributelist

    任意。 「属性リスト」を参照してください。

  • Partial

    任意。 部分メソッドの定義を示します。 「部分メソッド」を参照してください。

  • accessmodifier

    任意。 次のいずれかの値を指定します。

    Access levels in Visual Basic」を参照してください。

  • proceduremodifiers

    任意。 次のいずれかの値を指定します。

  • Shared

    任意。 「Shared」を参照してください。

  • Shadows

    任意。 「Shadows」を参照してください。

  • Async

    任意。 「Async」を参照してください。

  • name

    必須です。 プロシージャの名前。 「 Declared Element Names」を参照してください。 クラスのコンストラクター プロシージャを作成するには、Sub プロシージャの名前を New キーワードに設定します。 詳細については、以下をご覧ください: オブジェクトの有効期間: オブジェクトの作成と破棄

  • typeparamlist

    任意。 ジェネリック プロシージャの型パラメーターの一覧。 「型リスト」を参照してください。

  • parameterlist

    任意。 このプロシージャのパラメーターを表すローカル変数名の一覧。 「パラメーターの一覧」を参照してください。

  • Implements

    任意。 それぞれこのプロシージャの含まれているクラスまたは構造体によって実装されたインターフェイスに定義されている、1 つ以上の Sub プロシージャを、このプロシージャが実装することを示します。 「Implements ステートメント」を参照してください。

  • implementslist

    Implements を指定する場合は、必ず指定します。 実装される Sub プロシージャのリストです。

    implementedprocedure [ , implementedprocedure ... ]

    implementedprocedure の構文と指定項目は次のとおりです。

    interface.definedname

    パーツ 説明
    interface 必須です。 このプロシージャの含まれているクラスまたは構造体によって実装されたインターフェイスの名前。
    definedname 必須です。 interface の中でプロシージャを定義するために使用する名前。
  • Handles

    任意。 このプロシージャで 1 つ以上の特定のイベントを処理できることを示します。 「Handles」を参照してください。

  • eventlist

    Handles を指定する場合は、必ず指定します。 このプロシージャで処理するイベントの一覧。

    eventspecifier [ , eventspecifier ... ]

    eventspecifier の構文と指定項目は次のとおりです。

    eventvariable.event

    パーツ 説明
    eventvariable 必須です。 イベントを発生させるクラスまたは構造体のデータ型で宣言されたオブジェクト変数。
    event 必須です。 このプロシージャで処理するイベントの名前。
  • statements

    任意。 このプロシージャ内で実行するステートメントのブロック。

  • End Sub

    このプロシージャの定義を終了します。

Remarks

すべての実行可能コードは、プロシージャ内になければなりません。 呼び出し元のコードに値を返さない場合は、Sub プロシージャを使用します。 値を返す場合は、Function プロシージャを使用します。

Sub プロシージャの定義

Sub プロシージャは、モジュール レベルでのみ定義できます。 そのため、Sub プロシージャの宣言コンテキストはクラス、構造体、モジュール、インターフェイスにする必要があり、ソース ファイル、名前空間、プロシージャ、ブロックにすることはできません。 詳細については、「宣言コンテキストと既定のアクセス レベル」を参照してください。

Sub プロシージャは、既定でパブリック アクセスに設定されます。 アクセス修飾子を使用してこれらのアクセス レベルを調整できます。

プロシージャで Implements キーワードが使用されている場合、含まれているクラスまたは構造体には、その Class または Structure ステートメントの直後に Implements ステートメントが必要です。 Implements ステートメントには、implementslist で指定された各インターフェイスを含める必要があります。 ただし、インターフェイスで Sub を定義するときに使用する名前 (definedname) は、このプロシージャの名前 (name) に一致している必要はありません。

Sub プロシージャからの復帰

Sub プロシージャから呼び出し元のコードに返されると、実行は、それを呼び出したステートメントの後のステートメントから続行されます。

次の例は、Sub プロシージャからの戻り値を示しています。

Sub mySub(ByVal q As String)
    Return
End Sub

Exit Sub および Return ステートメントでは、Sub プロシージャがすぐに終了します。 任意の数の Exit Sub および Return ステートメントをプロシージャ内の任意の場所に記述でき、Exit Sub ステートメントと Return ステートメントを混在させることができます。

Sub プロシージャの呼び出し

Sub プロシージャを呼び出すには、ステートメントでプロシージャ名を使用し、その名前の後にかっこで囲んだ引数リストを指定します。 引数を指定しない場合のみ、かっこを省略できます。 ただし、常にかっこを含めると、コードが読みやすくなります。

Sub プロシージャと Function プロシージャは、パラメーターを持つことができ、一連のステートメントを実行できます。 ただし、Function プロシージャは値を返し、Sub プロシージャは返しません。 そのため、式の中で Sub プロシージャを使用することはできません。

Sub プロシージャを呼び出すときに Call キーワードを使用できますが、ほとんどの用途で、そのキーワードは推奨されません。 詳細については、「Call ステートメント」を参照してください。

Visual Basic では、内部効率を高めるために算術式が再配置されることがあります。 そのため、引数リストに他のプロシージャを呼び出す式が含まれている場合は、それらの式が特定の順序で呼び出されることを前提としないでください。

Async Sub プロシージャ

Async 機能を使用することによって、明示的なコールバックを使用せずに、または複数のメソッドやラムダ式にわたって手動でコードを分割することなく、非同期関数を呼び出すことができます。

プロシージャに Async 修飾子を付けると、そのプロシージャで Await 演算子を使用できます。 制御が Async プロシージャの Await 式に到達すると、制御が呼び出し元に戻り、待機中のタスクが完了するまでプロシージャの進行が中断されます。 タスクが完了すると、プロシージャで実行を再開できます。

注意

Async プロシージャは、まだ完了していない待機中の最初のオブジェクトが検出されるか、または Async プロシージャの最後に達するか、どちらか先に発生したときに、呼び出し元に戻ります。

また、Async 修飾子で、Function ステートメントをマークすることもできます。 Async 関数の戻り値の型には、Task<TResult> または Task を指定できます。 このトピックの後述の例では、Task<TResult> の戻り値の型を持つ Async 関数を示します。

AsyncSub プロシージャは、主にイベント ハンドラーで使用し、その場合、値を返すことはできません。 AsyncSub プロシージャは待機できず、AsyncSub プロシージャの呼び出し元では、Sub プロシージャがスローする例外をキャッチできません。

Async プロシージャでは、ByRef パラメーターを宣言することはできません。

Async プロシージャの詳細については、「Async および Await を使用した非同期プログラミング」、「非同期プログラムにおける制御フロー」、「非同期の戻り値の型」を参照してください。

例 1

次の例では、Sub ステートメントを使用して、Sub プロシージャの本体を形成する名前、パラメーター、およびコードを定義しています。

Sub ComputeArea(ByVal length As Double, ByVal width As Double)
    ' Declare local variable.
    Dim area As Double
    If length = 0 Or width = 0 Then
        ' If either argument = 0 then exit Sub immediately.
        Exit Sub
    End If
    ' Calculate area of rectangle.
    area = length * width
    ' Print area to Immediate window.
    Debug.WriteLine(area)
End Sub

例 2

次の例で、DelayAsync は、戻り値の型が Task<TResult> である AsyncFunction です。 DelayAsync には、整数を返す Return ステートメントがあります。 そのため、DelayAsync の関数宣言では、戻り値の型を Task(Of Integer) とする必要があります。 戻り値の型が Task(Of Integer) であるため、ステートメント Dim result As Integer = Await delayTask に示すように、DoSomethingAsync 内の Await 式を評価すると、整数が生成されます。

startButton_Click プロシージャは、Async Sub プロシージャの一例です。 DoSomethingAsyncAsync 関数であるため、ステートメント Await DoSomethingAsync() に示すように、DoSomethingAsync を呼び出すタスクは、待機させる必要があります。 startButton_ClickSub プロシージャは、Await 式を使用しているため、Async 修飾子を使用して定義する必要があります。

' Imports System.Diagnostics
' Imports System.Threading.Tasks

' This Click event is marked with the Async modifier.
Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
    Await DoSomethingAsync()
End Sub

Private Async Function DoSomethingAsync() As Task
    Dim delayTask As Task(Of Integer) = DelayAsync()
    Dim result As Integer = Await delayTask

    ' The previous two statements may be combined into
    ' the following statement.
    ' Dim result As Integer = Await DelayAsync()

    Debug.WriteLine("Result: " & result)
End Function

Private Async Function DelayAsync() As Task(Of Integer)
    Await Task.Delay(100)
    Return 5
End Function

'  Output:
'   Result: 5

関連項目