Übertragen von Daten in eine Excel-Arbeitsmappe mit Visual C# 2005 oder Visual C# .NET

Eine Microsoft Visual Basic 6.0-Version dieses Artikels finden Sie unter 247412.

In diesem Schritt-für-Schritt-Artikel werden verschiedene Methoden zum Übertragen von Daten aus einem Microsoft Visual C# 2005- oder Microsoft Visual C#-.NET-Programm nach Microsoft Excel 2002 beschrieben. In diesem Artikel werden auch die Vor- und Nachteile jeder Methode erläutert, sodass Sie die Lösung auswählen können, die für Ihre Situation am besten geeignet ist.

Übersicht

Die Methode, die am häufigsten zum Übertragen von Daten an eine Excel-Arbeitsmappe verwendet wird, ist Automatisierung. Mit der Automatisierung können Sie Methoden und Eigenschaften aufrufen, die für Excel-Aufgaben spezifisch sind. Automatisierung bietet Ihnen die größte Flexibilität beim Angeben des Speicherorts Ihrer Daten in der Arbeitsmappe, beim Formatieren der Arbeitsmappe und beim Erstellen verschiedener Einstellungen zur Laufzeit.

Mit automatisierung können Sie verschiedene Techniken verwenden, um Ihre Daten zu übertragen:

  • Übertragen von Daten zelleweise.
  • Übertragen von Daten in einem Array in einen Zellbereich.
  • Übertragen von Daten in einem ADO-Recordset in einen Zellbereich mithilfe der CopyFromRecordset-Methode.
  • Erstellen Sie ein QueryTable-Objekt auf einem Excel-Arbeitsblatt, das das Ergebnis einer Abfrage für eine ODBC- oder OLEDB-Datenquelle enthält.
  • Übertragen Sie Daten in die Zwischenablage, und fügen Sie dann den Inhalt der Zwischenablage in ein Excel-Arbeitsblatt ein.
    Sie können auch mehrere Methoden verwenden, die nicht unbedingt automatisierungsbedürftig sind, um Daten an Excel zu übertragen. Wenn Sie ein serverseitiges Programm ausführen, kann dies ein guter Ansatz sein, um den Großteil der Datenverarbeitung von Ihren Clients zu entfernen.

Um Ihre Daten ohne Automatisierung zu übertragen, können Sie die folgenden Ansätze verwenden:

  • Übertragen Sie Ihre Daten in eine durch Tabstopps getrennte oder durch Trennzeichen getrennte Textdatei, die Excel später in Zellen eines Arbeitsblatts analysieren kann.
  • Übertragen Sie Ihre Daten mithilfe von ADO.NET auf ein Arbeitsblatt.
  • Übertragen sie XML-Daten an Excel (Version 2002 und 2003), um Daten bereitzustellen, die formatiert und in Zeilen und Spalten angeordnet sind.

Dieser Artikel enthält eine Erläuterung und ein Codebeispiel für jede dieser Techniken. Im Abschnitt "Create the Complete Sample Visual C# 2005 or Visual C# .NET Project" weiter unten in diesem Artikel wird veranschaulicht, wie Sie ein Visual C# .NET-Programm erstellen, das die einzelnen Verfahren ausführt.

Techniken

Verwenden der Automatisierung zum Übertragen von Datenzellen nach Zellen

Mit der Automatisierung können Sie Daten jeweils einzeln in ein Arbeitsblatt übertragen:

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));

// Add data to cells in the first worksheet in the new workbook.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange.Value = "Last Name";
m_objRange = m_objSheet.get_Range("B1", m_objOpt);
m_objRange.Value = "First Name";
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.Value = "Doe";
m_objRange = m_objSheet.get_Range("B2", m_objOpt);
m_objRange.Value = "John";

// Apply bold to cells A1:B1.
m_objRange = m_objSheet.get_Range("A1", "B1");
m_objFont = m_objRange.Font;
m_objFont.Bold=true;

// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

