automatizar access con c#

27
En este artículo se muestra cómo automatizar Microsoft Access mediante Microsoft Visual C# 2005 o Microsoft Visual C#. NET. Los temas y el código de ejemplo le enseñarán cómo: Abrir una base de datos en Access. Imprimir u obtener una vista previa de un informe de Access. Mostrar y editar un formulario de Access. Evitar los cuadros de diálogo cuando abra una base de datos protegida mediante contraseña o cuando esté activada la seguridad a nivel de usuario. Automatizar el tiempo de ejecución de Access. Volver al principio Automatización frente a ADO.NET Un desarrollador puede trabajar con una base de datos Microsoft Access desde Visual C# 2005 o Visual C# .NET utilizando dos tecnologías diferentes: automatización y Microsoft ADO.NET. ADO.NET será la tecnología indicada para trabajar con objetos de datos, como, por ejemplo, tablas y consultas de una base de datos de Access. La automatización únicamente deberá utilizarse en caso de que se requieran funciones específicas de Microsoft Access, tales como imprimir u obtener una vista previa de un informe, mostrar un formulario o llamar a macros. Se explica cómo automatizar Access. El artículo no trata ADO.NET. Para obtener información sobre ADO.NET, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base: 306636 Cómo conectarse a una base de datos y ejecutar un comando mediante ADO 2005 y Visual C# 2005 o mediante ADO.NET y Visual C# .NET 314145 Cómo llenar un objeto DataSet desde una base de datos mediante Visual C# .NET 307587 Cómo actualizar una base de datos de un objeto DataSet mediante Visual C# 2005 o Visual C# .NET Automatización es un modelo de objetos de componentes (COM) tecnología. La automatización permite que aplicaciones escritas en lenguajes como Visual C# .NET controlar otras aplicaciones mediante programación. Cuando automatiza una aplicación de Microsoft Office, se ejecutar realmente una instancia de la aplicación en la memoria y, a continuación, llamar a en del modelo de objetos de aplicación para realizar diversas tareas en esa aplicación. Con Access y otras aplicaciones de Microsoft Office, prácticamente todas las acciones ejecutables manualmente desde la interfaz de usuario pueden ser realizadas también mediante programación utilizando la automatización. Access expone esta función de programación por medio de un modelo de objetos. 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 Access. Para tener acceso al modelo de objetos desde Visual C# .NET, puede configurar una referencia de proyecto a la biblioteca de tipos. Para obtener más información sobre este proceso o sobre la documentación del modelo de objetos para Office, haga clic en el siguiente número de artículo para verlo en Microsoft Knowledge Base: 222101 Cómo encontrar y utilizar la documentación del modelo de objetos de Office

Upload: keelmii-woolf

Post on 14-Apr-2015

169 views

Category:

Documents


9 download

TRANSCRIPT

Page 1: Automatizar Access Con c#

En este artículo se muestra cómo automatizar Microsoft Access mediante Microsoft Visual C# 2005 o Microsoft Visual C#. NET. Los temas y el código de ejemplo le enseñarán cómo:

Abrir una base de datos en Access.

Imprimir u obtener una vista previa de un informe de Access.

Mostrar y editar un formulario de Access.

Evitar los cuadros de diálogo cuando abra una base de datos protegida mediante

contraseña o cuando esté activada la seguridad a nivel de usuario.

Automatizar el tiempo de ejecución de Access.Volver al principio

Automatización frente a ADO.NETUn desarrollador puede trabajar con una base de datos Microsoft Access desde Visual C# 2005 o Visual C# .NET utilizando dos tecnologías diferentes: automatización y Microsoft ADO.NET.

ADO.NET será la tecnología indicada para trabajar con objetos de datos, como, por ejemplo, tablas y consultas de una base de datos de Access. La automatización únicamente deberá utilizarse en caso de que se requieran funciones específicas de Microsoft Access, tales como imprimir u obtener una vista previa de un informe, mostrar un formulario o llamar a macros.

Se explica cómo automatizar Access. El artículo no trata ADO.NET. Para obtener información sobre ADO.NET, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:

306636  Cómo conectarse a una base de datos y ejecutar un comando mediante ADO 2005 y

Visual C# 2005 o mediante ADO.NET y Visual C# .NET

314145  Cómo llenar un objeto DataSet desde una base de datos mediante Visual C# .NET

307587  Cómo actualizar una base de datos de un objeto DataSet mediante Visual C# 2005 o

Visual C# .NETAutomatización es un modelo de objetos de componentes (COM) tecnología. La automatización permite que aplicaciones escritas en lenguajes como Visual C# .NET controlar otras aplicaciones mediante programación. Cuando automatiza una aplicación de Microsoft Office, se ejecutar realmente una instancia de la aplicación en la memoria y, a continuación, llamar a en del modelo de objetos de aplicación para realizar diversas tareas en esa aplicación. Con Access y otras aplicaciones de Microsoft Office, prácticamente todas las acciones ejecutables manualmente desde la interfaz de usuario pueden ser realizadas también mediante programación utilizando la automatización.

Access expone esta función de programación por medio de un modelo de objetos. 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 Access. Para tener acceso al modelo de objetos desde Visual C# .NET, puede configurar una referencia de proyecto a la biblioteca de tipos. Para obtener más información sobre este proceso o sobre la documentación del modelo de objetos para Office, haga clic en el siguiente número de artículo para verlo en Microsoft Knowledge Base:

222101  Cómo encontrar y utilizar la documentación del modelo de objetos de OfficeVolver al principio

Tareas comunes de automatización

