2010-06-22 7 views
13

Ich schreibe eine Funktion zum Exportieren von Daten nach Excel mit dem Office-Interop in VB .NET. Ich schreibe zur Zeit die Zellen direkt die Zellen der Excel-Arbeitsblatt() -Methode:Schnellste Möglichkeit zum Schreiben von Zellen in Excel mit Office Interop?

worksheet.Cells(rowIndex, colIndex) = data(rowIndex)(colIndex) 

Dies ist eine lange Zeit für große Datenmengen nehmen. Gibt es eine schnellere Möglichkeit, viele Daten gleichzeitig in Excel zu schreiben? Würde etwas mit den Bereichen schneller sein?

+0

Dieses Beinahe-Duplikat hat umfangreiche Antworten: http://stackoverflow.com/questions/3840270/fastest-way-to-interface-between-live-unsaved-excel-data-and-c-sharp-objects. – Govert

Antwort

28

Sie sollten vermeiden, Zelle für Zelle zu lesen und zu schreiben, wenn Sie können. Es ist viel schneller, mit Arrays zu arbeiten und ganze Blöcke gleichzeitig zu lesen oder zu schreiben. Ich schrieb einen Beitrag vor einer Weile zurück auf reading from worksheets using C#; Im Grunde funktioniert der gleiche Code umgekehrt (siehe unten) und läuft viel schneller, insbesondere bei größeren Datenblöcken.

var sheet = (Worksheet)Application.ActiveSheet; 
    var range = sheet.get_Range("A1", "B2"); 
    var data = new string[3,3]; 
    data[0, 0] = "A1"; 
    data[0, 1] = "B1"; 
    data[1, 0] = "A2"; 
    data[1, 1] = "B2"; 
    range.Value2 = data; 
+1

Ich konnte keinen Kommentar zu deinem Blog hinterlassen, also lass mich es hier schreiben. Sie können ein 1-basiertes Array in C# mit der CreateInstance-Methode erstellen: var arr = (Objekt [,]) Array.CreateInstance (typeof (Objekt), neues int [] {2, 3}, neues int [] {1 , 1}) – IMil

10

Wenn nicht, stellen Sie sicher, dass Sie Application.ScreenUpdating = false festlegen, bevor Sie mit der Ausgabe Ihrer Daten beginnen. Dies wird die Dinge viel schneller machen. Setzen Sie es auf True zurück, wenn Sie mit der Ausgabe Ihrer Daten fertig sind. Das erneute Zeichnen des Bildschirms bei jedem Zellenwechsel dauert ein gutes Stück Zeit, das Umgehen spart dies.

Wie bei der Verwendung von Bereichen müssen Sie immer noch 1 (eine) spezifische Zelle für einen Wert anvisieren, sodass ich hier keinen Vorteil sehe. Ich bin mir nicht bewusst, dass dies schneller geht als das, was Sie tun, um die Daten tatsächlich auszugeben.

5

Nur um Tommys Antwort hinzuzufügen.

  • Sie können die Berechnung auch auf manuell einstellen, bevor Sie mit dem Schreiben beginnen.

Application.Calculation = xlCalculationManual

Und es zurück auf automatisch gesetzt, wenn Sie mit Ihrem Schreiben fertig sind. (Wenn es eine Chance, dass der ursprüngliche Modus etwas anderes als automatische gewesen sein könnte, werden Sie diesen Wert speichern müssen, bevor sie auf manuelle Einstellung)

Application.Calculation = xlCalculationAutomatic

  • Sie können auch die CopyFromRecordset-Methode des Range-Objekts verwenden.

http://msdn.microsoft.com/de-de/library/microsoft.office.interop.excel.range.copyfromrecordset(office.11).aspx

2

Ehrlich gesagt, ist der schnellste Weg, es zu schreiben ist mit Komma Trennzeichen. Es ist einfacher, eine Reihe von Feldern mit der ToString-Methode Join (",") zu schreiben, anstatt zu versuchen, Zellen zu durchlaufen. Speichern Sie die Datei dann als ".csv". Öffnen Sie die Datei als csv, indem Sie die Datei interop öffnen, damit die Zelle beim Öffnen automatisch aktualisiert wird.

+3

Wenn Geschwindigkeit ist was du willst, dann ist dies der Weg zu gehen, aber es gibt vor allem um Zeichenfolgen und Sonderzeichen gotchas –

+0

Funktioniert das, wenn Sie in Formeln schreiben möchten? –

3

Der schnellste Weg zum Schreiben und Lesen von Werten aus Excel-Bereichen ist Range.get_Value und Range.set_Value.

Die Art und Weise ist, wie unten:

Range filledRange = Worksheet.get_Range("A1:Z678",Missing); 
object[,] rngval = (object[,]) filledRange.get_Value (XlRangeValueDataType.xlRangeValueDefault); 

Range Destination = Worksheet2.get_Range("A1:Z678",Missing); 
destination.set_Value(Missing,rngval); 

und ja, keine Iteration erforderlich.Leistung ist nur voila !!

Hoffe es hilft !!

0

Falls jemand wie ich nach einer vollständigen Lösung sucht, die die Methode von @Mathias (die für das Laden in Excel am schnellsten zu sein scheint) verwendet, mit @ IMils Vorschlag für das Array.
Hier gehen Sie:

'dt (DataTable) is the already populated DataTable 
'myExcelWorksheet (Worksheet) is the worksheet we are populating 
'rowNum (Integer) is the row we want to start from (usually 1) 
Dim misValue As Object = System.Reflection.Missing.Value 
Dim arr As Object = DataTableToArray(dt) 
'Char 65 is the letter "A" 
Dim RangeTopLeft As String = Convert.ToChar(65 + 0).ToString() + rowNum.ToString() 
Dim RangeBottomRight As String = Convert.ToChar(65 + dt.Columns.Count - 1).ToString() + (rowNum + dt.Rows.Count - 1).ToString() 
Dim Range As String = RangeTopLeft + ":" + RangeBottomRight 
myExcelWorksheet.Range(Range, misValue).NumberFormat = "@" 'Include this line to format all cells as type "Text" (optional step) 
'Assign to the worksheet 
myExcelWorksheet.Range(Range, misValue).Value2 = arr 

Dann

Einschränkungen umfassen so dass nur 26 Spalten, bevor es für die kommenden mit den Bereichswert Buchstaben besseren Code benötigen würde.

Verwandte Themen