Das Übertragen von Daten von Zelle zu Zelle ist ein akzeptabler Ansatz, wenn Sie über eine kleine Datenmenge verfügen. Sie haben die Flexibilität, Daten an einer beliebigen Stelle in der Arbeitsmappe zu platzieren, und Sie können die Zellen zur Laufzeit bedingt formatieren. Es empfiehlt sich jedoch nicht, diesen Ansatz zu verwenden, wenn Sie über eine große Datenmenge verfügen, die in eine Excel-Arbeitsmappe übertragen werden soll. Jedes Range-Objekt, das Sie zur Laufzeit abrufen, führt zu einer Schnittstellenanforderung, die eine langsamere Datenübertragung bedeutet. Darüber hinaus gelten für Microsoft Windows 95, Microsoft Windows 98 und Microsoft Windows Millennium Edition (Me) einschränkungen von 64 KB für Schnittstellenanforderungen. Wenn Sie über mehr als 64 KB Schnittstellenanforderungen verfügen, reagiert der Automatisierungsserver (Excel) möglicherweise nicht mehr, oder Sie erhalten Fehlermeldungen, die auf wenig Arbeitsspeicher hinweisen.

Auch hier ist die Übertragung von Datenzellen nach Zelle nur für kleine Datenmengen zulässig. Wenn Sie große Datensätze nach Excel übertragen müssen, sollten Sie einen der anderen Ansätze in Betracht ziehen, die in diesem Artikel erläutert werden, um Daten in Massen zu übertragen.

Wenn Sie weitere Informationen und ein Beispiel für die Automatisierung von Excel mit Visual C# .NET wünschen, klicken Sie auf die artikelnummer unten, um den Artikel in der Microsoft Knowledge Base anzuzeigen:

302084 HOWTO: Automatisieren von Microsoft Excel aus Microsoft Visual C# .NET

Verwenden der Automatisierung zum Übertragen eines Datenarrays in einen Bereich auf einem Arbeitsblatt

Sie können ein Datenarray gleichzeitig in einen Bereich mit mehreren Zellen übertragen:

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));

// Create an array for the headers and add it to cells A1:C1.
object[] objHeaders = {"Order ID", "Amount", "Tax"};
m_objRange = m_objSheet.get_Range("A1", "C1");
m_objRange.Value = objHeaders;
m_objFont = m_objRange.Font;
m_objFont.Bold=true;

// Create an array with 3 columns and 100 rows and add it to
// the worksheet starting at cell A2.
object[,] objData = new Object[100,3];
Random rdm = new Random((int)DateTime.Now.Ticks);
double nOrderAmt, nTax;
for(int r=0;r<100;r++)
{
objData[r,0] = "ORD" + r.ToString("0000");
nOrderAmt = rdm.Next(1000);
objData[r,1] = nOrderAmt.ToString("c");
nTax = nOrderAmt*0.07;
objData[r,2] = nTax.ToString("c");
}
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange = m_objRange.get_Resize(100,3);
m_objRange.Value = objData;

// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

Wenn Sie Ihre Daten mithilfe eines Arrays anstelle von Zelle zu Zelle übertragen, können Sie mit einer großen Datenmenge einen enormen Leistungsgewinn erzielen. Betrachten Sie die folgenden Zeilen aus dem oben genannten Code, die Daten an 300 Zellen im Arbeitsblatt übertragen:

objRange = objSheet.get_Range("A2", m_objOpt);
objRange = objRange.get_Resize(100,3);
objRange.Value = objData;

Dieser Code stellt zwei Schnittstellenanforderungen dar: eine für das Range-Objekt, das die Range-Methode zurückgibt, und eine weitere für das Range-Objekt, das die Resize-Methode zurückgibt. Im Gegensatz dazu erfordert das Übertragen der Datenzelle nach Zelle Anforderungen für 300 Schnittstellen an Range-Objekte. Wenn möglich, können Sie von der Massenübertragung Ihrer Daten und der Verringerung der Anzahl der Schnittstellenanforderungen profitieren, die Sie vornehmen.

Weitere Informationen zur Verwendung von Arrays zum Abrufen und Festlegen von Werten in Bereichen mit Excel Automation finden Sie in den folgenden Artikeln der Microsoft Knowledge Base:

302096 HOWTO: Automatisieren von Excel mit Visual C# .NET zum Ausfüllen oder Abrufen von Daten in einem Bereich mithilfe von Arrays

Verwenden der Automatisierung zum Übertragen eines ADO-Recordsets in einen Arbeitsblattbereich

Die Objektmodelle für Excel 2000, Excel 2002 und Excel 2003 stellen die CopyFromRecordset-Methode zum Übertragen eines ADO-Recordsets in einen Bereich auf einem Arbeitsblatt bereit. Der folgende Code veranschaulicht, wie Sie Excel automatisieren, um den Inhalt der Tabelle "Orders" in der Northwind-Beispieldatenbank mithilfe der CopyFromRecordset-Methode zu übertragen:

