2012-06-14 63 views
6

Estoy tratando de crear un programa que elimine columnas en un DataSet que se llena con un archivo de Excel. La forma en que elimina las columnas es que compara el encabezado de cada columna con el primer elemento de cada fila y elimina la columna de cualquier cadena que no aparece en las filas. Mi problema es que estoy obteniendo un error extraño que no puedo entender. dice:La invocación del constructor en el tipo que coincide con las restricciones de enlace especificadas arrojó una excepción

La invocación del constructor en el tipo 'Excel_Retriever.MainWindow' que coincide con las restricciones de enlace especificadas arrojó una excepción. ' Número de línea '3' y posición de línea '9'.

Soy nuevo en C# y XAML y realmente agradecería cualquier ayuda para resolver este error. ¡Gracias! Aquí está mi código:

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

conexión Wrap y adaptador con un bloque utilizando, de todos modos. – abatishchev

Respuesta

3

No es necesario pasar strTableName a su método, ya que nunca lo usa.

Si utiliza @ "" para cadenas, no necesita escaparse: @ "c: \ users ....";

Estás recibiendo una excepción porque estás intentando destruir las filas que realmente no existen. Este es el aspecto que debería tener su método, si entiendo correctamente su objetivo aquí.

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); 
    } 

Además, en MainWindow constructor, sólo debe hacerlo después de configurar Excel:

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

Nota que estoy estableciendo ItemsSource, no DataContext, y estoy pasando el DefaultView. Puede eliminar su enlace de ItemsSource del XAML por completo.

que realmente debería estar usando VSTO en lugar de conjuntos de datos, pero eso es otra cosa que aprender :)

+0

¡Muchas gracias! Esto funcionó a la perfección! Una última cosa sin embargo. ¿Podría explicar el propósito de usar el símbolo "@"? No entiendo muy bien cuando dijiste que no necesito "escapar de las cosas". ¡Gracias de nuevo! –

+2

Estoy seguro de que ya lo descubrió hace mucho tiempo, pero usar @ "" en vez de "" solo hace que el compilador ignore los \ caracteres y los trate como un carácter \ real en lugar de un carácter de escape. – Gargoyle

Cuestiones relacionadas