Cómo automatizar Microsoft Access desde Visual Basic .NET

Resumen

Este artículo proporciona ejemplos paso a paso que muestran cómo automatizar Microsoft Access desde Visual Basic .NET. Los temas y el código de ejemplo muestran cómo hacer lo siguiente:
  • Abrir una base de datos en Access
  • Imprimir o vista previa de un informe de Access
  • Mostrar y editar un formulario de Access
  • Evitar los cuadros de diálogo al abrir una base de datos protegida con contraseña o cuando está activada la seguridad a nivel de usuario
  • Automatizarlos

Automatización frente a ADO.NET

Un desarrollador puede trabajar con una base de datos de Microsoft Access desde .NET de Visual Basic utilizar dos tecnologías diferentes: la automatización y los objetos de datos ActiveX de Microsoft (ADO.NET).

ADO.NET es la tecnología recomendada si desea trabajar con objetos de datos, como tablas y consultas en una base de datos de Access. Utilizar la automatización sólo si necesita características específicas de la aplicación de Microsoft Access, como la capacidad para imprimir u obtener una vista previa de un informe de Access, para mostrar un formulario de Access, o llamar a macros.

Este artículo describe cómo automatizar Access. El artículo no describe ADO.NET. Para obtener información acerca de ADO.NET, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:
301075 cómo conectarse a una base de datos y ejecutar un comando mediante ADO.NET y Visual Basic .NET
301216 cómo llenar un objeto DataSet desde una base de datos mediante Visual Basic .NET
301248 cómo actualizar una base de datos desde un objeto DataSet mediante Visual Basic .NET
La automatización es una tecnología de COM. La automatización permite que las aplicaciones escritas en lenguajes como Visual Basic .NET controlar otras aplicaciones mediante programación. Cuando se automatiza una aplicación de Microsoft Office, ejecutar realmente una instancia de esa aplicación en la memoria y, a continuación, llamar al modelo de objetos de la aplicación para realizar diversas tareas en esa aplicación. Con Access y otras aplicaciones de Microsoft Office, prácticamente todas las acciones que puede realizar manualmente mediante la interfaz de usuario pueden también realizarse mediante programación utilizando la automatización.

Access expone esta funcionalidad a través de un modelo de objetos de programación. El modelo de objetos es una colección de clases y métodos que actúan como homólogos de los componentes lógicos de acceso. Para tener acceso al modelo de objetos desde Visual Basic .NET, puede establecer una referencia de proyecto a la biblioteca de tipos, que se describe en el ejemplo en este artículo paso a paso. Para obtener más información acerca de este proceso, o para obtener más información acerca de la documentación del modelo de objetos de Office, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
222101 cómo encontrar y usar la documentación del modelo de objetos de Office

Tareas comunes de automatización

Abrir una base de datos en Access

Al automatizar Microsoft Access, debe abrir una base de datos para poder realizar tareas útiles, como la impresión de informes. Para abrir una base de datos en la instancia de Access que esté automatizando, utilice los métodos OpenCurrentDatabase u OpenAccessProject del objeto Application . Puede tener sólo una base de datos abierta en Access a la vez. Para trabajar con una base de datos diferente, puede utilizar el método CloseCurrentDatabase antes de abrirla.

También puede utilizar la función GetObject (< ruta de acceso a la base de datos >) para abrir una base de datos en una instancia de Access. Si la base de datos ya está abierto en una instancia de Access, GetObject devuelve el objeto Application de esa instancia. De lo contrario, GetObject abrirá la base de datos en una instancia en ejecución de Access. Si se está ejecutando ninguna instancia de Access, GetObject iniciará una nueva instancia de Access y abre la base de datos especificada.

Si utiliza la función GetObject para abrir una base de datos, no puede controlar la instancia de Access en la que se abre la base de datos. OpenCurrentDatabase es el método preferido para abrir una base de datos porque permite especificar la instancia de Access que desea automatizar. También puede proporcionar argumentos opcionales para controlar cómo se abre la base de datos, por ejemplo:
Dim oAccess As Access.Application
' Start a new instance of Access for Automation:
oAccess = New Access.ApplicationClass()

' Open a database in exclusive mode:
oAccess.OpenCurrentDatabase(filepath:="c:\mydb.mdb", Exclusive:=True)

Imprimir o vista previa de un informe de Access

Para obtener una vista previa o imprimir un informe de Access, llame el método OpenReport del objeto DoCmd . Al llamar a OpenReport, uno de los argumentos que se pasan determina si el informe de vista previa en la pantalla o si ha de enviarse a la impresora:
' Preview a report named Sales:oAccess.DoCmd.OpenReport(ReportName:="Sales", _
View:=Access.AcView.acViewPreview)
' Print a report named Sales:
oAccess.DoCmd.OpenReport(ReportName:="Sales", _
View:=Access.AcView.acViewNormal)

Observe que el argumento vista determina si se muestra el informe en Access, o si ha de enviarse a la impresora. El método OpenReport tiene otros argumentos útiles, como WhereCondition. WhereCondition permite limitar el conjunto de registros del informe mediante una cláusula WHERE de SQL válida (sin la palabra donde.)

