Sub (Instrucción, Visual Basic)

Declara el nombre, los parámetros y el código que definen un procedimiento Sub.

Sintaxis

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

Partes

  • attributelist

    Opcional. Consulte Lista de atributos.

  • Partial

    Opcional. Indica la definición de un método parcial. Consulte Métodos parciales.

  • accessmodifier

    Opcional. Puede ser uno de los siguientes:

    Vea Access levels in Visual Basic.

  • proceduremodifiers

    Opcional. Puede ser uno de los siguientes:

  • Shared

    Opcional. Vea Shared.

  • Shadows

    Opcional. Consulte Shadows.

  • Async

    Opcional. Consulte Async.

  • name

    Necesario. Nombre del procedimiento. Vea Declared Element Names. Para crear un procedimiento de constructor para una clase, establezca el nombre de un procedimiento Sub en la palabra clave New. Para obtener más información, consulte Duración de los objetos: cómo se crean y destruyen.

  • typeparamlist

    Opcional. Lista de parámetros de tipo para un procedimiento genérico. Consulte Lista de tipos.

  • parameterlist

    Opcional. Lista de nombres de variables locales que representan los parámetros de este procedimiento. Consulte Lista de parámetros.

  • Implements

    Opcional. Indica que este procedimiento implementa uno o varios procedimientos Sub, cada uno definido en una interfaz implementada por la clase o estructura que contiene este procedimiento. Consulte Instrucción Implements.

  • implementslist

    Es necesario si se proporciona Implements. Lista de procedimientos Sub que se implementan.

    implementedprocedure [ , implementedprocedure ... ]

    Cada implementedprocedure tiene la sintaxis y las partes siguientes:

    interface.definedname

    Parte Descripción
    interface Necesario. Nombre de una interfaz implementada por la estructura o clase contenedora de este procedimiento.
    definedname Necesario. Nombre por el que se define el procedimiento en interface.
  • Handles

    Opcional. Indica que este procedimiento puede controlar uno o varios eventos específicos. Consulte Handles.

  • eventlist

    Es necesario si se proporciona Handles. Lista de eventos que controla este procedimiento.

    eventspecifier [ , eventspecifier ... ]

    Cada eventspecifier tiene la sintaxis y las partes siguientes:

    eventvariable.event

    Parte Descripción
    eventvariable Necesario. Variable de objeto declarada con el tipo de datos de la clase o estructura que genera el evento.
    event Necesario. Nombre del evento que controla este procedimiento.
  • statements

    Opcional. Bloque de instrucciones que se ejecutarán dentro de este procedimiento.

  • End Sub

    Finaliza la definición de este procedimiento.

Comentarios

Todo el código ejecutable debe estar dentro de un procedimiento. Use un procedimiento Sub cuando no quiera devolver un valor al código que realiza la llamada. Use un procedimiento Function cuando quiera devolver un valor.

Definición de un procedimiento Sub

Solo puede definir un procedimiento Sub en el nivel de módulo. Por lo tanto, el contexto de declaración de un procedimiento Sub debe ser una clase, una estructura, un módulo o una interfaz y no puede ser un archivo de código fuente, un espacio de nombres, un procedimiento o un bloque. Para obtener más información, vea Declaration Contexts and Default Access Levels (Contextos de declaración y niveles de acceso predeterminados).

Procedimientos Sub predeterminados para el acceso público. Los niveles de acceso se pueden ajustar con los modificadores de acceso.

Si el procedimiento usa la palabra clave Implements, la clase o estructura contenedora debe tener una instrucción Implements que vaya inmediatamente después de su instrucción Class o Structure. La instrucción Implements debe incluir cada interfaz especificada en implementslist. Sin embargo, el nombre por el que una interfaz define Sub (en definedname) no tiene que coincidir con el nombre de este procedimiento (en name).

Devolución desde un procedimiento Sub

Cuando un procedimiento Sub realiza la devolución al código de llamada, la ejecución continúa con la instrucción después de la instrucción que la llamó.

En el ejemplo siguiente se muestra una devolución desde un procedimiento Sub.

