C# Progressbar / Fortschrittsanzeige fuer Datenimport in Excel

palaber

Captain
Registriert
Juni 2006
Beiträge
3.856
Hello Leute,

ich hab mal wieder ein neues Problem. Bin gerade dabei mir meine Aufgaben für morgen zurecht zu legen. Und zwar möchte ich morgen eine Progressbar implementieren, welche mir den Fortschritt vom import von Daten in Excel anzeigt.

Meine bisherige Suche hat mir nie etwas für meine Vorgehensweise geliefert. Ich schreibe die Daten von einem / mehreren Arrays in verschiedene Bereiche eines Datenblattes. Umsetzen tu ich dies meistens mit for-Schleifen.
Ich habe den Code mal angehängt. Ich selber hab mich hierbei bei MSDN bedient und den Code an meine Bedürfnisse angepasst.

Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;

namespace WindowsFormsApplication1
{
    class UseExcel
    {
        public void safeDataToExcel(string[] arrSetData, double[] arrNAData)
        {
            Excel.Application oXL;
            Excel._Workbook oWB;
            Excel._Worksheet oSheet;
            Excel.Range oRng;
            string sTimeStamp = Convert.ToString(DateTime.Now);

            int iCount = 0;

            //Clean the TimeStampstring
            ChangeString cS = new ChangeString();
            sTimeStamp = cS.cleanTimestamp(sTimeStamp);

            //Start Excel and get Application object.
            oXL = new Excel.Application();
            oXL.Visible = false;

            //Open the existing Excel worksheet
            oWB = oXL.Workbooks.Open(@"D:\C#\IITAv1\test\Excel_Files\IITS_Data_File_Template.xlsx");
            
            // write AUTO to excelfile
            if (arrSetData.Last() == "auto")
            {
                oSheet = (Excel._Worksheet)oWB.Worksheets.get_Item(2);  //open the second worksheet (LearnedLimits)

                //Description, Startfrequenz, Stopfrequenz
                for (int i = 1; i < 6; i++)
                {
                    oSheet.Cells[i, 1] = arrSetData[iCount];
                    iCount++;
                }

                oSheet.Cells[7, 1] = arrSetData[iCount];
                iCount++;

                for (int i = 9; iCount < (arrSetData.Length-1); i++)
                {
                    oSheet.Cells[i, 1] = arrSetData[iCount];
                    iCount++;
                }

                iCount = 0;
                for (int i = 9; iCount < arrNAData.Length; i++)
                {
                    oSheet.Cells[i, 2] = arrNAData[iCount];
                    iCount++;
                }

                //AutoFit columns A:B.
                oRng = oSheet.get_Range("A1", "B1");
                oRng.EntireColumn.AutoFit();
            }
            
            // write MANUAL to the excel sheet
            else
            {
                oSheet = (Excel._Worksheet)oWB.Worksheets.get_Item(1);  //open the first worksheet (ManualLimits)

                //Description, Startfrequenz, Stopfrequenz
                iCount = 1;
                for (int i = 3; i < 6; i++)
                {
                    oSheet.Cells[i, 1] = arrSetData[iCount];
                    iCount++;
                }

                //Limit 1 (4 Values)
                iCount = 5;
                for (int i = 8; i < 12; i++)
                {
                    oSheet.Cells[i, 1] = arrSetData[iCount];
                    iCount++;
                }

                if (arrSetData.Length >= 13)
                {
                    //Limit 2 (4 Values)
                    iCount = 9;
                    for (int i = 13; i < 17; i++)
                    {
                        oSheet.Cells[i, 1] = arrSetData[iCount];
                        iCount++;
                    }
                }

                if (arrSetData.Length >= 17)
                {
                    //Limit 3 (4 Values)
                    iCount = 13;
                    for (int i = 18; i < 22; i++)
                    {
                        oSheet.Cells[i, 1] = arrSetData[iCount];
                        iCount++;
                    }
                }

                if (arrSetData.Length == 21)
                {
                    //Limit 4 (4 Values)
                    iCount = 17;
                    for (int i = 23; i < 27; i++)
                    {
                        oSheet.Cells[i, 1] = arrSetData[iCount];
                        iCount++;
                    }
                }

                iCount = 0;

                //Fill A28:A428 with an array of values (the values of the points).
                for (int i = 28; iCount < arrNAData.Length; i++)
                {
                    oSheet.Cells[i, 1] = arrNAData[iCount];
                    iCount++;
                }

                //AutoFit columns A:B.
                oRng = oSheet.get_Range("A1", "B1");
                oRng.EntireColumn.AutoFit();
            }
           
            //Save the Data to following path / filename (Partno + Timestamp)
            oWB.SaveAs(@"D:\C#\IITAv1\test\Excel_Files\" + arrSetData[0] + "_" + sTimeStamp + ".xlsx");

            oWB.Close();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(oXL);
            GC.Collect();
        }
    }
}

Das ganze rufe ich über einen Button auf.
Code:
private void buttonSave_Click(object sender, EventArgs e)
        {
            try
            {
                labelResult.Text = "SAVE FILE";
                groupBoxResult.BackColor = Color.LightGray;
                UseExcel uE = new UseExcel();

                if (arrDataInput.Last() == "auto")
                {
                    uE.safeDataToExcel(arrDataInput, arrDoubleNAData);
                }

                else
                {
                    uE.safeDataToExcel(arrDataInput, arrDoubleNAData);
                }

                MessageBox.Show("File saved!");
            }

            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex);
            }
        }
