2012-06-14 15 views
6

Ich versuche, ein Programm zu erstellen, das Spalten in einem DataSet löscht, das von einer Excel-Datei gefüllt wird. Die Art, wie Spalten gelöscht werden, ist der Vergleich der Kopfzeile in jeder Spalte mit dem ersten Element in jeder Zeile und das Löschen der Spalte einer beliebigen Zeichenfolge, die nicht in den Zeilen erscheint. Mein Problem ist, dass ich einen seltsamen Fehler bekomme, den ich nicht verstehen kann. es heißt:Der Aufruf des Konstruktors für den Typ, der den angegebenen Bindungseinschränkungen entspricht, hat eine Ausnahme ausgelöst

Der Aufruf des Konstruktors für den Typ 'Excel_Retriever.MainWindow', der den angegebenen Bindungseinschränkungen entspricht, hat eine Ausnahme ausgelöst. ' Zeilennummer '3' und Zeilenposition '9'.

Ich bin neu in C# und XAML und würde wirklich jede Hilfe bei der Lösung dieses Fehlers zu schätzen wissen. Vielen Dank! Hier ist mein Code:

XAML:

<Window x:Class="Excel_Retriever.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid Name="ExcelGrid"> 
     <DataGrid ItemsSource="{Binding}" AutoGenerateColumns="True" Height="289"  HorizontalAlignment="Left" Margin="10,10,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="481" /> 
    </Grid> 
</Window> 

C#:

namespace Excel_Retriever 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataSet excel = GetDataTableFromExcel("C:\\Users\\Sweet Lou\\Desktop\\Adjusted research info.xlsx", "Research"); 
      //dataGrid1.DataContext = excel.Tables[0]; 
      DataSet ignoreds = Ignore_Names(excel); 
      dataGrid1.DataContext = ignoreds.Tables[0]; 
     } 

     public DataSet GetDataTableFromExcel(string FilePath, string strTableName) 
     { 
      try 
      { 
       OleDbConnection con = new OleDbConnection("Provider= Microsoft.ACE.OLEDB.12.0;Data Source=" + FilePath + "; Extended Properties=\"Excel 12.0;HDR=YES;\""); 
       OleDbDataAdapter da = new OleDbDataAdapter("select * from [Sheet1$]", con); 
       DataSet ds = new DataSet(); 
       da.Fill(ds); 
       return ds; 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
      return null; 
     } 

     public DataSet Ignore_Names(DataSet sheet) 
     { 
      DataSet ignoreds = sheet; 
      DataColumn columnNames = sheet.Tables[0].Columns["Name"]; //first column with names 
      //ignoreds.Tables[0].Columns.Add(columnNames); 
      int j = 1; 
      for (int i = 0; i < 15; i++) //change 15 to variable 
      { 
       while (String.Compare(columnNames.Table.Rows[i].ToString(), sheet.Tables[0].Columns[j].ColumnName, true) != 0) 
       { 
        ignoreds.Tables[0].Columns.RemoveAt(j); 
        j++; 
       } 
       j++; 
      } 
      return ignoreds; 
     } 
    } 
} 
+1

Wrap-Anschluss und -Adapter mit einem mit Block zu lernen. – abatishchev

Antwort

3

Sie brauchen nicht strTableName auf Ihre Methode zu übergeben, wie Sie es nie verwenden.

Wenn Sie @ "" für Strings verwenden, müssen Sie die Dinge nicht umgehen: @ "c: \ users ....";

Sie erhalten eine Ausnahme, weil Sie versuchen, Zeilen zu replizieren, die nicht wirklich existieren. So sollte Ihre Methode aussehen, wenn ich Ihr Ziel hier richtig verstehe.

public static void Ignore_Names(DataSet sheet) { 
     var table = sheet.Tables[0]; 
     var columns = table.Columns; 
     var nameColumn = columns["Name"]; 

     var names = new List<string>(); 
     foreach (DataRow row in nameColumn.Table.Rows) 
      names.Add(row[0].ToString().ToLower()); 

     // Work from right to left. If you delete column 3, is column 4 now 3, or still 4? This fixes that issue. 
     for (int i = columns.Count - 1; i >= 0; i--) 
      if (!names.Contains(columns[i].ColumnName.ToLower())) 
       columns.RemoveAt(i); 
    } 

Auch in Mainwindow-Konstruktor, sollten Sie dies nur tun, nachdem Sie Excel gesetzt:

Ignore_Names(excel);  
    dataGrid1.ItemsSource = excel.Tables[0].DefaultView; 

Bitte beachte, dass ich Itemssource bin Einstellung nicht Datacontext, und ich bin die Default vorbei. Sie können Ihre ItemsSource-Bindung vollständig aus dem XAML entfernen.

Sie sollten sich wirklich wie auch immer, werden mit VSTO anstelle von Datensätzen, aber das ist noch eine andere Sache zu :)

+0

Vielen Dank! Das hat perfekt funktioniert! Eine letzte Sache jedoch. Könnten Sie bitte den Zweck der Verwendung des "@" - Symbols erläutern? Ich verstehe nicht ganz, als du sagtest, ich brauche nicht "den Dingen zu entkommen". Danke noch einmal! –

+2

Ich bin mir sicher, dass Sie dies schon lange herausgefunden haben, aber wenn Sie @ "" anstelle von "" verwenden, ignoriert der Compiler die Zeichen und behandelt sie wie ein tatsächliches Zeichen anstelle eines Escape-Zeichens. – Gargoyle

Verwandte Themen