2017-10-30 1 views
1

Ich habe ein einfaches Standalone-Programm für die Arbeit, die Netzlaufwerke automatisch zugeordnet. Das Programm verwendet eine DataGridView, um alle Laufwerksbuchstaben und -pfade aufzulisten und der Code, den ich geschrieben habe, liest die Einträge in DataGridView und ordnet die Laufwerke basierend darauf zu - auch den Laufwerksbuchstaben und Pfad von einem bestimmten Excel-Blatt.So importieren Sie bestimmte Spalten und Zeilen von Excel-Daten zu DataGridview WITHOUT OLEDB in C#

Diese spezifische Excel-Datei verfolgt bestimmte Informationen des Computers eines Benutzers mit VB-Code. Auf dem dritten Arbeitsblatt mit dem Namen "Laufwerke" befinden sich die Netzwerklaufwerke. Laufwerksbuchstabe und Pfad befinden sich in Spalte C und D. Vor Zeile 3 werden keine Header außer dem Namen "Netzwerklaufwerke" angezeigt Nach Zeile 29 beginnen leider Einträge für Outlook PST-Dateien.

Mit meinem begrenzten Wissen über C# (Ich bin neu in C#), ich schaffte es irgendwie, diese zu erstellen:

public void FileSelect() 
    { 
     string filePath = string.Empty; 
     string fileExt = string.Empty; 
     OpenFileDialog file = new OpenFileDialog(); //open dialog to choose file 
     file.Filter = "Discovery Excel|*.xlsm| CSV (Coming Soon)| *.csv"; 
     file.Title = "Please select a valid data file"; 

     if (file.ShowDialog() == System.Windows.Forms.DialogResult.OK) //if there is a file choosen by the user 
     { 
      filePath = file.FileName; //get the path of the file 
      fileExt = Path.GetExtension(filePath); //get the file extension 
      if (fileExt.CompareTo(".xls") == 0 || fileExt.CompareTo(".xlsm") == 0) 
      { 
       try 
       { 

        DataTable dtExcel = new DataTable(); 
        dtExcel = ReadExcel(filePath, fileExt); //read file 
        InfoTB.Visible = false; 
        dataGridView1.Visible = true; 
        FileSelectBT.Visible = false; 
        ManualBT.Visible = false; 
        RunBT.Visible = true; 
        ExitBT.Visible = true; 
        RunBT.Location = new System.Drawing.Point(109, 334); 
        ExitBT.Location = new System.Drawing.Point(190, 334); 
        dataGridView1.DataSource = dtExcel; 
        dataGridView1.AutoResizeColumns(); 
        dataGridView1.Columns[0].HeaderText = "Drive Letter"; 
        dataGridView1.Columns[1].HeaderText = "Drive Path"; 
        for (int i = 1; i < dataGridView1.RowCount - 1; i++) 
        { 
         if (dataGridView1.Rows[i].Cells[0].Value.ToString() == "" || dataGridView1.Rows[i].Cells[1].Value.ToString() == "") 
         { 
          dataGridView1.Rows.RemoveAt(i); 
          i--; 
         } 
        } 

       } 
       catch (Exception ex) 
       { 
        MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error); 
        ManualMode(); 
        OpenExcel(filePath); 
        TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file 
        txt.Write(ex.ToString()); 
        txt.Close(); 
       } 
      } 
      else 
      { 
       MessageBox.Show("Please choose .xlsm or .CSV file only.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error); //custom messageBox to show error 
      } 
     } 
    } 


    public DataTable ReadExcel(string fileName, string fileExt) 
    { 
     string conn = string.Empty; 
     DataTable dtexcel = new DataTable(); 
     conn = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source =" + fileName + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1\";"; //loading the Access engine to load/read the Excel file 
     using (OleDbConnection con = new OleDbConnection(conn)) 
     { 
      try 
      { 
       OleDbDataAdapter oleAdpt = new OleDbDataAdapter("Select TOP 24 F3,F4 FROM [Drives$]", conn); //read data from sheet 3 which should be the drives 
       oleAdpt.Fill(1, 24, dtexcel); //fill excel data into dataTable 
      } 
      catch (InvalidOperationException ex) 
      { 
       MessageBox.Show("Oops! Something went wrong! We'll make a log of that.\nDon't worry, we'll open the Excel File and switch to manuel mode for you!", "FAIL!", MessageBoxButtons.OK, MessageBoxIcon.Error); 
       ManualMode(); 
       OpenExcel(fileName); 
       TextWriter txt = new StreamWriter(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)+ "NDrive_Error_Log.txt"); //Saving the info from the results textbox to an actual text file 
       txt.Write(ex.ToString()); 
       txt.Close(); 
      } 
     } 
     return dtexcel; 
    } 