// Create a Recordset from all the records in the Orders table.
ADODB.Connection objConn = new ADODB.Connection();
ADODB._Recordset objRS = null;
objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", "", "", 0);
objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
object objRecAff;
objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff, 
(int)ADODB.CommandTypeEnum.adCmdTable);

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));

// Get the Fields collection from the recordset and determine
// the number of fields (or columns).
System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator();
int nFields = objRS.Fields.Count;

// Create an array for the headers and add it to the
// worksheet starting at cell A1.
object[] objHeaders = new object[nFields];
ADODB.Field objField = null;
for(int n=0;n<nFields;n++)
{
objFields.MoveNext();
objField = (ADODB.Field)objFields.Current;
objHeaders[n] = objField.Name;
}
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objRange = m_objRange.get_Resize(1, nFields);
m_objRange.Value = objHeaders;
m_objFont = m_objRange.Font;
m_objFont.Bold=true;

// Transfer the recordset to the worksheet starting at cell A2.
m_objRange = m_objSheet.get_Range("A2", m_objOpt);
m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt);

// Save the Workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

// Close the recordset and connection.
objRS.Close();
objConn.Close();

Hinweis

CopyFromRecordset funktioniert nur mit ADO-Recordset-Objekten. Sie können das DataSet, das Sie mithilfe von ADO.NET mit der CopyFromRecordset-Methode erstellen, nicht verwenden. Einige Beispiele in den folgenden Abschnitten veranschaulichen, wie Daten mit ADO.NET nach Excel übertragen werden.

Verwenden der Automatisierung zum Erstellen eines QueryTable-Objekts auf einem Arbeitsblatt

Ein QueryTable-Objekt stellt eine Tabelle dar, die aus Daten erstellt wird, die von einer externen Datenquelle zurückgegeben werden. Wenn Sie Excel automatisieren, können Sie eine QueryTable erstellen, indem Sie eine Verbindungszeichenfolge für eine OLE DB- oder ODBC-Datenquelle und eine SQL-Zeichenfolge angeben. Excel generiert das Recordset und fügt das Recordset an der von Ihnen angegebenen Position in das Arbeitsblatt ein. QueryTable-Objekte bieten gegenüber der CopyFromRecordset-Methode die folgenden Vorteile:

  • Excel übernimmt die Erstellung des Recordsets und dessen Platzierung auf dem Arbeitsblatt.
  • Sie können die Abfrage mit dem QueryTable-Objekt speichern und später aktualisieren, um ein aktualisiertes Recordset abzurufen.
  • Wenn dem Arbeitsblatt eine neue QueryTable hinzugefügt wird, können Sie angeben, dass Daten, die bereits in Zellen auf dem Arbeitsblatt vorhanden sind, verschoben werden, um die neuen Daten zu verarbeiten (weitere Informationen finden Sie in der RefreshStyle-Eigenschaft).

Der folgende Code veranschaulicht, wie Sie Excel 2000, Excel 2002 oder Excel 2003 automatisieren, um eine neue QueryTable in einem Excel-Arbeitsblatt mithilfe von Daten aus der Northwind-Beispieldatenbank zu erstellen:

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));

// Create a QueryTable that starts at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objQryTables = m_objSheet.QueryTables;
m_objQryTable = (Excel._QueryTable)m_objQryTables.Add(
"OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
m_strNorthwind + ";", m_objRange, "Select * From Orders");
m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows;
m_objQryTable.Refresh(false);

// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

Verwenden der Windows-Zwischenablage

Sie können die Windows-Zwischenablage verwenden, um Daten an ein Arbeitsblatt zu übertragen. Wenn Sie Daten in mehrere Zellen eines Arbeitsblatts einfügen möchten, können Sie eine Zeichenfolge kopieren, in der Spalten durch TAB-Zeichen und Zeilen durch Wagenrücklauf getrennt werden. Der folgende Code veranschaulicht, wie Visual C# .NET die Windows-Zwischenablage verwenden kann, um Daten nach Excel zu übertragen:

// Copy a string to the Windows clipboard.
string sData = "FirstName\tLastName\tBirthdate\r\n"  +
"Bill\tBrown\t2/5/85\r\n"  +
"Joe\tThomas\t1/1/91";
System.Windows.Forms.Clipboard.SetDataObject(sData);

// Start a new workbook in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));

// Paste the data starting at cell A1.
m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
m_objRange = m_objSheet.get_Range("A1", m_objOpt);
m_objSheet.Paste(m_objRange, false);

// Save the workbook and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

Erstellen einer Durch Trennzeichen getrennten Textdatei, die Excel in Zeilen und Spalten analysieren kann

