Entwickler-Ecke

WinForms - Excel Werte aulesen, ComException


herrfuchs - Mo 07.01.13 13:10
Titel: Excel Werte aulesen, ComException
Hallo,

ich bekomme immer eine ComException Fehlermeldung, habe schon danach gegooglt finde aber keine Lösung dazu.

Verwende Office 2007.

Methode, zum Auslesen der Excel Datei:

Soll die Spalte x und x+1 aulesen und in das 2 Dimensionale Array speichern

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
 public double[,] LesenArraySpalte(string dateiname, int spalte)
        {
            double[,] werte = new double[8000,2];
            this.myExcelApplication = new Excel.Application();
            this.myExcelWorkbook = (Excel.Workbook)myExcelApplication.Workbooks.Open(Environment.CurrentDirectory + "\\Excel\\" + dateiname);
            this.myExcelWorkSheet = (Excel.Worksheet)myExcelWorkbook.ActiveSheet;
            //SetNewCurrentCulture();
            try
            {              
                //Excel Werte auselesen
                range = myExcelWorkSheet.UsedRange;
                for (int i = 0; i <= range.Rows.Count; i++)
                {
                    werte[i, 0] = (double)(range.Cells[i+4, spalte] as Excel.Range).Value2;
                    werte[i, 1] = (double)(range.Cells[i+4, spalte+1as Excel.Range).Value2;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Exception: " + ex);
            }  
            //ResetCurrentCulture();
            this.myExcelApplication.Quit();
            closeExcel();           

            return werte;
        }


Fehlermeldung:

C#-Quelltext
1:
Message  "Ausnahme von HRESULT: 0x800A03EC"                    


Edit:
Hätte Solution 1 probiert, bin mir aber nicht sicher wo ich die Methoden aufrufen muss, siehe oben:
http://www.made4dotnet.com/Default.aspx?tabid=141&aid=15

Edit2:
Habe folgende Zeile geändert:

statt werte[i+4] --> werte[i] und range.Cells[i, spalte] --> range.Cells[i+4, spalte]


C#-Quelltext
1:
2:
werte[i, 0] = (double)(range.Cells[i+4, spalte] as Excel.Range).Value2;
werte[i, 1] = (double)(range.Cells[i+4, spalte+1as Excel.Range).Value2;


C#-Quelltext
1:
Die Funktionsauswertung wurde deaktiviert, weil bei einer vorhergehenden Funktionsauswertung das Timeout überschritten wurde. Sie müssen die Ausführung fortsetzen, um die Funktionsauswertung wieder zu aktivieren.}  System.Exception {Microsoft.CSharp.RuntimeBinder.RuntimeBinderException                    



MfG


Th69 - Mo 07.01.13 13:59

Hallo

evtl. hilft dir Bei Zugriff auf Range in Excel kommt eine Exception 0x800A03EC [http://meinews.niuz.biz/bei-t458010.html] ?


Ralf Jansen - Mo 07.01.13 14:14

Zitat:
for (int i = 0; i <= range.Rows.Count; i++)


Egal ob jetzt COM bei Arrays 0 oder 1 basiert ist (ich glaube es war 1-basiert). Eine Schleife von 0 bis einschließlich Count ist jedenfalls immer ein Element zuviel. Und wenn COM nicht knallt spätestens dein werte Array sollte knallen.

Bei welchem Call bekommst du denn die Exception? Und wenn es bei einem der Cell Zugriffe ist bei welchem Element(i,Spalte) passiert das.


herrfuchs - Mo 07.01.13 22:01

Danke, irgendwie funktioniert es jetzt die Fehlermeldung kommt nicht mehr ;)

Hat jemand eine Idee wie man das Auslesen beschleunigen kann?
Es liest 16.000 Werte aus und die Methode wird öfter aufgerufen, insegsamt dauert es ca. 2Min.
Die Werte werden eig ziemlich schnelle ausgelesen, jedoch die Übergabe von der Range in in das Array dauert sehr lange.

MfG


Ralf Jansen - Di 08.01.13 00:25

Zitat:
Hat jemand eine Idee wie man das Auslesen beschleunigen kann?


Nicht COM verwenden? Jeder Zellenzugriff ist ein COM Aufruf das kann nicht schnell sein. Ob das jetzt so langsam sein muss wie du feststellst kann ich aber gerade nicht beurteilen. Ein Datenbankzugriff über ADO.Net auf das Excelsheet sollte aber wesentlich schneller sein.


herrfuchs - Mi 09.01.13 12:55

Danke


herrfuchs - Do 10.01.13 11:44

Ich habe jetzt noch ein kleines Problem, das Auslesen geht schon wesentlich schneller.
Jedoch soll er jetzt noch Abfragen ob in der Saplte des Tables Werte stehen, wenn nicht soll das Array mit 0 initialisiert. Ich weiß aber nicht wie ich die Werte in den einzelenen Spalten abfragen kann, ich habe schon einiges probiert aber es klappt nicht, jetzt springt er immer in den ELSE Zweig


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
        double[,] werte = new double[80002];
           
            table = excel.excelAbfrage(dateiname);

            //DateTime StartZeit = DateTime.Now;
            for (int j = 0; j < 10; j+=2)
            {                    
                if (table.Columns.IndexOf(j.ToString()) != -1//Funktioniert nicht
                {
                    int i = 0;
                    foreach (DataRow r in table.Rows)
                    {
                        werte[i, 0] = Convert.ToDouble(r[j]);
                        werte[i, 1] = Convert.ToDouble(r[j + 1]);                                        

                        i++;
                    }

                }
                else
                {
                    for (int i = 0; i < 8000; i++)
                    {
                        werte[i, 0] = 0//Fehlermeldung: InvalidCastException
                                         //Ein Objekt kann nicht von DBNull in andere Typen umgewandelt werden.
                        werte[i, 1] = 0;
                    }
                }             
                //Funktionsaufruf wo das Array Werte übergeben wird
            }


Edit habe es schon gelöst:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
foreach (DataRow r in table.Rows)
                    {
                        if (r[j] == DBNull.Value)
                        {
                            for (int k = 0; k < 8000; k++)
                            {
                                werte[k, 0] = 0;
                                werte[k, 1] = 0;
                            }
                            break;
                        }
                        werte[i, 0] = Convert.ToDouble(r[j]);
                        werte[i, 1] = Convert.ToDouble(r[j + 1]);                                        

                        i++;


MfG Herrfuchs