2012-06-14 5 views
6

Excel에서 채워진 DataSet의 열을 삭제하는 프로그램을 만들려고합니다. 열을 삭제하는 방법은 각 열의 머리글을 각 행의 첫 번째 요소와 비교하고 행에 나타나지 않는 문자열의 열을 삭제하는 것입니다. 내 문제는 내가 이해할 수없는 이상한 오류가 발생하고 있다는 것이다. 그것은 :지정한 바인딩 제약 조건과 일치하는 형식에서 생성자를 호출하면 예외가 throw되었습니다.

지정한 바인딩 제약 조건과 일치하는 'Excel_Retriever.MainWindow'형식의 생성자 호출이 예외를 던졌습니다. ' 행 번호 '3'및 행 위치 '9'.

저는 C# 및 XAML을 처음 사용했으며이 오류를 해결하는 데 도움을 주셔서 감사합니다. 고맙습니다! 여기 내 코드입니다 :

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

랩의 연결 및 어댑터를 배울 수있는 또 다른 일이다. – abatishchev

답변

3

당신은 당신이 그것을 사용하지 않을 귀하의 방법에 strTableName을 통과 할 필요가 없습니다.

문자열에 @ ""를 사용하면 상황을 벗어날 필요가 없습니다. @ "c : \ users ....";

실제로 존재하지 않는 행을 누락하려고하므로 예외가 발생합니다. 당신의 목표가 올바르게 이해된다면 이것이 당신의 방법처럼 보일 것입니다. 내가 ItemsSource,하지의 DataContext를 설정하고있어, 나는 기본보기를 통과하고있어

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

참고 : 엑셀을 설정 한 후

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

또한, MainWindow를 생성자에서이 작업을 수행 불과합니다. ItemsSource 바인딩을 XAML에서 완전히 제거 할 수 있습니다.

하기 정말 대신 데이터 집합의 VSTO를 사용한다,하지만 어쨌든 사용하여 블록 :

+0

정말 고마워요! 이것은 완벽하게 작동했습니다! 마지막으로 한 가지. "@"기호를 사용하는 목적을 설명해 주시겠습니까? 나는 당신이 "나는 물건을 피할 필요가 없다"고 말할 때 나는 꽤 이해하지 못한다. 다시 한 번 감사드립니다! –

+2

나는 이것을 오래 전에 알았 겠지만 ""대신 @ ""를 사용하면 컴파일러가 \ 문자를 무시하고 이스케이프 문자 대신 실제 \ 문자처럼 처리하도록합니다. – Gargoyle

관련 문제