Excel kann tabstopp- oder kommagetrennte Dateien öffnen und die Daten ordnungsgemäß in Zellen analysieren. Sie können dieses Feature verwenden, wenn Sie eine große Menge von Daten auf ein Arbeitsblatt übertragen möchten, während Sie nur wenig Automatisierung verwenden möchten, falls vorhanden. Dies kann ein guter Ansatz für ein Client-Server-Programm sein, da die Textdatei serverseitig generiert werden kann. Sie können die Textdatei dann auf dem Client öffnen, indem Sie die Automatisierung verwenden, wo sie geeignet ist.

Der folgende Code veranschaulicht, wie sie eine durch Registerkarten getrennte Textdatei aus Daten generieren, die mit ADO.NET gelesen werden:

// Connect to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";");
objConn.Open();

// Execute a command to retrieve all records from the Employees table.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand( 
"Select * From Employees", objConn);
System.Data.OleDb.OleDbDataReader objReader;
objReader = objCmd.ExecuteReader();

// Create the FileStream and StreamWriter object to write 
// the recordset contents to file.
System.IO.FileStream fs = new System.IO.FileStream(
m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create);
System.IO.StreamWriter sw = new System.IO.StreamWriter(
fs, System.Text.Encoding.Unicode);

// Write the field names (headers) as the first line in the text file.
sw.WriteLine(objReader.GetName(0) +  "\t" + objReader.GetName(1) +
"\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) +
"\t" + objReader.GetName(4) + "\t" + objReader.GetName(5));

// Write the first six columns in the recordset to a text file as
// tab-delimited.
while(objReader.Read()) 
{
for(int i=0;i<=5;i++)
{
if(!objReader.IsDBNull(i))
{
string s;
s = objReader.GetDataTypeName(i);
if(objReader.GetDataTypeName(i)=="DBTYPE_I4")
{
sw.Write(objReader.GetInt32(i).ToString());
}
else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE")
{
sw.Write(objReader.GetDateTime(i).ToString("d"));
}
else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR")
{
sw.Write(objReader.GetString(i));
}
}
if(i<5) sw.Write("\t");
}
sw.WriteLine(); 
}
sw.Flush();// Write the buffered data to the filestream.

// Close the FileStream.
fs.Close();

// Close the reader and the connection.
objReader.Close();
objConn.Close(); 

Der oben genannte Code verwendet keine Automatisierung. Wenn Sie möchten, können Sie jedoch die Automatisierung verwenden, um die Textdatei zu öffnen und die Datei im Excel-Arbeitsmappenformat zu speichern, ähnlich wie hier:

// Open the text file in Excel.
m_objExcel = new Excel.Application();
m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1, 
Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
false, true, false, false, false, false, m_objOpt, m_objOpt, 
m_objOpt, m_objOpt, m_objOpt);

m_objBook = m_objExcel.ActiveWorkbook;

// Save the text file in the typical workbook format and quit Excel.
m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal, 
m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
m_objOpt, m_objOpt);
m_objBook.Close(false, m_objOpt, m_objOpt);
m_objExcel.Quit();

Übertragen von Daten auf ein Arbeitsblatt mithilfe von ADO.NET

Sie können den Microsoft Jet OLE DB-Anbieter verwenden, um einer Tabelle in einer vorhandenen Excel-Arbeitsmappe Datensätze hinzuzufügen. Eine Tabelle in Excel ist lediglich ein Zellbereich. der Bereich hat möglicherweise einen definierten Namen. In der Regel enthält die erste Zeile des Bereichs die Kopfzeilen (oder Feldnamen), und alle späteren Zeilen im Bereich enthalten die Datensätze.

Mit dem folgenden Code werden einer Tabelle in Book7.xls zwei neue Datensätze hinzugefügt. Die Tabelle ist in diesem Fall Sheet1:

// Establish a connection to the data source.
System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder +
"Book7.xls;Extended Properties=Excel 8.0;");
objConn.Open();

// Add two records to the table named 'MyTable'.
System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand();
objCmd.Connection = objConn;
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Bill', 'Brown')";
objCmd.ExecuteNonQuery();
objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
" values ('Joe', 'Thomas')";
objCmd.ExecuteNonQuery();

// Close the connection.
objConn.Close();

Wenn Sie Datensätze mit ADO.NET hinzufügen, wie in diesem Beispiel gezeigt, wird die Formatierung in der Arbeitsmappe beibehalten. Jeder Datensatz, der einer Zeile hinzugefügt wird, leiht das Format aus der Zeile davor aus.