Si en la vista preliminar de un informe, asegúrese de establecer la propiedad Visible del objeto Application para que Access esté visible en la pantalla. De esta forma, el usuario puede ver el informe en la ventana de Access.

Hay otra forma de imprimir un informe u otros objetos de la base de datos. Utilice el método PrintOut del objeto DoCmd . En este ejemplo, se selecciona el informe Employees en la ventana Base de datos y, a continuación, se llama a PrintOut para imprimir el objeto seleccionado. El método PrintOut permite proporcionar los argumentos correspondientes al cuadro de diálogo Imprimir de la caja en Access, incluyendo PrintRange, PageFrom, PageTo, PrintQuality, Copiesy CollateCopies:
' Select the Employees report in the Database window: oAccess.DoCmd.SelectObject(ObjectType:=Access.AcObjectType.acReport, _
ObjectName:="Employees", InDatabaseWindow:=True)
' Print 2 copies of the selected object:
oAccess.DoCmd.PrintOut(PrintRange:=Access.AcPrintRange.acPrintAll, _
Copies:=2, CollateCopies:=False)

O bien, en algunos casos, es aconsejable utilizar el OpenReport y los métodos de impresión para imprimir un informe. Suponga que desea imprimir varias copias del informe Employees, pero sólo para un empleado específico. En este ejemplo primero se utiliza OpenReport para abrir el informe en modo de vista previa, con el argumento WhereCondition para limitar los registros para un empleado específico. A continuación, se utiliza PrintOut para imprimir varias copias del objeto activo:
' Open the report in preview mode using a WhereCondition: oAccess.DoCmd.OpenReport(ReportName:="Employees", _
View:=Access.AcView.acViewPreview, _
WhereCondition:="[EmployeeID]=1")
' Print 2 copies of the active object:
oAccess.DoCmd.PrintOut(PrintRange:=Access.AcPrintRange.acPrintAll, _
Copies:=2, CollateCopies:=False)
' Close the report preview window:
oAccess.DoCmd.Close(ObjectType:=Access.AcObjectType.acReport, _
ObjectName:="Employees")

Access 2002 introduce el objeto Printer . Puede utilizar este objeto para personalizar la configuración de impresora de acceso más fácilmente que en versiones anteriores de Access. Para obtener un ejemplo de uso del objeto Printer de Access para imprimir un informe, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
284286 ACC2002: cómo restablecer los cambios al objeto Application.Printer

Mostrar y editar un formulario de Access

Visual Basic .NET cuenta con capacidades muy potentes para formularios. Sin embargo, puede haber ocasiones cuando desea que el usuario para ver formularios desarrollados en Access. O bien, podría tener un formulario en la base de datos de Access que proporciona criterios para una consulta o un informe, y debe abrir dicho formulario antes de que se puede obtener una vista previa o imprimir el informe. Para abrir y mostrar un formulario de Access, llame al método OpenForm del objeto DoCmd :
' Show a form named Employees:oAccess.DoCmd.OpenForm(FormName:="Employees", _
View:=Access.AcFormView.acNormal)

Ahora puede editar los controles en el formulario.

Cuadros de diálogo de seguridad de acceso

Al automatizar Access, es posible que se deba introducir un nombre de usuario o contraseña o ambos, cuando intenta abrir una base de datos. Si el usuario introdujera algún valor equivocado, se producirá un error en el código. Puede haber ocasiones cuando desea evitar estos cuadros de diálogo y en su lugar para proporcionar mediante programación el nombre de usuario y la contraseña para que el código de automatización se ejecute sin interrupciones.

Hay dos tipos de seguridad en Microsoft Access: bases de datos protegidas con contraseña y seguridad de nivel de usuario a través de un archivo de grupo de trabajo (System.mdw). Si intenta abrir una base de datos está protegida por contraseña, aparecerá un cuadro de diálogo le pide la contraseña de la base de datos. Seguridad de nivel de usuario es diferente de una base de datos protegida con contraseña. Cuando está activada la seguridad de nivel de usuario, Access muestra un cuadro de diálogo de inicio de sesión que pide un nombre de usuario y una contraseña antes de que el usuario puede abrir cualquier base de datos en Access. Para obtener más información acerca de la seguridad de acceso y el archivo de información de grupo de trabajo, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

305542 ACC2002: la función del archivo de información de grupo de trabajo en seguridad

Evitar los cuadros de diálogo de contraseña de base de datos

Si está abriendo una base de datos que se ha protegido con una contraseña, podrá evitar el cuadro de diálogo proporcionando la contraseña al método OpenCurrentDatabase :
' Open a password-protected database in shared mode:' Note: The bstrPassword argument is case-sensitive
oAccess.OpenCurrentDatabase(filepath:="c:\mydb.mdb", _
Exclusive:=False, bstrPassword:="MyPassword")

El argumento bstrPassword , agregado al método OpenCurrentDatabase con el lanzamiento de Access 2002. No está disponible en Access 2000. Para evitar el cuadro de diálogo de contraseña al automatizar Access 2000 para abrir una base de datos protegida con contraseña, debe utilizar el método OpenDatabase del objeto DBEngine y proporcionar la contraseña de la base de datos con el argumento Connect . A continuación, utilice OpenCurrentDatabase para abrir la base de datos en Access.

