Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Riepilogo
Questo articolo illustra come automatizzare Microsoft Access usando Microsoft Visual C# 2005 o Microsoft Visual C# .NET. Gli argomenti e il codice di esempio illustrano come eseguire le operazioni seguenti:
- Aprire un database in Access.
- Stampare o visualizzare in anteprima un report di Access.
- Visualizzare e modificare un modulo di Access.
- Evitare finestre di dialogo quando si apre un database protetto da password o quando è attivata la sicurezza a livello di utente.
- Automatizzare il runtime di Accesso.
Automazione e ADO.NET
Uno sviluppatore può usare un database di Microsoft Access da Visual C# 2005 o Visual C# .NET usando due tecnologie separate: Automazione e Microsoft ADO.NET.
ADO.NET è la tecnologia preferita se si desidera utilizzare oggetti dati, ad esempio tabelle e query in un database di Access. Usare Automazione solo se sono necessarie funzionalità specifiche dell'applicazione di Microsoft Access, ad esempio la possibilità di stampare o visualizzare in anteprima un report di Access, di visualizzare una maschera di Access o di chiamare macro di Access.
Questo articolo illustra come automatizzare Access. L'articolo non illustra ADO.NET. Per informazioni su ADO.NET, fare clic sui numeri degli articoli seguenti per visualizzare gli articoli della Microsoft Knowledge Base:
306636 Come connettersi a un database ed eseguire un comando usando ADO 2005 e Visual C# 2005 o ADO.NET e Visual C# .NET
314145 Come popolare un oggetto DataSet da un database usando Visual C# .NET
307587 Come aggiornare un database da un oggetto DataSet usando Visual C# 2005 o Visual C# .NET
L'automazione è una tecnologia COM (Component Object Model). L'automazione consente alle applicazioni scritte in linguaggi come Visual C# .NET di controllare altre applicazioni a livello di codice. Quando si automatizza un'applicazione di Microsoft Office, si esegue effettivamente un'istanza di tale applicazione in memoria e quindi si chiama sul modello a oggetti dell'applicazione per eseguire varie attività in tale applicazione. Con Access e altre applicazioni di Microsoft Office, praticamente tutte le azioni che è possibile eseguire manualmente tramite l'interfaccia utente possono essere eseguite anche a livello di codice tramite Automazione.
Access espone questa funzionalità a livello di codice tramite un modello a oggetti. Il modello a oggetti è una raccolta di classi e metodi che fungono da controparti ai componenti logici di Access. Per accedere al modello a oggetti da Visual C# .NET, è possibile impostare un riferimento al progetto alla libreria dei tipi.
Attività comuni di automazione
Aprire un database in Access
Quando si automatizza Microsoft Access, è necessario aprire un database prima di poter eseguire attività utili, ad esempio la stampa di report. Per aprire un database nell'istanza di Access che si sta automatizzando, usare i metodi OpenCurrentDatabase o OpenAccessProject dell'oggetto Application. In Access è possibile aprire un solo database alla volta. Per usare un database diverso, è possibile utilizzare il metodo CloseCurrentDatabase prima di aprirlo.
È anche possibile utilizzare il metodo System.Runtime.InteropServices.Marshal.BindToMoniker(<path to database>) per aprire un database in un'istanza di Access. Se il database è già aperto in un'istanza di Access, BindToMoniker restituisce l'oggetto Application di tale istanza. In caso contrario, BindToMoniker avvia una nuova istanza di Access e apre il database specificato.
OpenCurrentDatabase è il metodo preferito per aprire un database, perché si specifica l'istanza di Access che si sta automatizzando. È anche possibile fornire argomenti per controllare la modalità di apertura del database, ad esempio:
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
);
Stampare o visualizzare in anteprima un report di Accesso
Per visualizzare in anteprima o per stampare un report di Access, chiamare il metodo OpenReport dell'oggetto DoCmd. Quando si chiama OpenReport, uno degli argomenti passati determina se il report viene visualizzato in anteprima sullo schermo o se viene inviato alla stampante:
// 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
);
Si noti che l'argomento Visualizza determina se il report viene visualizzato in Access o se viene inviato alla stampante. L'argomento WhereCondition può limitare il recordset del report, se si usa una clausola SQL WHERE valida (senza la parola WHERE). Si noti che è possibile usare System.Reflection.Missing.Value per ignorare tutti i parametri dell'oggetto facoltativi.
Se si visualizza in anteprima un report, assicurarsi di impostare la proprietà Visible dell'oggetto Application in modo che Access sia visibile sullo schermo. In questo modo, l'utente può visualizzare il report nella finestra di Access.
Esiste un altro modo per stampare un report o altri oggetti nel database. Utilizzare il metodo PrintOut dell'oggetto DoCmd. In questo esempio si seleziona un report denominato Employees nella finestra Database e quindi si chiama PrintOut per stampare l'oggetto selezionato. Il metodo PrintOut consente di specificare argomenti che corrispondono alla finestra di dialogo Stampa in 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
);
In alcuni casi, in alternativa, è possibile usare entrambi i metodi OpenReport e PrintOut per stampare un report. Si supponga di voler stampare più copie del report Dipendenti, ma solo per un dipendente specifico. In questo esempio viene innanzitutto utilizzato OpenReport per aprire il report Employees in modalità anteprima, utilizzando l'argomento WhereCondition per limitare i record a un dipendente specifico. Quindi, PrintOut viene usato per stampare più copie dell'oggetto attivo:
// 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
);
Access 2002 ha introdotto l'oggetto Printer. È possibile utilizzare questo oggetto per personalizzare le impostazioni della stampante di Access più facilmente rispetto alle versioni precedenti di Access. Per un esempio di utilizzo dell'oggetto Printer in Access per stampare un report, fare clic sul numero dell'articolo seguente per visualizzare l'articolo della Microsoft Knowledge Base:
284286 Come reimpostare le modifiche all'oggetto Application.Printer
Visualizzare e modificare un modulo di accesso
Visual C# .NET offre funzionalità di modulo molto potenti. Tuttavia, potrebbero verificarsi momenti in cui si vuole che l'utente visuali un modulo sviluppato in precedenza in Access. In alternativa, è possibile che nel database di Access sia presente una maschera che fornisce i criteri per una query o un report ed è necessario aprirla prima di poter visualizzare in anteprima o stampare il report. Per aprire e visualizzare una maschera di Access, chiamare il metodo OpenForm dell'oggetto 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
);
È ora possibile modificare i controlli nel modulo.
Finestre di dialogo Per la sicurezza di accesso
Quando si automatizza Access, potrebbe essere richiesto di immettere un nome utente o una password, o entrambi, quando si tenta di aprire un database. Se l'utente immette le informazioni errate, si verificherà un errore nel codice. In alcuni casi è possibile evitare queste finestre di dialogo e specificare invece a livello di codice il nome utente e la password in modo che il codice di Automazione venga eseguito senza interruzioni.
In Microsoft Access esistono due tipi di sicurezza: database protetti da password e sicurezza a livello di utente tramite un file del gruppo di lavoro (System.mdw). Se si sta tentando di aprire un database protetto da password, verrà visualizzata una finestra di dialogo che richiede la password del database. La sicurezza a livello di utente è diversa da un database protetto da password. Quando viene attivata la sicurezza a livello di utente, Access visualizza una finestra di dialogo di accesso che richiede sia un nome utente che una password prima che l'utente possa aprire qualsiasi database in Access.
Evitare le finestre di dialogo Password database
Se si apre un database protetto con una password, è possibile evitare la finestra di dialogo specificando la password per il metodo OpenCurrentDatabase:
// Open a password-protected database in shared mode:
// Note: The bstrPassword argument is case-sensitive
oAccess.OpenCurrentDatabase(
"c:\\mydb.mdb", //filepath
false, //Exclusive
"MyPassword" //bstrPassword
);
Di seguito è riportato un esempio in cui oAccess è stato impostato in precedenza su un'istanza di Access che non ha un database aperto. Questo codice fornisce la password al database per evitare una finestra di dialogo:
string sDBPassword = "MyPassword"; //database password
DAO._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;
ODB.Close non chiude effettivamente il database in Access. Chiude solo la connessione DAO al database creato tramite l'oggetto DBEngine. La connessione DAO non è più necessaria dopo l'utilizzo del metodo OpenCurrentDatabase. Si noti il codice per rilasciare gli oggetti oDB e oDBEngine. È necessario usare questi oggetti in modo che Access venga chiuso correttamente dopo il completamento del codice.
Evitare le finestre di dialogo accesso alla sicurezza di accesso
Se la sicurezza a livello di utente è attivata in Access, all'utente viene visualizzata una finestra di dialogo di accesso che richiede sia un nome utente che una password. Non è possibile specificare un nome utente e una password usando il modello a oggetti di Access. Pertanto, se si vuole evitare la finestra di dialogo di accesso durante l'automazione di Access, è necessario innanzitutto avviare il file Msaccess.exe e specificare le opzioni della riga di comando /user e /pwd per specificare il nome utente e la password. Successivamente, è possibile usare GetActiveObject o BindToMoniker per recuperare l'oggetto Application dell'istanza in esecuzione di Access, in modo da poter procedere con Automazione.
Automazione del runtime di accesso
Microsoft Office Developer Edition include Microsoft Office Developer Tools (MOD). Usando MOD, gli sviluppatori di Access possono creare e distribuire applicazioni di Access agli utenti che non dispongono della versione finale di Access. Quando l'utente installa l'applicazione Access in un computer che non dispone della versione finale di Access, viene installata una versione runtime di Access. Il runtime di Access viene installato ed è registrato come la versione finale. Il file eseguibile viene anche chiamato Msaccess.exe. Il runtime di accesso consente l'esecuzione di un'applicazione Access in un computer client, ma il runtime di Access non consente a un utente di sviluppare nuove applicazioni o modificare la progettazione delle applicazioni esistenti.
Il runtime di accesso deve essere avviato con un database. A causa di questo requisito, se si vuole automatizzare il runtime di Access, è necessario avviare il Msaccess.exe e specificare un database da aprire. Dopo aver usato GetActiveObject o BindToMoniker per recuperare l'oggetto Application, è possibile automatizzare il runtime di Access. Se non si usa questo approccio quando si tenta di automatizzare il runtime di Access, quando si tenta di creare un'istanza dell'istanza viene visualizzato un messaggio di errore simile al seguente:
Esecuzione del server System.Runtime.InteropServices.COMException (0x80080005) non riuscita.
Creare il progetto Visual C# 2005 o Visual C# .NET di esempio completo
Per usare l'esempio dettagliato seguente, assicurarsi che sia installato il database di esempio Northwind. Per impostazione predefinita, Microsoft Access 2000 installa i database di esempio nel percorso seguente:
C:\Programmi\Microsoft Office\Office\Samples
Microsoft Access 2002 usa il percorso seguente:
C:\Programmi\Microsoft Office\Office10\Samples
Microsoft Office Access 2003 usa il percorso seguente:
C:\Programmi\Microsoft\Office\Office11\Samples
Per assicurarsi che il database di esempio Northwind sia installato in Access 2002 o in Access 2003, scegliere Database di esempio dal menu ? e quindi fare clic su Database di esempio Northwind.
Chiudere tutte le istanze di Access attualmente in esecuzione.
Avviare Microsoft Visual Studio .NET.
Scegliere Nuovo dal menu File e quindi fare clic su Progetto. Selezionare Applicazione Windows dai tipi di progetto Visual C#. Per impostazione predefinita, viene creato Form1.
Nota È necessario modificare il codice in Visual Studio 2005. Per impostazione predefinita, Visual C# aggiunge una maschera al progetto quando si crea un progetto Windows Forms. Il modulo è denominato Form1. I due file che rappresentano il modulo sono denominati Form1.cs e Form1.designer.cs. Il codice viene scritto in Form1.cs. Nel file Form1.designer.cs il Windows Forms Designer scrive il codice che implementa tutte le azioni eseguite trascinando ed eliminando i controlli dalla casella degli strumenti.
Per altre informazioni su Progettazione Windows Forms in Visual C# 2005, visitare il seguente sito Web Microsoft Developer Network (MSDN):https://msdn.microsoft.com/en-us/library/ms173077.aspx
Aggiungere un riferimento alla libreria di oggetti di Microsoft Access. A tal fine, attenersi alla seguente procedura:
- Scegliere Aggiungi riferimento dal menu Progetto.
- Nella scheda COM individuare Libreria oggetti di Microsoft Access e quindi fare clic su Seleziona.
Nota In Visual Studio 2005. non è necessario fare clic su Seleziona.
Nota Microsoft Office 2003 include assembly di interoperabilità primari ( PIA). Microsoft Office XP non include FUNZIONALITÀ personali, ma può essere scaricato.
Nella finestra di dialogo Aggiungi riferimenti fare clic su OK per accettare le selezioni.
Nota Se si fa riferimento alla libreria di oggetti di Access 10.0 e si ricevono errori quando si tenta di aggiungere il riferimento.
Scegliere Casella degli strumenti dal menu Visualizza per visualizzare la casella degli strumenti.
Aggiungere cinque controlli pulsante di opzione e un controllo pulsante a Form1.
Selezionare tutti i controlli pulsante di opzione e quindi impostare la proprietà Size su 150,24.
Aggiungere gestori eventi per l'evento Form Load e per l'evento Click del controllo Button:
Nella visualizzazione Progettazione per Form1.cs fare doppio clic su Form1.
Il gestore per l'evento Load del form viene creato e visualizzato in Form1.cs.
Scegliere Progettazione dal menu Visualizza per passare alla visualizzazione progettazione.
Fare doppio clic su Button1.
Il gestore per l'evento Click del pulsante viene creato e visualizzato in Form1.cs.
In Form1.cs sostituire il codice seguente
private void Form1_Load(object sender, System.EventArgs e) { } private void button1_Click(object sender, System.EventArgs e) { }
Con:
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; 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 { // 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; } 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; 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 //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 { 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: 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{} 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; } // 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) { 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, ""); // 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, 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); 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. // 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); 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 //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; } 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; } }
Aggiungere il codice seguente alle direttive Using in Form1.cs:
using System.Runtime.InteropServices; using System.Diagnostics; using System.Reflection;
Premere F5 per compilare ed eseguire il programma. Viene visualizzato Il modulo 1.
Fare clic su Stampa report e quindi su Go!. La routine Print_Report stampa un report dal database Northwind.
Fare clic su Anteprima report e quindi su Go!. La routine Preview_Report visualizza in anteprima un report dal database Northwind. Chiudere l'istanza di Access quando si è pronti per continuare.
Fare clic su Mostra modulo e quindi su Go!. Nella procedura Show_Form viene visualizzata la maschera della finestra di dialogo Etichette cliente del database Northwind. Imposta anche il gruppo di opzioni nel modulo su "Paese specifico" e seleziona "USA" dall'elenco. Chiudere l'istanza di Access quando si è pronti per continuare.
Fare clic su Stampa report (sicurezza) e quindi su Go!. La procedura Print_Report_Security illustra come automatizzare Access e come evitare la finestra di dialogo di accesso se la sicurezza a livello di utente è attivata. In questo esempio si supponga che l'accesso predefinito passi all'utente Amministrazione con una password vuota. Il codice stampa quindi un report nel database Northwind.
Fare clic su Anteprima report (runtime) e quindi su Go!. La procedura Preview_Report_Runtime illustra come automatizzare il runtime di Access per visualizzare in anteprima un report nel database Northwind. Se la versione finale di Access è installata, la procedura continuerà a funzionare correttamente. Chiudere l'istanza di Access quando si è pronti per continuare.
Riferimenti
Per altre informazioni, visitare il seguente sito Web MSDN: Sviluppo di Microsoft Office con Visual Studio https://msdn.microsoft.com/en-us/library/aa188489(office.10).aspxPer altre informazioni, fare clic sui numeri degli articoli seguenti per visualizzare gli articoli della Microsoft Knowledge Base:
317109'applicazione di Office non viene chiusa dopo l'automazione dal client .NET di Visual Studio
316126 Come usare Visual C# per automatizzare un'istanza in esecuzione di un'applicazione di Office