2012-06-14 12 views
6

Bir excel dosyası tarafından doldurulmuş bir DataSet'te sütunları silen bir program yapmaya çalışıyorum. Sütunları silme şekli, her bir sütundaki başlıkları her satırdaki ilk öğe ile karşılaştırır ve satırlarda görünmeyen herhangi bir dizenin sütununu siler. Benim problemim, anlayamadığım garip bir hata alıyorum. diyor ki:Belirtilen bağ kısıtlamalarına uyan türdeki kurucunun çağrılması bir istisna attı

Yapıcının, belirtilen ciltleme kısıtlamalarıyla eşleşen "Excel_Retriever.MainWindow" üzerindeki çağrılması bir istisna attı. Satır numarası '3' ve satır konumu '9'.

C# ve XAML için yeni ve bu hatayı çözme konusunda herhangi bir yardımı gerçekten takdir ediyorum. Teşekkür ederim! İşte benim kodudur:

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 Bağlantısı ve Adaptör öğrenmek için başka bir şey. – abatishchev

cevap

3

Sen bunu kullanmak asla gibi yönteme strTableName geçmesine gerek yoktur.

Dizeler için @ "" kullanırsanız, bir şeylerden kaçmanız gerekmez: @ "c: \ users ....";

Bir istisna görüyorsunuz, çünkü gerçekten varolmayan satırları yoklamaya çalışıyorsunuz. Hedefinizi burada doğru anlıyorsam, yöntemin nasıl görünmesi gerektiği budur. Ben ItemsSource değil DataContext'i ayarı ediyorum ve defaultView geçiyorum

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

Not: Eğer excel ayarladıktan sonra

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

Ayrıca MainWindow yapıcısındaki, bunu sadece gerekir. ItemsSource bağlayıcınızı tamamen XAML'den kaldırabilirsiniz.

Gerçekten yerine DataSet VSTO kullanarak olmalıdır, ama bu yine de, bir kullanma bloğu ile :)

+0

Çok teşekkür ederim! Bu mükemmel çalıştı! Son bir şey olsa da. "@" Sembolünü kullanma amacını açıklar mısınız? "Kaçış şeylerine" ihtiyacım olmadığını söylediğinde anlamıyorum. Tekrar teşekkürler! –

+2

Uzun zaman önce bunu anladığınızdan eminim ancak "" yerine "" sadece derleyicinin \ karakterleri görmezden gelmesini ve onları bir çıkış karakteri yerine gerçek bir karakter gibi ele almasını sağlıyor. – Gargoyle

İlgili konular