Wenn Sie weitere Informationen zur Verwendung von ADO.NET benötigen, klicken Sie auf die folgenden Artikelnummern, um die Artikel in der Microsoft Knowledge Base anzuzeigen:

306636 HOW TO: Connect to a Database and Run a Command by Using ADO.NET and Visual C# .NET

314145 HOW TO: Populate a DataSet Object from a Database by Using Visual C# .NET

307587 HOW TO: Update a Database from a DataSet Object by Using Visual C# .NET

Weitere Informationen zur Verwendung des Jet OLEDB-Anbieters mit Excel-Datenquellen erhalten Sie, indem Sie auf die folgenden Artikelnummern klicken, um die Artikel in der Microsoft Knowledge Base anzuzeigen:

278973 BEISPIEL: ExcelADO veranschaulicht die Verwendung von ADO zum Lesen und Schreiben von Daten in Excel-Arbeitsmappen

257819 HOWTO: Verwenden von ADO mit Excel-Daten aus Visual Basic oder VBA

Übertragen von XML-Daten (Excel 2002 und Excel 2003)

Excel 2002 und 2003 können jede xml-Datei öffnen, die wohlgeformt ist. Sie können XML-Dateien direkt mithilfe des Befehls "Öffnen" im Menü "Datei" oder programmgesteuert mithilfe der Open- oder OpenXML-Methoden der Workbooks-Auflistung öffnen. Wenn Sie XML-Dateien zur Verwendung in Excel erstellen, können Sie auch Stylesheets zum Formatieren der Daten erstellen.