Wie gesagt, wenn auf diesen Button geklickt wird, soll die Fortschrittsanzeige durchlaufen. Ich bin mir jetzt nicht mal sicher, ob es für meine "Methode" Daten in Excel zu schreiben, eine Möglichkeit gibt die Fortschrittsanzeige zu aktuallisieren.

Kennt ihr gute Tutorials? Oder evtl. Lösungsansätze, die ich mir anschauen kann? Oder habt selber ne Idee? Bin nicht so das Programmierass! :rolleyes:
Vielen Dank!
 
Hi,

damit deine Benutzerobfläche noch reagiert, während die Daten importiert werden, solltest du die Aktion in einen Thread auslagern:

Code:
using System.Threading;
...
Thread t = new Thread( () => uE.safeDataToExcel(arrDataInput, arrDoubleNAData) );
t.isBackground = true;
t.start();

Dann kannst du in der Benutzeroberfläche einen Timer starten, der regelmäßig den Fortschritt ausliest und den Wert an die ProgressBar gibt. Der Timer hat den Vorteil, dass er im UI-Thread läuft. Vom erzeugten Thread darfst du nicht auf die ProgressBar zugreifen. Den Fortschritt musst du selber ermitteln und in einer Varible speichern, auf die der Timer zugreifen kann.
 
Zuletzt bearbeitet:
Du könntest dir auch mal die Klasse BackgroundWorker ansehen:

Link

Der BackgroundWorker bietet von Haus aus ein Callback-Event ProgressChanged, welches durch die Methode ReportProgress(int) ausgelöst wird. Somit kannst du dem UI-Thread jederzeit den Fortschritt aus dem Worker-Thread melden.

Im Gegensatz zu Lösung von michi.o musst du nicht auf einer Variable arbeiten, auf die beide Threads zugreifen, da die Logik schon im BackgroundWorker via Eventhandler enthalten ist.

Schau dir einfach mal die Beispiele (das erste ist ganz simpel) im Link an.
 
Danke schonmal. Ja das mit dem Threading habe ich mir auch schon ueberlegt. Aber
ich glaub ich brauch das nicht, waehrend des Speicherns soll der User naemlich nix machen koennen ;)
Aber das muss ich mir noch ueberlegen. Mir geht es erstmal darum zu verstehen wie ich am besten eine Progessbar implementiere.
Den Link schaue ich mir gleich mal an!

EDIT:
Also mir hat dieses Tutorium sehr gut geholfen. Ist zwar VB, aber macht ja kaum nen unterschied.
Die Funktionsweise kann man hier sehr gut nachvollziehen, wie ich finde.
http://www.youtube.com/watch?v=RMIOVVLhUvE
 
Zuletzt bearbeitet:
Hier stand Müll. ;)

Edit: Habe gedacht du meinst den Code aus meinem Link, aber du meinst mit VB ja das Video^^
 
Zuletzt bearbeitet:
Yop, danke, aber ich bin generell nicht so fit in Programmieren. Und man hat in dem Video einfach sehr gut gesehen was sich wie auswirkt. War ja nur so gepostet, falls mal jemand hier rein schaut mit aehnlichen fragen.

Ich habe es jetzt uebrigens so geloest, das ich einfach in der Klasse, die mir alles in Excel schreibt eine Variable deklariert habe, welche ich mit dem BackgroundWorker solange abrufe, bis die Aufgabe erledigt ist.
Die Variable wird mit ner Formel gefuettert, welche immer so grob den prozentualen Fortschritt pro Loop / Anweisung angibt. Klappt super.
 

Ähnliche Themen

Zurück
Oben