Abrir una base de datos en Access

En la automatización de Microsoft Access, antes de poder realizar tareas útiles, como, por ejemplo, imprimir informes, será necesario abrir una base de datos. Para abrir una base de datos en la instancia de Access está automatizando, utilice los métodos de método OpenCurrentDatabase o OpenAccessProject del objetoApplication . Sólo podrá tener abierta en Access una base de datos a la vez. Para trabajar con una base de datos diferente, puede utilizar el método CloseCurrentDatabase antes de abrir otra.

También puede utilizar el System.Runtime.InteropServices.Marshal.BindToMoniker (<

Page 2: Automatizar Access Con c#

ruta de acceso a base de datos >) método para abrir una base de datos en una instancia de Access. Si la base de datos ya está abierto en una instancia de Access, BindToMoniker devuelve el objeto Application de esa instancia. De lo contrario, BindToMoniker inicia una nueva instancia de Access y abre la base de datos especificado.OpenCurrentDatabase es el método preferido para abrir una base de datos, porque especifica la instancia de Access que está automatizando. También puede proporcionar argumentos para controlar cómo se abre la base de datos, por ejemplo:

Access.Application oAccess = null;

// Start a new instance of Access for Automation:oAccess = new Access.ApplicationClass();

// Open a database in exclusive mode:oAccess.OpenCurrentDatabase( "c:\\mydb.mdb", //filepath true //Exclusive );

Imprimir u obtener una vista previa de un informe de Access

Para obtener una vista previa o imprimir un informe de Access, llamar al método OpenReport del objetoDoCmd . Cuando se llama a OpenReport , uno de los argumentos que pasa determina si el informe de vista previa en la pantalla, o si se envía a la impresora:

// Preview a report named Sales:oAccess.DoCmd.OpenReport( "Sales", //ReportName Access.AcView.acViewPreview, //View System.Reflection.Missing.Value, //FilterName System.Reflection.Missing.Value //WhereCondition );

// Print a report named Sales:oAccess.DoCmd.OpenReport( "Sales", //ReportName Access.AcView.acViewNormal, //View System.Reflection.Missing.Value, //FilterName System.Reflection.Missing.Value //WhereCondition );

aviso que el argumento vista determina si se muestra el informe en Access o si se envía a la impresora. El argumento WhereCondition puede limitar el conjunto de registros del informe, si utiliza un SQL válido cláusula WHERE (sin la palabra WHERE.) Observe que puede utilizar System.Reflection.Missing.Value para omitir los parámetros de objeto que son opcionales.

Si Vista previa 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 podrá ver el informe en la ventana de Access.

Hay otra forma para imprimir un informe u otros objetos en la base de datos. Utilice el método PrintOut del objeto DoCmd . En este ejemplo, seleccione un informe llamado a empleados en la ventana base de datos y, a continuación, llamar a Imprimir para imprimir el

Page 3: Automatizar Access Con c#

objeto seleccionado. El método PrintOut permite proporcionar argumentos que corresponden al cuadro de diálogo impresión en Access:

// Select the Employees report in the database window:oAccess.DoCmd.SelectObject( Access.AcObjectType.acReport, //ObjectType "Employees", //ObjectName true //InDatabaseWindow );

// Print 2 copies of the selected object:oAccess.DoCmd.PrintOut( Access.AcPrintRange.acPrintAll, //PrintRange System.Reflection.Missing.Value, //PageFrom System.Reflection.Missing.Value, //PageTo Access.AcPrintQuality.acHigh, //PrintQuality 2, //Copies false //CollateCopies );

O, en algunos casos, quizás desee utilizar métodos Imprimir y de la AbrirInforme para imprimir un informe. Supongamos que desea imprimir varias copias del informe Employees, pero sólo para un empleado concreto. En este ejemplo primero se utiliza OpenReport para abrir el informe empleados en modo de vista previa, con el argumento WhereCondition para limitar los registros para un empleado específico. A continuación, Imprimir se utiliza para imprimir varias copias del objeto activo:

// Open the report in preview mode using a WhereCondition:oAccess.DoCmd.OpenReport( "Employees", //ReportName Access.AcView.acViewPreview, //View System.Reflection.Missing.Value, //FilterName "[EmployeeID]=1" //WhereCondition );

// Print 2 copies of the active object: oAccess.DoCmd.PrintOut( Access.AcPrintRange.acPrintAll, //PrintRange System.Reflection.Missing.Value, //PageFrom System.Reflection.Missing.Value, //PageTo Access.AcPrintQuality.acHigh, //PrintQuality 2, //Copies false //CollateCopies );

// Close the report preview window: oAccess.DoCmd.Close( Access.AcObjectType.acReport, //ObjectType "Employees", //ObjectName Access.AcCloseSave.acSaveNo //Save );

Page 4: Automatizar Access Con c#

Access 2002 se introdujo el objeto Printer . Puede utilizar este objeto para personalizar configuración de impresora de acceso más fácilmente que en versiones anteriores de Access. Para obtener un ejemplo del uso del objeto de impresora para imprimir un informe en Access, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

284286  Cómo restablecer los cambios al objeto Application.Printer

Mostrar y editar un formulario de Access

Visual C# .NET tiene capacidades de forma muy eficaz. Habrá casos, sin embargo, en que los usuarios deban ver formularios desarrollados en Access. O bien, puede tener un formulario en la base de datos Access que proporciona criterios para una consulta o un informe y debe abrir dicho formulario antes de poder obtener una vista previa o imprimir el informe. Para abrir y mostrar un formulario de Access, llame al método OpenFormdel objeto DoCmd :