Erstellen des vollständigen Visual C# .NET-Beispielprojekts

  1. Erstellen Sie einen neuen Ordner mit dem Namen C:\ExcelData. Das Beispielprogramm speichert Excel-Arbeitsmappen in diesem Ordner.

  2. Erstellen Sie eine neue Arbeitsmappe für das Beispiel, in das geschrieben werden soll:

    1. Starten Sie eine neue Arbeitsmappe in Excel.
    2. Geben Sie in Sheet1 der neuen Arbeitsmappe "FirstName" in Zelle A1 und "LastName" in Zelle B1 ein.
    3. Wählen Sie A1:B1 aus.
    4. Zeigen Sie im Menü "Einfügen" auf "Name", und klicken Sie dann auf "Definieren". Geben Sie den Namen "MyTable" ein, und klicken Sie dann auf "OK".
    5. Speichern Sie die Arbeitsmappe als C:\Exceldata\Book7.xls.
    6. Beenden Sie Excel.
  3. Starten Sie Microsoft Visual Studio 2005 oder Microsoft Visual Studio .NET. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt. Wählen Sie unter Visual C#-Projekte oder Visual C# die Option "Windows-Anwendung" aus. Standardmäßig wird Form1 erstellt.

  4. Fügen Sie einen Verweis auf die Excel-Objektbibliothek und die primäre Interopassembly ADODB hinzu. Gehen Sie dazu wie folgt vor:

    1. On the Project menu, click Add Reference.
    2. Suchen Sie auf der Registerkarte "NET" nach ADODB, und klicken Sie dann auf "Auswählen".

    Hinweis: In Visual Studio 2005 müssen Sie nicht auf "Auswählen" klicken.
    3. Suchen Sie auf der Registerkarte COM die Microsoft Excel 10.0-Objektbibliothek oder die Microsoft Excel 11.0-Objektbibliothek, und klicken Sie dann auf "Auswählen".

    Hinweis: In Visual Studio 2005 müssen Sie nicht auf "Auswählen" klicken.

    Hinweis Wenn Sie Microsoft Excel 2002 verwenden und dies noch nicht getan haben, empfiehlt Microsoft, die primären Interopassemblys (Primary Interop Assemblies, PIAs) von Microsoft Office XP herunterzuladen und dann zu installieren.

  5. Klicken Sie im Dialogfeld "Verweise hinzufügen" auf "OK", um Ihre Auswahl zu übernehmen.

  6. Fügen Sie Formular1 ein Kombinationsfeld-Steuerelement und ein Schaltflächensteuerelement hinzu.

  7. Fügen Sie Ereignishandler für das Formularladeereignis und die Click-Ereignisse des Schaltflächen-Steuerelements hinzu:

    1. Doppelklicken Sie in der Entwurfsansicht für "Form1.cs" auf "Form1".

    Der Handler für das Load-Ereignis des Formulars wird erstellt und in Form1.cs angezeigt.
    2. Klicken Sie im Menü "Ansicht" auf "Designer", um zur Entwurfsansicht zu wechseln.
    3. Doppelklicken Sie auf Schaltfläche1.

    Der Handler für das Click-Ereignis der Schaltfläche wird erstellt und in Form1.cs angezeigt.

  8. Ersetzen Sie in Form1.cs den folgenden Code:

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

    mit:

            // Excel object references.
            private Excel.Application m_objExcel =  null;
            private Excel.Workbooks m_objBooks = null;
            private Excel._Workbook m_objBook = null;
            private Excel.Sheets m_objSheets = null;
            private Excel._Worksheet m_objSheet = null;
            private Excel.Range m_objRange =  null;
            private Excel.Font m_objFont = null;
            private Excel.QueryTables m_objQryTables = null;
            private Excel._QueryTable m_objQryTable = null;
    
    // Frequenty-used variable for optional arguments.
            private object m_objOpt = System.Reflection.Missing.Value;
    
    // Paths used by the sample code for accessing and storing data.
            private object m_strSampleFolder = "C:\\ExcelData\\";
            private string m_strNorthwind = "C:\\Program Files\\Microsoft Office\\Office10\\Samples\\Northwind.mdb";
    
    private void Form1_Load(object sender, System.EventArgs e)
            {
                comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
    
    comboBox1.Items.AddRange(new object[]{
                                                         "Use Automation to Transfer Data Cell by Cell ", 
                                                         "Use Automation to Transfer an Array of Data to a Range on a Worksheet ", 
                                                         "Use Automation to Transfer an ADO Recordset to a Worksheet Range ", 
                                                         "Use Automation to Create a QueryTable on a Worksheet", 
                                                         "Use the Clipboard", 
                                                         "Create a Delimited Text File that Excel Can Parse into Rows and Columns", 
                                                         "Transfer Data to a Worksheet Using ADO.NET "});
                comboBox1.SelectedIndex = 0;
                button1.Text = "Go!";
            }
    
    private void button1_Click(object sender, System.EventArgs e)
            {
                switch (comboBox1.SelectedIndex)
                {
                    case 0 : Automation_CellByCell(); break;
                    case 1 : Automation_UseArray(); break;
                    case 2 : Automation_ADORecordset(); break;
                    case 3 : Automation_QueryTable(); break;
                    case 4 : Use_Clipboard(); break;
                    case 5 : Create_TextFile(); break;
                    case 6 : Use_ADONET(); break;
                }
    
    //Clean-up
                m_objFont = null;
                m_objRange = null;
                m_objSheet = null;
                m_objSheets = null;
                m_objBooks = null;
                m_objBook = null;
                m_objExcel = null;
                GC.Collect();
    
    }
    
    private void Automation_CellByCell()
            {
                // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
    
    // Add data to cells of the first worksheet in the new workbook.
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objRange.set_Value(m_objOpt,"Last Name");
                m_objRange = m_objSheet.get_Range("B1", m_objOpt);
                m_objRange.set_Value(m_objOpt,"First Name");
                m_objRange = m_objSheet.get_Range("A2", m_objOpt);
                m_objRange.set_Value(m_objOpt,"Doe");
                m_objRange = m_objSheet.get_Range("B2", m_objOpt);
                m_objRange.set_Value(m_objOpt,"John");
    
    // Apply bold to cells A1:B1.
                m_objRange = m_objSheet.get_Range("A1", "B1");
                m_objFont = m_objRange.Font;
                m_objFont.Bold=true;
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book1.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Automation_UseArray()
            {
                // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
    
    // Create an array for the headers and add it to cells A1:C1.
                object[] objHeaders = {"Order ID", "Amount", "Tax"};
                m_objRange = m_objSheet.get_Range("A1", "C1");
                m_objRange.set_Value(m_objOpt,objHeaders);
                m_objFont = m_objRange.Font;
                m_objFont.Bold=true;
    
    // Create an array with 3 columns and 100 rows and add it to
                // the worksheet starting at cell A2.
                object[,] objData = new Object[100,3];
                Random rdm = new Random((int)DateTime.Now.Ticks);
                double nOrderAmt, nTax;
                for(int r=0;r<100;r++)
                {
                    objData[r,0] = "ORD" + r.ToString("0000");
                    nOrderAmt = rdm.Next(1000);
                    objData[r,1] = nOrderAmt.ToString("c");
                    nTax = nOrderAmt*0.07;
                    objData[r,2] = nTax.ToString("c");
                }
                m_objRange = m_objSheet.get_Range("A2", m_objOpt);
                m_objRange = m_objRange.get_Resize(100,3);
                m_objRange.set_Value(m_objOpt,"objData");
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book2.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Automation_ADORecordset()
            {
                // Create a Recordset from all the records in the Orders table.
                ADODB.Connection objConn = new ADODB.Connection();
                ADODB._Recordset objRS = null;
                objConn.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
                    m_strNorthwind + ";", "", "", 0);
                objConn.CursorLocation = ADODB.CursorLocationEnum.adUseClient;
                object objRecAff;
                objRS = (ADODB._Recordset)objConn.Execute("Orders", out objRecAff, 
                    (int)ADODB.CommandTypeEnum.adCmdTable);
    
    // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
    
    // Get the Fields collection from the recordset and determine
                // the number of fields (or columns).
                System.Collections.IEnumerator objFields = objRS.Fields.GetEnumerator();
                int nFields = objRS.Fields.Count;
    
    // Create an array for the headers and add it to the
                // worksheet starting at cell A1.
                object[] objHeaders = new object[nFields];
                ADODB.Field objField = null;
                for(int n=0;n<nFields;n++)
                {
                    objFields.MoveNext();
                    objField = (ADODB.Field)objFields.Current;
                    objHeaders[n] = objField.Name;
                }
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objRange = m_objRange.get_Resize(1, nFields);
                m_objRange.set_Value(m_objOpt,objHeaders);
                m_objFont = m_objRange.Font;
                m_objFont.Bold=true;
    
    // Transfer the recordset to the worksheet starting at cell A2.
                m_objRange = m_objSheet.get_Range("A2", m_objOpt);
                m_objRange.CopyFromRecordset(objRS, m_objOpt, m_objOpt);
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book3.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    //Close the recordset and connection
                objRS.Close();
                objConn.Close();
    
    }
    
    private void Automation_QueryTable()
            {
                // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
    
    // Create a QueryTable that starts at cell A1.
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objQryTables = m_objSheet.QueryTables;
                m_objQryTable = (Excel._QueryTable)m_objQryTables.Add(
                    "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
                    m_strNorthwind + ";", m_objRange, "Select * From Orders");
                m_objQryTable.RefreshStyle = Excel.XlCellInsertionMode.xlInsertEntireRows;
                m_objQryTable.Refresh(false);
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book4.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
                    m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Use_Clipboard()
            {
                // Copy a string to the clipboard.
                string sData = "FirstName\tLastName\tBirthdate\r\n"  +
                    "Bill\tBrown\t2/5/85\r\n"  +
                    "Joe\tThomas\t1/1/91";
                System.Windows.Forms.Clipboard.SetDataObject(sData);
    
    // Start a new workbook in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBook = (Excel._Workbook)(m_objBooks.Add(m_objOpt));
    
    // Paste the data starting at cell A1.
                m_objSheets = (Excel.Sheets)m_objBook.Worksheets;
                m_objSheet = (Excel._Worksheet)(m_objSheets.get_Item(1));
                m_objRange = m_objSheet.get_Range("A1", m_objOpt);
                m_objSheet.Paste(m_objRange, false);
    
    // Save the workbook and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book5.xls", m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
                    m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Create_TextFile()
            {
                // Connect to the data source.
                System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection( 
                    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strNorthwind + ";");
                objConn.Open();
    
    // Execute a command to retrieve all records from the Employees  table.
                System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand( 
                    "Select * From Employees", objConn);
                System.Data.OleDb.OleDbDataReader objReader;
                objReader = objCmd.ExecuteReader();
    
    // Create the FileStream and StreamWriter object to write 
                // the recordset contents to file.
                System.IO.FileStream fs = new System.IO.FileStream(
                    m_strSampleFolder + "Book6.txt", System.IO.FileMode.Create);
                System.IO.StreamWriter sw = new System.IO.StreamWriter(
                    fs, System.Text.Encoding.Unicode);
    
    // Write the field names (headers) as the first line in the text file.
                sw.WriteLine(objReader.GetName(0) +  "\t" + objReader.GetName(1) +
                    "\t" + objReader.GetName(2) + "\t" + objReader.GetName(3) +
                    "\t" + objReader.GetName(4) + "\t" + objReader.GetName(5));
    
    // Write the first six columns in the recordset to a text file as
                // tab-delimited.
                while(objReader.Read()) 
                {
                    for(int i=0;i<=5;i++)
                    {
                        if(!objReader.IsDBNull(i))
                        {
                            string s;
                            s = objReader.GetDataTypeName(i);
                            if(objReader.GetDataTypeName(i)=="DBTYPE_I4")
                            {
                                sw.Write(objReader.GetInt32(i).ToString());
                            }
                            else if(objReader.GetDataTypeName(i)=="DBTYPE_DATE")
                            {
                                sw.Write(objReader.GetDateTime(i).ToString("d"));
                            }
                            else if (objReader.GetDataTypeName(i)=="DBTYPE_WVARCHAR")
                            {
                                sw.Write(objReader.GetString(i));
                            }
                        }
                        if(i<5) sw.Write("\t");
                    }
                    sw.WriteLine(); 
                }
                sw.Flush();// Write the buffered data to the FileStream.
    
    // Close the FileStream.
                fs.Close();
    
    // Close the reader and the connection.
                objReader.Close();
                objConn.Close(); 
    
    // ==================================================================
                // Optionally, automate Excel to open the text file and save it in the
                // Excel workbook format.
    
    // Open the text file in Excel.
                m_objExcel = new Excel.Application();
                m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;
                m_objBooks.OpenText(m_strSampleFolder + "Book6.txt", Excel.XlPlatform.xlWindows, 1, 
                    Excel.XlTextParsingType.xlDelimited, Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
                    false, true, false, false, false, false, m_objOpt, m_objOpt, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, m_objOpt);
    
    m_objBook = m_objExcel.ActiveWorkbook;
    
    // Save the text file in the typical workbook format and quit Excel.
                m_objBook.SaveAs(m_strSampleFolder + "Book6.xls", Excel.XlFileFormat.xlWorkbookNormal, 
                    m_objOpt, m_objOpt, m_objOpt, m_objOpt, Excel.XlSaveAsAccessMode.xlNoChange, m_objOpt, m_objOpt,
                    m_objOpt, m_objOpt, m_objOpt);
                m_objBook.Close(false, m_objOpt, m_objOpt);
                m_objExcel.Quit();
    
    }
    
    private void Use_ADONET()
            {
                // Establish a connection to the data source.
                System.Data.OleDb.OleDbConnection objConn = new System.Data.OleDb.OleDbConnection(
                    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + m_strSampleFolder +
                    "Book7.xls;Extended Properties=Excel 8.0;");
                objConn.Open();
    
    // Add two records to the table named 'MyTable'.
                System.Data.OleDb.OleDbCommand objCmd = new System.Data.OleDb.OleDbCommand();
                objCmd.Connection = objConn;
                objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
                    " values ('Bill', 'Brown')";
    
    objCmd.ExecuteNonQuery();
                objCmd.CommandText = "Insert into MyTable (FirstName, LastName)" +
                    " values ('Joe', 'Thomas')";
                objCmd.ExecuteNonQuery();
    
    // Close the connection.
                objConn.Close(); 
    
    } 
    
    }  // End Class
    }// End namespace
    
    

    Hinweis: Sie müssen den Code in Visual Studio 2005 ändern. Visual C# fügt dem Projekt standardmäßig ein Formular hinzu, wenn Sie ein Windows Forms Projekt erstellen. Das Formular heißt "Form1". Die beiden Dateien, die das Formular darstellen, heißen "Form1.cs" und "Form1.designer.cs". Sie schreiben den Code in Form1.cs. In der Datei "Form1.designer.cs" schreibt der Windows Forms-Designer den Code, der alle Aktionen implementiert, die Sie durch Ziehen und Ablegen von Steuerelementen aus der Toolbox ausgeführt haben.

    Weitere Informationen zum Windows Forms-Designer in Visual C# 2005 finden Sie auf der folgenden Microsoft Developer Network (MSDN)-Website:

    Erstellen eines Projekts (Visual C#) Hinweis Wenn Sie Office nicht im Standardordner (C:\Programme\Microsoft Office) installiert haben, ändern Sie die m_strNorthwind Konstante im Codebeispiel so, dass sie ihrem Installationspfad für "Northwind.mdb" entspricht.

  9. Fügen Sie den Using-Direktiven in Form1.cs Folgendes hinzu:

    using System.Reflection;
    using System.Runtime.InteropServices;
    using Excel = Microsoft.Office.Interop.Excel;
    
  10. Drücken Sie zum Erstellen und Ausführen des Beispiels F5.

References

Weitere Informationen hierzu finden Sie auf folgender Website von Microsoft:

Microsoft Office-Entwicklung mit Visual Studio