7

我正在尝试制作一个程序来删除由 excel 文件填充的 DataSet 中的列。它删除列的方式是将每列中的标题与每行中的第一个元素进行比较,并删除未出现在行中的任何字符串的列。我的问题是我遇到了一个我无法理解的奇怪错误。它说:

对匹配指定绑定约束的“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;
        }
    }
}
4

1 回答 1

3

您不需要将 strTableName 传递给您的方法,因为您从不使用它。

如果您对字符串使用 @"" ,则不需要转义:@"c:\users....";

你得到了一个例外,因为你试图核对实际上并不存在的行。如果我正确理解您的目标,这就是您的方法应该是什么样子。

    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 构造函数中,您应该在设置 excel 后执行此操作:

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

请注意,我设置的是 ItemsSource,而不是 DataContext,并且我正在传递 DefaultView。您可以从 XAML 中完全删除 ItemsSource 绑定。

您确实应该使用VSTO而不是 DataSet,但这是要学习的另一件事 :)

于 2012-06-14T06:22:27.083 回答