// Show a form named Employees:oAccess.DoCmd.OpenForm( "Employees", //FormName Access.AcFormView.acNormal, //View System.Reflection.Missing.Value, //FilterName System.Reflection.Missing.Value, //WhereCondition Access.AcFormOpenDataMode.acFormPropertySettings, //DataMode Access.AcWindowMode.acWindowNormal, //WindowMode System.Reflection.Missing.Value //OpenArgs );

ahora puede editar los controles en el formulario.

Volver al principio

Cuadros de diálogo de seguridad de AccessAl automatizar Access, se le pedirá que escriba un nombre de usuario o una contraseña o ambos, cuando intenta abrir una base de datos. Si el usuario escribe información incorrecta, se producirá un error en el código. En ocasiones, tal vez prefiera evitar estos cuadros de diálogo y, en su lugar, proporcionar el nombre de usuario y la contraseña mediante programación para que el código de automatización se ejecute sin interrupciones.

En Microsoft Access existen dos tipos de seguridad: bases de datos protegidas mediante contraseña y seguridad a nivel de usuario mediante un archivo de grupos de trabajo (System.mdw). Si está intentando abrir una base de datos que está protegido por contraseña, aparecerá un cuadro de diálogo 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 se activa la seguridad de nivel de usuario, Access muestra un cuadro de diálogo Inicio de sesión preguntar un nombre de usuario y contraseña antes de abrir cualquier base de datos, en Access. Para obtener más información sobre la seguridad en Access y el archivo de información de grupos de trabajo, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

305542  Información para comprender la función de los archivos de información de grupo de

trabajo en seguridad

Evitar los cuadros de diálogo de contraseña en las bases de datos

Si va a abrir una base de datos que se ha protegido con una contraseña, puede evitar el cuadro de diálogo proporcionando la contraseña para el método OpenCurrentDatabase :

// Open a password-protected database in shared mode:

Page 5: Automatizar Access Con c#

// Note: The bstrPassword argument is case-sensitiveoAccess.OpenCurrentDatabase( "c:\\mydb.mdb", //filepath false, //Exclusive "MyPassword" //bstrPassword );

Aquí es un ejemplo donde oAccess se ha establecido previamente a una instancia de Access que no tiene abierta una base de datos. Este código proporciona la contraseña para la base de datos para evitar un cuadro de diálogo:

string sDBPassword = "MyPassword"; //database passwordDAO._DBEngine oDBEngine = oAccess.DBEngine;DAO.Database oDB = oDBEngine.OpenDatabase("c:\\mydb.mdb", false, false, ";PWD=" + sDBPassword);oAccess.OpenCurrentDatabase("c:\\mydb.mdb", false);oDB.Close();System.Runtime.InteropServices.Marshal.ReleaseComObject(oDB);oDB = null;System.Runtime.InteropServices.Marshal.ReleaseComObject(oDBEngine);oDBEngine = null;

el oDB.Close no cierra realmente la base de datos de Access. Sólo cierra la conexión de DAO con la base de datos que se realizó a través del objeto DBEngine . Ya no es necesaria la conexión de DAO después de utiliza el método OpenCurrentDatabase . Observe el código que libera los objetos oDB y oDBEngine. Estos objetos deberán utilizarse para que Access pueda cerrarse correctamente una vez se haya 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  Cómo abrir una base de datos protegida con contraseña mediante automatización en

Access 2000

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

Si está activada la seguridad de nivel de usuario en Access, el usuario se le pide un cuadro de diálogo de inicio de sesión, pide un nombre de usuario y una contraseña. Con el modelo de objetos de Access no es posible especificar nombres de usuario o contraseñas. Por tanto, si desea evitar el cuadro de diálogo de inicio de sesión al automatizar Access, primero deberá iniciar el archivo Msaccess.exe y proporcionar los modificadores de la línea de comandos /user y /pwd para especificar el nombre de usuario y la contraseña. Posteriormente, puede utilizar GetActiveObject o BindToMoniker para recuperar el objeto Application de la instancia en ejecución de Access, de modo que, a continuación, puede continuar con la automatización. Para obtener un ejemplo de este procedimiento, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

192919  Cómo automatizar una base de datos acceso seguro mediante Visual BasicPara obtener más información sobre cómo iniciar Access con modificadores de la 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 AccessVolver al principio

Automatizar los archivos en tiempo de ejecución de Access

Page 6: Automatizar Access Con c#

Microsoft Office Developer Edition incluye las Microsoft Office Developer Tools (MOD). Las MOD permiten a los programadores de Access crear aplicaciones de Access y distribuirlas a usuarios que no tengan la versión comercial del programa. Cuando éstos las instalen en un equipo sin la versión comercial, se instalarán además los archivos en tiempo de ejecución de Access. Estos archivos quedarán instalados y registrados de igual forma que la versión comercial. El ejecutable también se denominará Msaccess.exe. El tiempo de ejecución de Access permite una aplicación de Access que se ejecute en un equipo cliente, pero el tiempo de ejecución de Access no permite que un usuario para desarrollar nuevas aplicaciones o modificar el diseño de las aplicaciones existentes. 

Los archivos en tiempo de ejecución de Access deberán iniciarse con una base de datos. Debido a este requisito, si desea automatizarlos, deberá iniciar Msaccess.exe y especificar la base de datos que se ha de abrir. Después de utilizar GetActiveObject o BindToMoniker para recuperar el objeto Application , a continuación, puede automatizar el tiempo de ejecución de Access. Si no utiliza este enfoque al intentar automatizar Access Runtime, recibirá un mensaje de error such as lo siguiente cuando intenta crear la instancia:

System.Runtime.InteropServices.COMException (0 x 80080005)

Error de ejecución de servidor.

Para obtener más información, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:

295179  Utilizando la automatización provoca un error en tiempo de ejecución cuando sólo

Microsoft Access Runtime está instalada en un equipoVolver al principio

Crear el ejemplo completo Visual C# 2005 o proyecto de Visual C# .NETAntes de utilizar el siguiente ejemplo paso a paso, compruebe que tiene instalada la base de datos de ejemplo Neptuno. De forma predeterminada, Microsoft Access 2000 instala las bases de datos de ejemplo en la ruta de acceso siguiente:

C:\Archivos de programa\Microsoft Office\Office\EjemplosMicrosoft Access 2002 usa la ruta de acceso siguiente:

C:\Archivos de programa\Microsoft Office\Office10\EjemplosMicrosoft Office Access 2003 utiliza la ruta de acceso siguiente:

C:\Archivos programa\Microsoft Office\Office11\SamplesPara asegurarse de que está instalada la base de datos Neptuno en Access 2002 o en Access 2003, haga clic enBases de datos de ejemplo en el menú Ayuda y haga clic en Datos de ejemplo Northwind .

1. Cierre cualquier instancia de Access que se esté ejecutando.

2. Inicie Microsoft Visual Studio NET..

3. En el menú archivo , haga clic en nuevo y, a continuación, haga clic en proyecto .

SeleccioneAplicación para Windows de los tipos de proyecto de Visual C#. De forma

predeterminada, se crea Form1.

Nota Debe cambiar el código en Visual Studio 2005. De forma predeterminada, C#

agrega un formulario al proyecto cuando se crea un proyecto de formularios Windows

Forms. El formulario se denomina Form1. Los dos archivos que representan el formulario

se denominan Form1.cs y Form1.Designer.cs. Escribir el código en Form1.cs. El archivo

de Form1.Designer.cs es donde el Diseñador de Windows Forms escribe el código que

implementa todas las acciones que realizó arrastrando y colocando controles desde el

cuadro de herramientas. 

Para obtener más información acerca del Diseñador de Windows Forms en Visual C#

2005, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):

Page 7: Automatizar Access Con c#

http://msdn2.microsoft.com/en-us/library/ms173077.aspx

4. Agregue una referencia a la Biblioteca de objetos de Access . Para ello, siga estos

pasos:

a. En el menú proyecto , haga clic en Agregar referencia .

b. En la ficha COM , busque la Biblioteca de objetos de Microsoft Access y a

continuación, haga clic en seleccionar .

Nota En Visual Studio 2005. no es necesario haga clic en Seleccionar .

Nota Microsoft Office 2003 incluye a ensamblados de interoperabilidad primarios

(PIA). Microsoft Office XP no incluye PIA, pero pueden descargar. Para obtener más

información acerca de los PIA de Office XP, haga clic en el número de artículo

siguiente para verlo en Microsoft Knowledge Base:

328912  Microsoft Office XP ensamblados de interoperabilidad primarios (PIA)

están disponibles para descarga

c. En el cuadro de diálogo Agregar referencias , haga clic en Aceptar para

aceptar sus selecciones.

Nota Si hace referencia a la biblioteca de objeto Access 10.0 y recibe errores

cuando intenta agregar la referencia, haga clic en el número de artículo siguiente

para verlo en Microsoft Knowledge Base::

317157  PRB: Errores cuando se hace referencia la 10.0 Access escriba biblioteca

con Visual Studio.NET

En el menú Ver , haga clic en cuadro de herramientas para mostrar el cuadro de

herramientas.

Agregue cinco controles de botón de radio y control de un botón a Form1.

Seleccione todos los controles de botón de opción y, a continuación, establezca la

propiedad Size a150,24 .

Agregue controladores de eventos para el evento Form Load y para el evento Click del

control Button:

a. En la vista Diseño de Form1.cs, haga doble clic en Form1 . 

El controlador del evento de Load del formulario se crea y aparece en Form1.cs.

b. En el menú Ver , haga clic en el Diseñador para cambiar a la vista Diseño.

c. Haga doble clic en Button1 . 

El controlador del evento Click del botón se crea y aparece en Form1.cs.

In Form1.cs, replace the following code

private void Form1_Load(object sender, System.EventArgs e){

}

private void button1_Click(object sender, System.EventArgs e){

}

Page 8: Automatizar Access Con c#

with:

private string msAction = null; // Commonly-used variable for optional arguments: private object moMissing = System.Reflection.Missing.Value;

private void Form1_Load(object sender, System.EventArgs e) { 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!"; radioButton1.Click += new EventHandler(RadioButtons_Click); radioButton2.Click += new EventHandler(RadioButtons_Click); radioButton3.Click += new EventHandler(RadioButtons_Click); radioButton4.Click += new EventHandler(RadioButtons_Click); radioButton5.Click += new EventHandler(RadioButtons_Click); }

private void RadioButtons_Click(object sender, System.EventArgs e) { RadioButton radioBtn = (RadioButton) sender; msAction = radioBtn.Text; }

private void button1_Click(object sender, System.EventArgs e) { // Calls the associated procedure to automate Access, based // on the selected radio button on the form. switch(msAction) { case "Print report": Print_Report(); break; case "Preview report": Preview_Report(); break; case "Show form": Show_Form(); break; case "Print report (Security)": Print_Report_Security(); break;

Page 9: Automatizar Access Con c#

case "Preview report (Runtime)": Preview_Report_Runtime(); break; } }