En el siguiente ejemplo, oAccess se ha establecido previamente a una instancia de Access y sDBPath es la ruta de la base de datos protegida por contraseña que desea abrir. Este código proporciona la contraseña para la base de datos de forma que se evite un cuadro de diálogo:
Dim sDBPassword as String        Dim oDBEngine As DAO.DBEngine
Dim oDB As DAO.Database

sDBPassword = "Mypassword" 'database password
oDBEngine = oAccess.DBEngine
oDB = oDBEngine.OpenDatabase(Name:=sDBPath, _
Options:=False, _
ReadOnly:=False, _
Connect:=";PWD=" & sDBPassword)
oAccess.OpenCurrentDatabase(filepath:=sDBPath, _
Exclusive:=False)
oDB.Close()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDB)
oDB = Nothing
System.Runtime.InteropServices.Marshal.ReleaseComObject(oDBEngine)
oDBEngine = Nothing

El oDB.Close no cierra realmente la base de datos en Access. Sólo cierra la conexión DAO a la base de datos se realizó a través del objeto DBEngine . Esta conexión ya no es necesaria cuando se utiliza el método OpenCurrentDatabase . Observe el código que libera los objetos oDB y oDBEngine. Debe utilizar estos objetos para que Access pueda cerrarse correctamente una vez completado el código.

Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
235422 ACC2000: cómo abrir una base de datos protegida con contraseña mediante automatización

Evitar el cuadro de diálogo de inicio de sesión de seguridad de acceso

Si está activada la seguridad de nivel de usuario en Access, se pide al usuario un cuadro de diálogo de inicio de sesión que pide un nombre de usuario y una contraseña. Un nombre de usuario y una contraseña no pueden especificarse mediante el modelo de objetos de Access. Por lo tanto, si desea evitar el cuadro de diálogo de inicio de sesión al automatizar Access, primero debe iniciar el archivo Msaccess.exe y proporcionar la /user y /pwd modificadores para especificar el nombre de usuario y la contraseña. Tras ello, puede utilizar GetObject para recuperar el objeto Application de la instancia en ejecución de Access que se puede proceder con la automatización. Para obtener un ejemplo de cómo hacerlo, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
192919 cómo automatizar una base de datos protegida de Access utilizando Visual Basic
Para obtener más información acerca de cómo iniciar Access con modificadores de línea de comandos, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
209207 cómo utilizar modificadores de línea de comandos en Microsoft Access

Automatizar Access Runtime

El Microsoft Office Developer Edition incluye Microsoft Office Developer Tools (MOD). Con MOD, los programadores de Access pueden crear y distribuir aplicaciones de acceso a los usuarios que no tengan la versión comercial de Access. Cuando el usuario instala la aplicación de Access en un equipo que no tiene la versión comercial de Access, se instala una versión en tiempo de ejecución de Access. El tiempo de ejecución de Access se instala y se registra como la versión comercial. El ejecutable también se denominará Msaccess.exe. El tiempo de ejecución de Access permite que una aplicación de Access ejecutar en un equipo cliente, pero el tiempo de ejecución de Access no permite un usuario para desarrollar nuevas aplicaciones o modificar el diseño de las aplicaciones existentes.

El tiempo de ejecución de Access debe iniciarse con una base de datos. Debido a este requisito, si desea automatizarlos, deberá iniciar Msaccess.exe y especificar una base de datos para abrir. Después de utilizar GetObject para recuperar el objeto Application , podrá seguir automatizando el tiempo de ejecución de Access. Si intenta automatizarlos con la palabra clave New o con CreateObject, recibirá un mensaje de error como el siguiente cuando intenta crear una instancia de la instancia:
-2147023186 que no se encontró el identificador único universal (UUID) de objeto.
Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
295179 ACC2002: no se puede usar Automatización OLE con Access Runtime

Crear el proyecto de ejemplo completo de Visual Basic .NET