Und dieser Code hat funktioniert!

Here's photo of what the program looks like when it has some entries

Leider ist die Microsoft.ACE.OLEDB.12.0 nicht zuverlässig, wenn es um die Bewegung des Programms von einem Computer zum anderen kommt. Ich bin nicht in der Lage, ACE auf jedem Computer bei der Arbeit zu installieren, also muss ich eine andere Methode finden, um die Excel-Dateien spezifisch zu lesen, ohne OLEDB zu verwenden.

Ich habe mich umgesehen, um eine alternative Lösung zu finden, aber die Sachen, die ich gefunden habe, schienen sich auf bestimmte Startreihen anstatt auf die Endreihen zu konzentrieren.

Obwohl, um fair zu sein, ich bin neu in C#, also habe ich vielleicht etwas übersehen, das mit meinem Programm helfen würde.

Das heißt, gibt es eine Alternative zu OLEDB für diese Situation?

+0

Für den Anfang gibt es [Excel Interop] (https: // msdn. microsoft.com/library/microsoft.office.interop.excel(v=vs.140).aspx) & auch mehrere Bibliotheken, die Sie bei Google finden können - ein weiterer Ausgangspunkt: http://nugetmusthaves.com/Tag/Excel – PaulF

+0

Ja, ich dachte mir, dass ich etwas übersehen habe. Ich habe sie übersehen, weil ich keine Dokumentation darüber finden konnte, was ich wollte, ein großer Fehler meinerseits. Nun, ich werde jetzt mehr Übungsprogramme machen, damit ich besser verstehen kann, wie Excel besser funktioniert. Danke für die Links! – The57thGamer

Antwort

0

Wie in den Kommentaren von PaulF erwähnt, ist Excel Interop eine mögliche Lösung, die die Notwendigkeit der Verwendung externer Bibliotheken erspart.

wird wie folgt unter der Annahme, dass Ihre Daten immer in C3:D29 sein wird, und geht auch davon aus, dass die Daten in dem Arbeitsblatt gültig ist:

public DataTable ReadExcel(string fileName) 
{ 
    var excel = new Excel.Application(); 
    var wkb = excel.Workbooks.Open(fileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
           Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, 
           Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing); 

    var sheet = wkb.Sheets["Drives"] as Excel.Worksheet; 

    var range = sheet.Range[sheet.Cells[3, 3], sheet.Cells[29, 4]]; 
    var data = range.Value2; 

    var dt = new DataTable(); 
    dt.Columns.Add("Drive"); 
    dt.Columns.Add("Path"); 

    for (int i = 1; i <= range.Rows.Count; i++) 
    { 
     dt.Rows.Add(data[i, 1], data[i, 2]); 
    } 

    return dt; 
} 
+1

Danke! Arbeitete perfekt! Obwohl es mir etwas peinlich ist, dass die Antwort in meinem Gesicht war, als ich mich umsah. Ich dachte mir, dass ich etwas übersehen habe. Nun, ich verstehe, wie der Code funktioniert, obwohl ich mehr Übungsprogramme wie dieses machen werde, damit ich besser verstehen kann, wie Excel besser funktioniert. Wie auch immer, danke nochmal! – The57thGamer

+0

@ The57thGamer Ich persönlich habe etwas wie EPPlus empfohlen, solange Sie mit einer externen Bibliothek arbeiten - es macht die Interaktion mit Excel viel einfacher als mit Interop – Chawin

+0

@Chawin Ich bekomme Fehler Kann nicht Indizierung mit [] auf eine anwenden Ausdruck des Typs bei Zeile 'dt.Rows.Add (Daten [i, 1], Daten [i, 2]);' – sam

Verwandte Themen