Sub mySub(ByVal q As String)
    Return
End Sub

Las instrucciones Exit Sub y Return provocan una salida inmediata de un procedimiento Sub. Puede aparecer cualquier número de instrucciones Exit Sub y Return en cualquier parte del procedimiento, y se pueden mezclar instrucciones Exit Sub y Return.

Llamada a un procedimiento Sub

Para llamar a un procedimiento Sub, use el nombre del procedimiento en una instrucción y, posteriormente, siga ese nombre con su lista de argumentos entre paréntesis. Solo puede omitir los paréntesis si no proporciona ningún argumento. Sin embargo, el código es más legible si siempre incluye los paréntesis.

Un procedimiento Sub y un procedimiento Function pueden tener parámetros y realizar una serie de instrucciones. Sin embargo, un procedimiento Function devuelve un valor, mientras que un procedimiento Sub no lo hace. Por lo tanto, no se puede usar un procedimiento Sub en una expresión.

Puede usar la palabra clave Call al llamar a un procedimiento Sub, pero esa palabra clave no se recomienda para la mayoría de los usos. Para obtener más información, consulte Call (Instrucción).

Visual Basic a veces reorganiza expresiones aritméticas para aumentar la eficacia interna. Por ese motivo, si la lista de argumentos incluye expresiones que llaman a otros procedimientos, no debe suponer que esas expresiones se llamarán en un orden determinado.

Procedimientos Sub Async

Mediante la característica Async, puede invocar funciones asincrónicas sin usar definiciones de llamada explícitas ni dividir manualmente el código en varias funciones o expresiones lambda.

Si marca un procedimiento con el modificador Async, puede usar el operador Await en el procedimiento. Cuando el control alcanza una expresión Await en el procedimiento Async, el control se devuelve al autor de llamada y el progreso del procedimiento se suspende hasta que se completa la tarea esperada. Cuando se completa la tarea, la ejecución puede reanudarse en el procedimiento.

Nota

Un procedimiento Async se devuelve al autor de la llamada cuando encuentra el primer objeto esperado que aún no se ha completado o cuando llega al final del procedimiento Async, lo que ocurra primero.

También puede marcar una instrucción Function con el modificador Async. Una función Async puede tener un tipo de valor devuelto de Task<TResult> o Task. Un ejemplo más adelante en este tema muestra una función Async que tiene un tipo de valor devuelto de Task<TResult>.

AsyncLos procedimientos Sub se usan principalmente para los controladores de eventos, donde no se puede devolver un valor. No se puede esperar un procedimiento AsyncSub y el autor de la llamada de un procedimiento AsyncSub no puede detectar las excepciones que produce el procedimiento Sub.

Un procedimiento Async no puede declarar ningún parámetro ByRef.

Para obtener Más información acerca de los procedimientos Async, consulte Programación asincrónica con Async y Await, Controlar el flujo en los programas asincrónicos y Tipos de valor devueltos asincrónicos.

Ejemplo 1

En el ejemplo siguiente se usa la instrucción Sub para definir el nombre, los parámetros y el código que forman el cuerpo de un procedimiento 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

Ejemplo 2

En el ejemplo siguiente, DelayAsync es un AsyncFunction con un tipo de valor devuelto de Task<TResult>. DelayAsync tiene una instrucción Return que devuelve un entero. Por lo tanto, la declaración de la función de DelayAsync debe tener un tipo de valor devuelto de Task(Of Integer). Dado que el tipo de valor devuelto es Task(Of Integer), la evaluación de la expresión Await en DoSomethingAsync genera un entero, como se muestra en la instrucción siguiente: Dim result As Integer = Await delayTask.

El procedimiento startButton_Click es un ejemplo de un procedimiento Async Sub. Dado que DoSomethingAsync es una función Async, la tarea de la llamada a DoSomethingAsync debe esperar, como se muestra en la siguiente instrucción: Await DoSomethingAsync(). El procedimiento startButton_ClickSub debe definirse con el modificador Async porque el método tiene una expresión Await.

' 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

Consulte también