Para utilizar el siguiente ejemplo paso a paso, asegúrese de que está instalada la base de datos de ejemplo Northwind.
Nota: De forma predeterminada, Access 2002 instalará las bases de datos de ejemplo en la siguiente ruta: C:\Program Files\Microsoft Office\Office10\Samples. Con Access 2002, puede asegurarse de que está instalada la base de datos de ejemplo Northwind. Haga clic en el menú Ayuda , haga clic en Bases de datos de ejemploy, a continuación, haga clic en Base de datos de ejemplo Northwind.
  1. Cierre todas las instancias de Access que se están ejecutando.
  2. Inicie Microsoft Visual Studio. NET. En el menú archivo , haga clic en nuevo y, a continuación, haga clic en proyecto. Seleccione Aplicación para Windows en los tipos de proyectos de Visual Basic. De forma predeterminada, se crea Form1 .
  3. Agregue una referencia a la Biblioteca de objetos de Microsoft Access. Para ello, siga estos pasos:
    1. En el menú proyecto , haga clic en Agregar referencia.
    2. En la ficha COM , busque Biblioteca de objetos de Microsoft Access 10.0y, a continuación, haga clic en Seleccionar. Nota: si no lo ha hecho ya, se recomienda que descargue e instale Microsoft Office XP Primary Interop Assemblies (PIA).

      Para obtener información adicional acerca de los PIA de Office XP, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
      328912 INFO: ensamblados de interoperabilidad primarios de Microsoft Office XP están disponibles para su descarga
    3. Haga clic en Aceptar en el cuadro de diálogo Agregar referencias para aceptar sus selecciones. Si recibe un mensaje para generar contenedores para las bibliotecas seleccionadas, haga clic en .

      Nota: Si hace referencia a la biblioteca de objetos de Access 10.0 y recibe errores al intentar agregar referencias, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
      317157 PRB: errores al hacer referencia a la biblioteca de tipos de Access 10.0
  4. En el menú Ver , seleccione cuadro de herramientas para mostrar el cuadro de herramientas.
  5. Agregue cinco controles de botón de opción y un control button a Form1.
  6. Seleccione todos los controles de botón de radio y, a continuación, establezca la propiedad Size en 150,24.
  7. En el menú Ver , haga clic en código.
  8. Inserte el código siguiente en la clase del formulario:
    Private m_sAction As String
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles MyBase.Load
    RadioButton1.Text = "Print report"
    RadioButton2.Text = "Preview report"
    RadioButton3.Text = "Show form"
    RadioButton4.Text = "Print report (Security)"
    RadioButton5.Text = "Preview report (Runtime)"
    Button1.Text = "Go!"
    End Sub

    Private Sub RadioButtons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles RadioButton1.Click, RadioButton2.Click, RadioButton3.Click, RadioButton4.Click, RadioButton5.Click
    m_sAction = sender.Text 'Store the text for the selected radio button
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click
    ' Calls the associated procedure to automate Access, based
    ' on the selected radio button on the form.
    Select Case m_sAction
    Case "Print report" : Print_Report()
    Case "Preview report" : Preview_Report()
    Case "Show form" : Show_Form()
    Case "Print report (Security)" : Print_Report_Security()
    Case "Preview report (Runtime)" : Preview_Report_Runtime()
    End Select
    End Sub

    Private Function ShellGetDB(ByVal sDBPath As String, _
    Optional ByVal sCmdLine As String = vbNullString, _
    Optional ByVal enuWindowStyle As Microsoft.VisualBasic.AppWinStyle _
    = AppWinStyle.MinimizedFocus, _
    Optional ByVal iSleepTime As Integer = 1000) As Access.Application

    'Launches a new instance of Access with a database (sDBPath)
    'using the Shell function then returns the Application object
    'via calling: GetObject(sDBPath). Returns the Application
    'object of the new instance of Access, assuming that sDBPath
    'is not already opened in another instance of Access. To ensure
    'the Application object of the new instance is returned, make
    'sure sDBPath is not already opened in another instance of Access.
    '
    'Example:
    'Dim oAccess As Access.Application
    'oAccess = ShellGetDB("c:\mydb.mdb")

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oAccess As Access.Application
    Dim sAccPath As String 'path to msaccess.exe

    ' Obtain the path to msaccess.exe:
    sAccPath = GetOfficeAppPath("Access.Application", "msaccess.exe")
    If sAccPath = "" Then
    MsgBox("Can't determine path to msaccess.exe", _
    MsgBoxStyle.MsgBoxSetForeground)
    Return Nothing
    End If

    ' Make sure specified database (sDBPath) exists:
    If Not System.IO.File.Exists(sDBPath) Then
    MsgBox("Can't find the file '" & sDBPath & "'", _
    MsgBoxStyle.MsgBoxSetForeground)
    Return Nothing
    End If

    ' Start a new instance of Access using sDBPath and sCmdLine:
    If sCmdLine = vbNullString Then
    sCmdLine = Chr(34) & sDBPath & Chr(34)
    Else
    sCmdLine = Chr(34) & sDBPath & Chr(34) & " " & sCmdLine
    End If
    Shell(Pathname:=sAccPath & " " & sCmdLine, _
    Style:=enuWindowStyle)
    'Note: It is advised that the Style argument of the Shell
    'function be used to give focus to Access.

    ' Move focus back to this form. This ensures that Access
    ' registers itself in the ROT, allowing GetObject to find it:
    AppActivate(Title:=Me.Text)

    ' Pause to allow database to open:
    System.Threading.Thread.Sleep(iSleepTime)

    ' Obtain Application object of the instance of Access
    ' that has the database open:
    oAccess = GetObject(sDBPath)

    Return oAccess
    ErrorCleanup:
    ' Try to quit Access due to an unexpected error:
    On Error Resume Next
    oAccess.Quit(Option:=Access.AcQuitOption.acQuitSaveNone)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Return Nothing
    ErrorHandler:
    MsgBox(Err.Number & ": " & Err.Description, _
    MsgBoxStyle.MsgBoxSetForeground, "Error Handler")
    Resume ErrorCleanup
    End Function

    Private Function ShellGetApp(Optional ByVal sCmdLine As String = vbNullString, _
    Optional ByVal enuWindowStyle As Microsoft.VisualBasic.AppWinStyle _
    = AppWinStyle.MinimizedFocus) As Access.Application

    'Launches a new instance of Access using the Shell function
    'then returns the Application object via calling:
    'GetObject(,"Access.Application"). If an instance of
    'Access is already running before calling this procedure,
    'the function may return the Application object of a
    'previously running instance of Access. If this is not
    'desired, then make sure Access is not running before
    'calling this function, or use the ShellGetDB()
    'function instead. Approach based on Q308409.
    '
    'Examples:
    'Dim oAccess As Access.Application
    'oAccess = ShellGetApp()
    '
    '-or-
    '
    'Dim oAccess As Access.Application
    'Dim sUser As String
    'Dim sPwd As String
    'sUser = "Admin"
    'sPwd = ""
    'oAccess = ShellGetApp("/user " & sUser & "/pwd " & sPwd)

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oAccess As Access.Application
    Dim sAccPath As String 'path to msaccess.exe
    Dim iSection As Integer = 0
    Dim iTries As Integer = 0

    ' Obtain the path to msaccess.exe:
    sAccPath = GetOfficeAppPath("Access.Application", "msaccess.exe")
    If sAccPath = "" Then
    MsgBox("Can't determine path to msaccess.exe", _
    MsgBoxStyle.MsgBoxSetForeground)
    Return Nothing
    End If

    ' Start a new instance of Access using sCmdLine:
    If sCmdLine = vbNullString Then
    sCmdLine = sAccPath
    Else
    sCmdLine = sAccPath & " " & sCmdLine
    End If
    Shell(Pathname:=sCmdLine, Style:=enuWindowStyle)
    'Note: It is advised that the Style argument of the Shell
    'function be used to give focus to Access.

    ' Move focus back to this form. This ensures that Access
    ' registers itself in the ROT, allowing GetObject to find it:
    AppActivate(Title:=Me.Text)

    ' Attempt to use GetObject to reference a running
    ' instance of Access:
    iSection = 1 'attempting GetObject...
    oAccess = GetObject(, "Access.Application")
    iSection = 0 'resume normal error handling

    Return oAccess
    ErrorCleanup:
    ' Try to quit Access due to an unexpected error:
    On Error Resume Next
    oAccess.Quit(Option:=Access.AcQuitOption.acQuitSaveNone)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Return Nothing
    ErrorHandler:
    If iSection = 1 Then 'GetObject may have failed because the
    'Shell function is asynchronous; enough time has not elapsed
    'for GetObject to find the running Office application. Wait
    '1/2 seconds and retry the GetObject. If you try 20 times
    'and GetObject still fails, assume some other reason
    'for GetObject failing and exit the procedure.
    iTries = iTries + 1
    If iTries < 20 Then
    System.Threading.Thread.Sleep(500) 'wait 1/2 seconds
    AppActivate(Title:=Me.Text)
    Resume 'resume code at the GetObject line
    Else
    MsgBox("GetObject failed. Process ended.", _
    MsgBoxStyle.MsgBoxSetForeground)
    End If
    Else 'iSection = 0 so use normal error handling:
    MsgBox(Err.Number & ": " & Err.Description, _
    MsgBoxStyle.MsgBoxSetForeground, "Error Handler")
    End If
    Resume ErrorCleanup
    End Function

    Private Function GetOfficeAppPath(ByVal sProgId As String, ByVal sEXE As String) As String
    'Returns path of the Office application. e.g.
    'GetOfficeAppPath("Access.Application", "msaccess.exe") returns
    'full path to Microsoft Access. Approach based on Q240794.
    'Returns empty string if path not found in registry.

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oReg As Microsoft.Win32.RegistryKey = _
    Microsoft.Win32.Registry.LocalMachine
    Dim oKey As Microsoft.Win32.RegistryKey
    Dim sCLSID As String
    Dim sPath As String
    Dim iPos As Integer

    ' First, get the clsid from the progid from the registry key
    ' HKEY_LOCAL_MACHINE\Software\Classes\<PROGID>\CLSID:
    oKey = oReg.OpenSubKey("Software\Classes\" & sProgId & "\CLSID")

    sCLSID = oKey.GetValue("")
    oKey.Close()

    ' Now that we have the CLSID, locate the server path at
    ' HKEY_LOCAL_MACHINE\Software\Classes\CLSID\
    ' {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx}\LocalServer32:
    oKey = oReg.OpenSubKey("Software\Classes\CLSID\" & sCLSID & "\LocalServer32")
    sPath = oKey.GetValue("")
    oKey.Close()

    ' Remove any characters beyond the exe name:
    iPos = InStr(1, sPath, sEXE, CompareMethod.Text)
    sPath = Microsoft.VisualBasic.Left(sPath, iPos + Len(sEXE) - 1)
    Return Trim(sPath)
    ErrorHandler:
    Return ""
    End Function

    Private Sub Print_Report()
    'Prints the "Summary of Sales by Year" report in Northwind.mdb.

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oAccess As Access.Application
    Dim sDBPath As String 'path to Northwind.mdb
    Dim sReport As String 'name of report to print

    sReport = "Summary of Sales by Year"

    ' Start a new instance of Access for Automation:
    oAccess = New Access.ApplicationClass()

    ' Determine the path to Northwind.mdb:
    sDBPath = oAccess.SysCmd(Action:=Access.AcSysCmdAction.acSysCmdAccessDir)
    sDBPath = sDBPath & "Samples\Northwind.mdb"

    ' Open Northwind.mdb in shared mode:
    oAccess.OpenCurrentDatabase(filepath:=sDBPath, Exclusive:=False)

    ' Select the report name in the database window and give focus
    ' to the database window:
    oAccess.DoCmd.SelectObject(ObjectType:=Access.AcObjectType.acReport, _
    ObjectName:=sReport, InDatabaseWindow:=True)

    ' Print the report:
    oAccess.DoCmd.OpenReport(ReportName:=sReport, _
    View:=Access.AcView.acViewNormal)

    Cleanup:
    ' Quit Access and release object:
    On Error Resume Next
    oAccess.Quit(Option:=Access.AcQuitOption.acQuitSaveNone)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorHandler:
    MsgBox(Err.Number & ": " & Err.Description, _
    MsgBoxStyle.MsgBoxSetForeground, "Error Handler")
    ' Try to quit Access due to an unexpected error:
    Resume Cleanup
    End Sub

    Private Sub Preview_Report()
    'Previews the "Summary of Sales by Year" report in Northwind.mdb.

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oAccess As Access.Application
    Dim oForm As Access.Form
    Dim sDBPath As String 'path to Northwind.mdb
    Dim sReport As String 'name of report to preview

    sReport = "Summary of Sales by Year"

    ' Start a new instance of Access for Automation:
    oAccess = New Access.ApplicationClass()

    ' Make sure Access is visible:
    If Not oAccess.Visible Then oAccess.Visible = True

    ' Determine the path to Northwind.mdb:
    sDBPath = oAccess.SysCmd(Action:=Access.AcSysCmdAction.acSysCmdAccessDir)
    sDBPath = sDBPath & "Samples\Northwind.mdb"

    ' Open Northwind.mdb in shared mode:
    oAccess.OpenCurrentDatabase(filepath:=sDBPath, Exclusive:=False)

    ' Close any forms that Northwind may have opened:
    For Each oForm In oAccess.Forms
    oAccess.DoCmd.Close(ObjectType:=Access.AcObjectType.acForm, _
    ObjectName:=oForm.Name, _
    Save:=Access.AcCloseSave.acSaveNo)
    Next
    If Not oForm Is Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
    End If
    oForm = Nothing

    ' Select the report name in the database window and give focus
    ' to the database window:
    oAccess.DoCmd.SelectObject(ObjectType:=Access.AcObjectType.acReport, _
    ObjectName:=sReport, InDatabaseWindow:=True)

    ' Maximize the Access window:
    oAccess.RunCommand(Command:=Access.AcCommand.acCmdAppMaximize)

    ' Preview the report:
    oAccess.DoCmd.OpenReport(ReportName:=sReport, _
    View:=Access.AcView.acViewPreview)

    ' Maximize the report window:
    oAccess.DoCmd.Maximize()

    ' Hide Access menu bar:
    oAccess.CommandBars("Menu Bar").Enabled = False

    ' Hide Report's Print Preview menu bar:
    oAccess.CommandBars("Print Preview").Enabled = False

    ' Hide Report's right-click popup menu:
    oAccess.CommandBars("Print Preview Popup").Enabled = False

    ' Release Application object and allow Access to be closed by user:
    If Not oAccess.UserControl Then oAccess.UserControl = True
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorCleanup:
    ' Try to quit Access due to an unexpected error:
    On Error Resume Next
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
    oForm = Nothing
    oAccess.Quit(Option:=Access.AcQuitOption.acQuitSaveNone)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorHandler:
    MsgBox(Err.Number & ": " & Err.Description, _
    MsgBoxStyle.MsgBoxSetForeground, "Error Handler")
    Resume ErrorCleanup
    End Sub

    Private Sub Show_Form()
    'Shows the "Customer Labels Dialog" form in Northwind.mdb
    'and manipulates controls on the form.

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oAccess As Access.Application
    Dim oForm As Access.Form
    Dim oCtls As Access.Controls
    Dim oCtl As Access.Control
    Dim sDBPath As String 'path to Northwind.mdb
    Dim sForm As String 'name of form to show

    sForm = "Customer Labels Dialog"

    ' Start a new instance of Access for Automation:
    oAccess = New Access.ApplicationClass()

    ' Make sure Access is visible:
    If Not oAccess.Visible Then oAccess.Visible = True

    ' Determine the path to Northwind.mdb:
    sDBPath = oAccess.SysCmd(Action:=Access.AcSysCmdAction.acSysCmdAccessDir)
    sDBPath = sDBPath & "Samples\Northwind.mdb"

    ' Open Northwind.mdb in shared mode:
    oAccess.OpenCurrentDatabase(filepath:=sDBPath, Exclusive:=False)

    ' Close any forms that Northwind may have opened:
    For Each oForm In oAccess.Forms
    oAccess.DoCmd.Close(ObjectType:=Access.AcObjectType.acForm, _
    ObjectName:=oForm.Name, _
    Save:=Access.AcCloseSave.acSaveNo)
    Next
    If Not oForm Is Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
    End If
    oForm = Nothing

    ' Select the form name in the database window and give focus
    ' to the database window:
    oAccess.DoCmd.SelectObject(ObjectType:=Access.AcObjectType.acForm, _
    ObjectName:=sForm, InDatabaseWindow:=True)

    ' Show the form:
    oAccess.DoCmd.OpenForm(FormName:=sForm, _
    View:=Access.AcFormView.acNormal)

    ' Use Controls collection to edit the form:
    oForm = oAccess.Forms(sForm)
    oCtls = oForm.Controls

    ' Set PrintLabelsFor option group to Specific Country:
    oCtl = oCtls.Item("PrintLabelsFor")
    oCtl.Value = 2 'second option in option group
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtl)
    oCtl = Nothing

    ' Put USA in the SelectCountry combo box:
    oCtl = oCtls.Item("SelectCountry")
    oCtl.Enabled = True
    oCtl.SetFocus()
    oCtl.Value = "USA"
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtl)
    oCtl = Nothing

    ' Hide the Database Window:
    oAccess.DoCmd.SelectObject(ObjectType:=Access.AcObjectType.acForm, _
    ObjectName:=sForm, InDatabaseWindow:=True)
    oAccess.RunCommand(Command:=Access.AcCommand.acCmdWindowHide)

    ' Set focus back to the form:
    oForm.SetFocus()

    ' Release Controls and Form objects:
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtls)
    oCtls = Nothing
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
    oForm = Nothing

    ' Release Application object and allow Access to be closed by user:
    If Not oAccess.UserControl Then oAccess.UserControl = True
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorCleanup:
    ' Try to quit Access due to an unexpected error:
    On Error Resume Next
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtl)
    oCtl = Nothing
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oCtls)
    oCtls = Nothing
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
    oForm = Nothing
    oAccess.Quit(Option:=Access.AcQuitOption.acQuitSaveNone)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorHandler:
    MsgBox(Err.Number & ": " & Err.Description, _
    MsgBoxStyle.MsgBoxSetForeground, "Error Handler")
    Resume ErrorCleanup
    End Sub

    Private Sub Print_Report_Security()
    'Shows how to automate Access when user-level
    'security is enabled and you wish to avoid the Logon
    'dialog asking for user name and password. In this
    'example we're assuming default security so we simply
    'pass the Admin user with a blank password to print the
    '"Summary of Sales by Year" report in Northwind.mdb.

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oAccess As Access.Application
    Dim sDBPath As String 'path to Northwind.mdb
    Dim sUser As String 'user name for Access security
    Dim sPwd As String 'user password for Access security
    Dim sReport As String 'name of report to print

    sReport = "Summary of Sales by Year"

    ' Determine the path to Northwind.mdb:
    sDBPath = GetOfficeAppPath("Access.Application", "msaccess.exe")
    If sDBPath = "" Then
    MsgBox("Can't determine path to msaccess.exe", _
    MsgBoxStyle.MsgBoxSetForeground)
    Exit Sub
    End If
    sDBPath = Microsoft.VisualBasic.Left(sDBPath, _
    Len(sDBPath) - Len("msaccess.exe")) & "Samples\Northwind.mdb"
    If Not System.IO.File.Exists(sDBPath) Then
    MsgBox("Can't find the file '" & sDBPath & "'", _
    MsgBoxStyle.MsgBoxSetForeground)
    Exit Sub
    End If

    ' Specify the user name and password for the Access workgroup
    ' information file, which is used to implement Access user-level security.
    ' The file by default is named System.mdw and can be specified
    ' using the /wrkgrp command-line switch. This example assumes
    ' default security and therefore does not specify a workgroup
    ' information file and uses Admin with no password:
    sUser = "Admin"
    sPwd = ""

    ' Start a new instance of Access with user name and password:
    oAccess = ShellGetDB(sDBPath, "/user " & sUser & " /pwd " & sPwd)
    'or
    'oAccess = ShellGetApp(Chr(34) & sDBPath & Chr(34) & " /user " & sUser & " /pwd " & sPwd)

    ' Select the report name in the database window and give focus
    ' to the database window:
    oAccess.DoCmd.SelectObject(ObjectType:=Access.AcObjectType.acReport, _
    ObjectName:=sReport, InDatabaseWindow:=True)

    ' Print the report:
    oAccess.DoCmd.OpenReport(ReportName:=sReport, _
    View:=Access.AcView.acViewNormal)

    Cleanup:
    ' Quit Access and release object:
    On Error Resume Next
    oAccess.Quit(Option:=Access.AcQuitOption.acQuitSaveNone)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorHandler:
    MsgBox(Err.Number & ": " & Err.Description, _
    MsgBoxStyle.MsgBoxSetForeground, "Error Handler")
    ' Try to quit Access due to an unexpected error:
    Resume Cleanup
    End Sub

    Private Sub Preview_Report_Runtime()
    'Shows how to automate the Access Runtime to preview
    'the "Summary of Sales by Year" report in Northwind.mdb.

    ' Enable an error handler for this procedure:
    On Error GoTo ErrorHandler

    Dim oAccess As Access.Application
    Dim oForm As Access.Form
    Dim sDBPath As String 'path to Northwind.mdb
    Dim sReport As String 'name of report to preview

    sReport = "Summary of Sales by Year"

    ' Determine the path to Northwind.mdb:
    sDBPath = GetOfficeAppPath("Access.Application", "msaccess.exe")
    If sDBPath = "" Then
    MsgBox("Can't determine path to msaccess.exe", _
    MsgBoxStyle.MsgBoxSetForeground)
    Exit Sub
    End If
    sDBPath = Microsoft.VisualBasic.Left(sDBPath, _
    Len(sDBPath) - Len("msaccess.exe")) & "Samples\Northwind.mdb"
    If Not System.IO.File.Exists(sDBPath) Then
    MsgBox("Can't find the file '" & sDBPath & "'", _
    MsgBoxStyle.MsgBoxSetForeground)
    Exit Sub
    End If

    ' Start a new instance of Access. If the retail
    ' version of Access is not installed, and only the
    ' Access Runtime is installed, launches a new instance
    ' of the Access Runtime (/runtime switch is optional):
    oAccess = ShellGetDB(sDBPath, "/runtime")
    'or
    'oAccess = ShellGetApp(Chr(34) & sDBPath & Chr(34) & " /runtime")

    ' Make sure Access is visible:
    If Not oAccess.Visible Then oAccess.Visible = True

    ' Close any forms that Northwind may have opened:
    For Each oForm In oAccess.Forms
    oAccess.DoCmd.Close(ObjectType:=Access.AcObjectType.acForm, _
    ObjectName:=oForm.Name, _
    Save:=Access.AcCloseSave.acSaveNo)
    Next
    If Not oForm Is Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
    End If
    oForm = Nothing

    ' Select the report name in the database window and give focus
    ' to the database window:
    oAccess.DoCmd.SelectObject(ObjectType:=Access.AcObjectType.acReport, _
    ObjectName:=sReport, InDatabaseWindow:=True)

    ' Maximize the Access window:
    oAccess.RunCommand(Command:=Access.AcCommand.acCmdAppMaximize)

    ' Preview the report:
    oAccess.DoCmd.OpenReport(ReportName:=sReport, _
    View:=Access.AcView.acViewPreview)

    ' Maximize the report window:
    oAccess.DoCmd.Maximize()

    ' Hide Access menu bar:
    oAccess.CommandBars("Menu Bar").Enabled = False

    ' Release Application object and allow Access to be closed by user:
    If Not oAccess.UserControl Then oAccess.UserControl = True
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorCleanup:
    ' Try to quit Access due to an unexpected error:
    On Error Resume Next
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oForm)
    oForm = Nothing
    oAccess.Quit(Option:=Access.AcQuitOption.acQuitSaveNone)
    System.Runtime.InteropServices.Marshal.ReleaseComObject(oAccess)
    oAccess = Nothing

    Exit Sub
    ErrorHandler:
    MsgBox(Err.Number & ": " & Err.Description, _
    MsgBoxStyle.MsgBoxSetForeground, "Error Handler")
    Resume ErrorCleanup
    End Sub

  9. Agregue el código siguiente al principio de Form1.vb:
    Imports Microsoft.Office.Interop
  10. Presione F5 para generar y ejecutar el programa.
  11. Haga clic en Imprimir informey, a continuación, haga clic en Ir!. El procedimiento Print_Report imprimirá un informe de la base de datos Northwind.
  12. Haga clic en vista previa del informey, a continuación, haga clic en Ir!. El procedimiento Preview_Report ofrecerá una muestra una vista previa de un informe de la base de datos Northwind. Cierre la instancia de Access cuando esté listo para continuar.
  13. Haga clic en Mostrar el formulario y, a continuación, haga clic en Ir!. El procedimiento Show_Form mostrará el formulario de diálogo etiquetas de cliente de la base de datos Northwind. También establece el grupo de opciones del formulario en "País específico" y seleccionará "EE" de la lista. Cierre la instancia de Access cuando esté listo para continuar.
  14. Haga clic en Print report (Security)y, a continuación, haga clic en Ir!. El procedimiento Print_Report_Security muestra cómo automatizar Access y cómo evitar el cuadro de diálogo de inicio de sesión si está activada la seguridad a nivel de usuario. En este ejemplo, se supone el inicio de sesión predeterminado pasando el usuario Admin con una contraseña en blanco. El código, a continuación, imprime un informe en la base de datos Northwind.
  15. Haga clic en Preview report (Runtime)y, a continuación, haga clic en Ir!. El procedimiento Preview_Report_Runtime muestra cómo automatizar Access Runtime para obtener una vista previa de un informe en la base de datos Northwind. Si se instala la versión comercial de Access, el procedimiento funcionará correctamente. Cuando esté listo para continuar, cierre la instancia de Access.

REFERENCIAS

Para obtener más información, consulte el siguiente sitio Web de Microsoft Developer Network (MSDN):
Desarrollo de Microsoft Office con Visual Studio
http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspx
Para obtener información adicional, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:
317157 PRB: errores al hacer referencia a la biblioteca de tipos de Access 10.0
317109 PRB: aplicación de Office no cierra después de automatización
308409 PRB: Error 429 en tiempo de ejecución utilizando GetObject para la aplicación de Office
244695 BUG: Error 2046 llamada AbrirFormulario o AbrirInforme automatizar Access
304661 cómo utilizar Visual Basic .NET para el enlace de los servidores de automatización de Office
302281 cómo utilizar VB.Net para obtener el identificador de ventana de Office Server
306682 cómo ejecutar Macros de Office mediante automatización desde Visual Basic .NET
Propiedades

Id. de artículo: 317113 - Última revisión: 17 ene. 2017 - Revisión: 2

Comentarios