private void NAR(object o) { // Releases the Automation object. try // use try..catch in case o is not set { Marshal.ReleaseComObject(o); } catch{} }

private Access.Application ShellGetDB(string sDBPath, string sCmdLine, ProcessWindowStyle enuWindowStyle, int iSleepTime) { //Launches a new instance of Access with a database (sDBPath) //using System.Diagnostics.Process.Start. Then, returns the //Application object via calling: BindToMoniker(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 //before calling this function. // //Example: //Access.Application oAccess = null; //oAccess = ShellGetDB("c:\\mydb.mdb", null, // ProcessWindowStyle.Minimized, 1000);

Access.Application oAccess = null; string sAccPath = null; //path to msaccess.exe Process p = null;

// Enable exception handler: try

Page 10: Automatizar Access Con c#

{ // Obtain the path to msaccess.exe: sAccPath = GetOfficeAppPath("Access.Application", "msaccess.exe"); if (sAccPath == null)

{ MessageBox.Show("Can't determine path to msaccess.exe"); return null; }

// Make sure specified database (sDBPath) exists: if(!System.IO.File.Exists(sDBPath)) { MessageBox.Show("Can't find the file '" + sDBPath + "'"); return null; }

// Start a new instance of Access passing sDBPath and sCmdLine: if(sCmdLine == null) sCmdLine = @"""" + sDBPath + @""""; else sCmdLine = @"""" + sDBPath + @"""" + " " + sCmdLine; ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = sAccPath; startInfo.Arguments = sCmdLine; startInfo.WindowStyle = enuWindowStyle; p = Process.Start(startInfo); p.WaitForInputIdle(60000); //max 1 minute wait for idle input state

// Move focus back to this form. This ensures that Access // registers itself in the ROT: this.Activate();

// Pause before trying to get Application object: System.Threading.Thread.Sleep(iSleepTime);

// Obtain Application object of the instance of Access // that has the database open: oAccess = (Access.Application) Marshal.BindToMoniker(sDBPath); return oAccess; }

Page 11: Automatizar Access Con c#

catch(Exception e) { MessageBox.Show(e.Message); // Try to quit Access due to an unexpected error: try // use try..catch in case oAccess is not set { oAccess.Quit(Access.AcQuitOption.acQuitSaveNone); } catch{} NAR(oAccess); oAccess = null; return null; } }

private Access.Application ShellGetApp(string sCmdLine, ProcessWindowStyle enuWindowStyle) { //Launches a new instance of Access using System.Diagnostics. //Process.Start then returns the Application object via calling: //GetActiveObject("Access.Application"). If an instance of //Access is already running before calling this function, //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 Q316125. // //Examples: //Access.Application oAccess = null; //oAccess = ShellGetApp("/nostartup", // ProcessWindowStyle.Minimized); // //-or- // //Access.Application oAccess = null; //string sUser = "Admin"; //string sPwd = "mypassword"; //oAccess = ShellGetApp("/nostartup /user " + sUser + "/pwd " + sPwd, // ProcessWindowStyle.Minimized);

Access.Application oAccess = null; string sAccPath = null; //path to msaccess.exe Process p = null;

Page 12: Automatizar Access Con c#

int iMaxTries = 20; //max GetActiveObject attempts before failing int iTries = 0; //GetActiveObject attempts made

// Enable exception handler: try { // Obtain the path to msaccess.exe: sAccPath = GetOfficeAppPath("Access.Application", "msaccess.exe"); if(sAccPath == null) { MessageBox.Show("Can't determine path to msaccess.exe"); return null; }

// Start a new instance of Access passing sCmdLine: ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = sAccPath; startInfo.Arguments = sCmdLine; startInfo.WindowStyle = enuWindowStyle; p = Process.Start(startInfo); p.WaitForInputIdle(60000); //max 1 minute wait for idle input state

// Move focus back to this form. This ensures that Access // registers itself in the ROT: this.Activate();

tryGetActiveObject: // Enable exception handler: try { // Attempt to use GetActiveObject to reference a running // instance of Access: oAccess = (Access.Application) Marshal.GetActiveObject("Access.Application"); } catch { //GetActiveObject may have failed because enough time has not //elapsed to find the running Office application. Wait 1/2

Page 13: Automatizar Access Con c#

//second and retry the GetActiveObject. If you try iMaxTries //times and GetActiveObject still fails, assume some other //reason for GetActiveObject failing and exit the procedure. iTries++; if(iTries < iMaxTries) { System.Threading.Thread.Sleep(500); //wait 1/2 second this.Activate(); goto tryGetActiveObject; } MessageBox.Show("Unable to GetActiveObject after " + iTries + " tries."); return null; }

// Return the Access Application object: return oAccess; } catch(Exception e) { MessageBox.Show(e.Message); // Try to quit Access due to an unexpected error: try // use try..catch in case oAccess is not set { oAccess.Quit(Access.AcQuitOption.acQuitSaveNone); } catch{} NAR(oAccess); oAccess = null; return null; } }

private string GetOfficeAppPath(string sProgId, string sEXE) { //Returns path of the Office application. e.g. //GetOfficeAppPath("Access.Application", "msaccess.exe") returns //full path to Microsoft Access. Approach based on Q240794. //Returns null if path not found in registry.

// Enable exception handler: try

Page 14: Automatizar Access Con c#

{ Microsoft.Win32.RegistryKey oReg = Microsoft.Win32.Registry.LocalMachine; Microsoft.Win32.RegistryKey oKey = null; string sCLSID = null; string sPath = null; int iPos = 0;

// 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("").ToString(); 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("").ToString(); oKey.Close();

// Remove any characters beyond the exe name: iPos = sPath.ToUpper().IndexOf(sEXE.ToUpper()); // 0-based position sPath = sPath.Substring(0, iPos + sEXE.Length); return sPath.Trim(); } catch { return null; } }

private void Print_Report() { // Prints the "Summary of Sales by Year" report in Northwind.mdb.

Access.Application oAccess = null; string sDBPath = null; //path to Northwind.mdb string sReport = null; //name of report to print

// Enable exception handler:

Page 15: Automatizar Access Con c#

try { 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(Access.AcSysCmdAction.acSysCmdAccessDir, moMissing, moMissing).ToString(); sDBPath = sDBPath + @"Samples\Northwind.mdb";

// Open Northwind.mdb in shared mode: oAccess.OpenCurrentDatabase(sDBPath, false, ""); // If using Access 10.0 object library, use this instead: //oAccess.OpenCurrentDatabase(sDBPath, false, null);

// Select the report name in the database window and give focus // to the database window: oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);

// Print the report: oAccess.DoCmd.OpenReport(sReport, Access.AcView.acViewNormal, moMissing, moMissing, Access.AcWindowMode.acWindowNormal, moMissing); // If using Access 10.0 object library, use this instead: //oAccess.DoCmd.OpenReport(sReport, // Access.AcView.acViewNormal, moMissing, moMissing, // Access.AcWindowMode.acWindowNormal, moMissing); } catch(Exception e) { MessageBox.Show(e.Message); } finally { // Release any Access objects and quit Access: try // use try..catch in case oAccess is not set { oAccess.Quit(Access.AcQuitOption.acQuitSaveNone); } catch{}

Page 16: Automatizar Access Con c#

NAR(oAccess); oAccess = null; } }

private void Preview_Report() { // Previews the "Summary of Sales by Year" report in Northwind.mdb.

Access.Application oAccess = null; Access.Form oForm = null; string sDBPath = null; //path to Northwind.mdb string sReport = null; //name of report to preview

// Enable exception handler: try { sReport = "Summary of Sales by Year";

// Start a new instance of Access for Automation: oAccess = new Access.ApplicationClass();

// Make sure Access is visible: if(!oAccess.Visible) oAccess.Visible = true;

// Determine the path to Northwind.mdb: sDBPath = oAccess.SysCmd(Access.AcSysCmdAction.acSysCmdAccessDir, moMissing, moMissing).ToString(); sDBPath = sDBPath + @"Samples\Northwind.mdb";

// Open Northwind.mdb in shared mode: oAccess.OpenCurrentDatabase(sDBPath, false, ""); // If using Access 10.0 object library, use this instead: //oAccess.OpenCurrentDatabase(sDBPath, false, null);

// Close any forms that Northwind may have opened: while(oAccess.Forms.Count > 0) { oForm = oAccess.Forms[0]; oAccess.DoCmd.Close(Access.AcObjectType.acForm, oForm.Name, Access.AcCloseSave.acSaveNo); NAR(oForm); oForm = null; }

Page 17: Automatizar Access Con c#

// Select the report name in the database window and give focus // to the database window: oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);

// Maximize the Access window: oAccess.RunCommand(Access.AcCommand.acCmdAppMaximize);

// Preview the report: oAccess.DoCmd.OpenReport(sReport, Access.AcView.acViewPreview, moMissing, moMissing, Access.AcWindowMode.acWindowNormal, moMissing); // If using Access 10.0 object library, use this instead: //oAccess.DoCmd.OpenReport(sReport, // Access.AcView.acViewPreview, moMissing, moMissing, // Access.AcWindowMode.acWindowNormal, moMissing);

// Maximize the report window: oAccess.DoCmd.Maximize();

// Hide Access menu bar: oAccess.CommandBars["Menu Bar"].Enabled = false; // Also hide NorthWindCustomMenuBar if it is available: try { oAccess.CommandBars["NorthwindCustomMenuBar"].Enabled = false; } catch{}

// 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(!oAccess.UserControl) oAccess.UserControl = true; NAR(oAccess); oAccess = null; } catch(Exception e) {

Page 18: Automatizar Access Con c#

MessageBox.Show(e.Message); // Release any Access objects and quit Access due to error: NAR(oForm); oForm = null; try // use try..catch in case oAccess is not set { oAccess.Quit(Access.AcQuitOption.acQuitSaveNone); } catch{} NAR(oAccess); oAccess = null; } }

private void Show_Form() { // Shows the "Customer Labels Dialog" form in Northwind.mdb // and manipulates controls on the form.

Access.Application oAccess = null; Access.Form oForm = null; Access.Controls oCtls = null; Access.Control oCtl = null; string sDBPath = null; //path to Northwind.mdb string sForm = null; //name of form to show

// Enable exception handler: try { sForm = "Customer Labels Dialog";

// Start a new instance of Access for Automation: oAccess = new Access.ApplicationClass();

// Make sure Access is visible: if(!oAccess.Visible) oAccess.Visible = true;

// Determine the path to Northwind.mdb: sDBPath = oAccess.SysCmd(Access.AcSysCmdAction.acSysCmdAccessDir, moMissing, moMissing).ToString(); sDBPath = sDBPath + @"Samples\Northwind.mdb";

// Open Northwind.mdb in shared mode: oAccess.OpenCurrentDatabase(sDBPath, false, "");

Page 19: Automatizar Access Con c#

// If using Access 10.0 object library, use this instead: //oAccess.OpenCurrentDatabase(sDBPath, false, null);

// Close any forms that Northwind may have opened: while(oAccess.Forms.Count > 0) { oForm = oAccess.Forms[0]; oAccess.DoCmd.Close(Access.AcObjectType.acForm, oForm.Name, Access.AcCloseSave.acSaveNo); NAR(oForm); oForm = null; }

// Select the form name in the database window and give focus // to the database window: oAccess.DoCmd.SelectObject(Access.AcObjectType.acForm, sForm, true);

// Show the form: oAccess.DoCmd.OpenForm(sForm, Access.AcFormView.acNormal, moMissing, moMissing, Access.AcFormOpenDataMode.acFormPropertySettings, Access.AcWindowMode.acWindowNormal, moMissing);

// Use Controls collection to edit the form:

oForm = oAccess.Forms[sForm]; oCtls = oForm.Controls;

// Set PrintLabelsFor option group to Specific Country:

oCtl = (Access.Control)oCtls["PrintLabelsFor"]; object[] Parameters = new Object[1]; Parameters[0] = 2; //second option in option group oCtl.GetType().InvokeMember("Value", BindingFlags.SetProperty, null, oCtl, Parameters); NAR(oCtl); oCtl = null;

// Put USA in the SelectCountry combo box: oCtl = (Access.Control)oCtls["SelectCountry"]; Parameters[0] = true; oCtl.GetType().InvokeMember("Enabled", BindingFlags.SetProperty,

Page 20: Automatizar Access Con c#

null, oCtl, Parameters); oCtl.GetType().InvokeMember("SetFocus", BindingFlags.InvokeMethod, null, oCtl, null); Parameters[0] = "USA"; oCtl.GetType().InvokeMember("Value", BindingFlags.SetProperty, null, oCtl, Parameters); NAR(oCtl); oCtl = null;

// Hide the Database Window: oAccess.DoCmd.SelectObject(Access.AcObjectType.acForm, sForm, true); oAccess.RunCommand(Access.AcCommand.acCmdWindowHide);

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

// Release Controls and Form objects: NAR(oCtls); oCtls = null; NAR(oForm); oForm = null;

// Release Application object and allow Access to be closed by user: if(!oAccess.UserControl) oAccess.UserControl = true; NAR(oAccess); oAccess = null; } catch(Exception e) { MessageBox.Show(e.Message); // Release any Access objects and quit Access due to error: NAR(oCtl); oCtl = null; NAR(oCtls); oCtls = null; NAR(oForm); oForm = null; try // use try..catch in case oAccess is not set { oAccess.Quit(Access.AcQuitOption.acQuitSaveNone); } catch{} NAR(oAccess);

Page 21: Automatizar Access Con c#

oAccess = null; } }

private void 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.

Access.Application oAccess = null; string sDBPath = null; //path to Northwind.mdb string sUser = null; //user name for Access security string sPwd = null; //user password for Access security string sReport = null; //name of report to print

// Enable exception handler: try { sReport = "Summary of Sales by Year"; // Determine the path to Northwind.mdb: sDBPath = GetOfficeAppPath("Access.Application", "msaccess.exe"); if(sDBPath == null) { MessageBox.Show("Can't determine path to msaccess.exe"); return; } sDBPath = sDBPath.Substring(0, sDBPath.Length - "msaccess.exe".Length) + @"Samples\Northwind.mdb"; if(!System.IO.File.Exists(sDBPath)) { MessageBox.Show("Can't find the file '" + sDBPath + "'"); return; }

// Specify the user name and password for the Access workgroup // information file, which is used to implement Access security.

Page 22: Automatizar Access Con c#

// Note: If you are not using the system.mdw in the default // location, you may include the /wrkgrp command-line switch to // point to a different workgroup information file. sUser = "Admin"; sPwd = "";

// Start a new instance of Access with user name and password: oAccess = ShellGetDB(sDBPath, "/user " + sUser + " /pwd " + sPwd, ProcessWindowStyle.Minimized, 1000); //or //oAccess = ShellGetApp(@"""" + sDBPath + @"""" + // " /user " + sUser + " /pwd " + sPwd, // ProcessWindowStyle.Minimized);

// Select the report name in the database window and give focus // to the database window: oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);

// Print the report: oAccess.DoCmd.OpenReport(sReport, Access.AcView.acViewNormal, moMissing, moMissing, Access.AcWindowMode.acWindowNormal, moMissing ); // If using Access 10.0 object library, use this instead: //oAccess.DoCmd.OpenReport(sReport, // Access.AcView.acViewNormal, moMissing, moMissing, // Access.AcWindowMode.acWindowNormal, moMissing); } catch(Exception e) { MessageBox.Show(e.Message); } finally { // Release any Access objects and quit Access: try // use try..catch in case oAccess is not set { oAccess.Quit(Access.AcQuitOption.acQuitSaveNone); } catch{} NAR(oAccess);

Page 23: Automatizar Access Con c#

oAccess = null; } }

private void Preview_Report_Runtime() { //Shows how to automate the Access Runtime to preview //the "Summary of Sales by Year" report in Northwind.mdb.

Access.Application oAccess = null; Access.Form oForm = null; string sDBPath = null; //path to Northwind.mdb string sReport = null; //name of report to preview

// Enable exception handler: try { sReport = "Summary of Sales by Year";

// Determine the path to Northwind.mdb: sDBPath = GetOfficeAppPath("Access.Application", "msaccess.exe"); if(sDBPath == null) { MessageBox.Show("Can't determine path to msaccess.exe"); return; }

sDBPath = sDBPath.Substring(0, sDBPath.Length - "msaccess.exe".Length) + @"Samples\Northwind.mdb"; if(!System.IO.File.Exists(sDBPath)) { MessageBox.Show("Can't find the file '" + sDBPath + "'"); return; }

// Start a new instance of Access with a database. 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", ProcessWindowStyle.Minimized, 1000); //or

Page 24: Automatizar Access Con c#

//oAccess = ShellGetApp(@"""" + sDBPath + @"""" + " /runtime", // ProcessWindowStyle.Minimized);

// Make sure Access is visible: if(!oAccess.Visible) oAccess.Visible = true;

// Close any forms that Northwind may have opened: while(oAccess.Forms.Count > 0) { oForm = oAccess.Forms[0]; oAccess.DoCmd.Close(Access.AcObjectType.acForm, oForm.Name, Access.AcCloseSave.acSaveNo); NAR(oForm); oForm = null; }

// Select the report name in the database window and give focus // to the database window: oAccess.DoCmd.SelectObject(Access.AcObjectType.acReport, sReport, true);

// Maximize the Access window: oAccess.RunCommand(Access.AcCommand.acCmdAppMaximize);

// Preview the report: oAccess.DoCmd.OpenReport(sReport, Access.AcView.acViewPreview, moMissing, moMissing, Access.AcWindowMode.acWindowNormal, moMissing ); // If using Access 10.0 object library, use this instead: //oAccess.DoCmd.OpenReport(sReport, // Access.AcView.acViewPreview, moMissing, moMissing, // Access.AcWindowMode.acWindowNormal, moMissing);

// Maximize the report window: oAccess.DoCmd.Maximize();

// Hide Access menu bar: oAccess.CommandBars["Menu Bar"].Enabled = false; // Also hide NorthWindCustomMenuBar if it is available: try { oAccess.CommandBars["NorthwindCustomMenuBar"].Enabled = false; }

Page 25: Automatizar Access Con c#

catch{}

// Release Application object and allow Access to be closed by user: if(!oAccess.UserControl) oAccess.UserControl = true; NAR(oAccess); oAccess = null; } catch(Exception e) { MessageBox.Show(e.Message); // Release any Access objects and quit Access due to error: NAR(oForm); oForm = null; try // use try..catch in case oAccess is not set { oAccess.Quit(Access.AcQuitOption.acQuitSaveNone); } catch{} NAR(oAccess); oAccess = null; } }

Agregue el código siguiente a las directivas Using de Form1.cs:

using System.Runtime.InteropServices;using System.Diagnostics;using System.Reflection;

Presione F5 para generar y ejecutar el programa. Se muestra Form1.

Haga clic en Imprimir informe y, a continuación, haga clic en Ir! . El procedimiento

Print_Report imprimirá un informe de la base de datos Neptuno.

Haga clic en informe de vista previa y, a continuación, haga clic en Ir! . El

procedimiento Preview_Report ofrecerá una vista previa de un informe de la base de

datos Neptuno. Cierre la instancia de Access cuando desee continuar.

Haga clic en Mostrar el formulario y, a continuación, haga clic en Ir! . El procedimiento

Show_Form muestra el formulario de cuadro de diálogo de etiquetas de cliente de la base

de datos Northwind. También establecerá el grupo de opciones del formulario en "País

específico" y seleccionará "EE.UU." en la lista. Cierre la instancia de Access cuando desee

continuar.

Haga clic en Imprimir el informe (seguridad) y, a continuación, haga clic en Ir! . El

procedimiento Print_Report_Security le mostrará cómo automatizar Access y cómo evitar

el cuadro de diálogo de inicio de sesión cuando se encuentre activada la seguridad a

nivel de usuario. En el ejemplo, se presupone que el inicio de sesión es el

predeterminado, por lo que se pasará el usuario Admin con una contraseña en blanco.

Tras ello, el código imprimirá un informe de la base de datos Neptuno.

Page 26: Automatizar Access Con c#

Haga clic en Preview report (Runtime) y, a continuación, haga clic en Ir! . El

procedimiento Preview_Report_Runtime le mostrará cómo automatizar los archivos en

tiempo de ejecución de Access para obtener la vista previa de un informe de la base de

datos Neptuno. Si se encuentra instalada la versión comercial de Access, el

procedimiento funcionará correctamente. Cierre la instancia de Access cuando esté listo

para continuar.Volver al principio

REFERENCIASPara obtener más información, visite el siguiente sitio Web de MSDN:

Desarrollo de Microsoft Office con Visual Studio

http://msdn2.microsoft.com/en-us/library/aa188489(office.10).aspxPara obtener más información, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:

317157  PRB: Errores cuando se hace referencia la 10.0 Access escriba biblioteca con Visual

Studio.NET

317109  Aplicación de Office no se cierra después de la automatización desde cliente de Visual

Studio .NET

316126  Cómo utilizar C# para automatizar una instancia en ejecución de un programa de Office

316125  PRB: Error de Visual C# .NET adjuntar a ejecutando instancia de la aplicación de Office

244695  Error: Mensaje de error 2046 llamada AbrirFormulario o AbrirInforme con la

automatización de acceso

302902  Enlazar con servidores de automatización de Office mediante Visual C# .NET

302295  Cómo obtener el identificador de ventana para un servidor de automatización de Office

mediante Visual C# .NET

306683  Cómo ejecutar macros de Office utilizando automatización desde Visual C# .NEThttp://www.mediafire.com/?hx4t4z6295dattb