You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

获取Excel工作表名至ComboBox后无法读取内容,报Cannot find table -1错误

解决Excel工作表选择时“Cannot find table -1”的报错问题

嘿,我一眼就瞅出问题出在哪了,咱们一步步拆解:

核心错误原因

  1. ComboBox未选中任何项时,SelectedIndex默认值是-1
    你刚把工作表名填充到ComboBox里,既没设置默认选中项,也没等用户手动选择,就直接用comboBox1.SelectedIndex去取DataTable集合里的表——索引-1对应的表根本不存在,自然会抛出“Cannot find table -1”的错误。

  2. 重复读取Excel文件,低效且没必要
    你在按钮点击事件里连续调用了三次ExcelToDataTable(ofd.FileName),每次调用都会重新打开文件、解析整个Excel,这不仅浪费系统资源,还可能因为文件被重复占用触发IO异常。

修正方案

咱们只需要做两个关键调整:

  • 只读取一次Excel文件,把结果存起来复用
  • 给ComboBox设置默认选中项,或等待用户选择后再加载数据

第一步:修改按钮点击事件,复用DataSet

首先在窗体类里添加一个成员变量存储读取的Excel数据,避免重复读取:

// 窗体类的成员变量,用来缓存当前读取的Excel数据
private DataSet _currentExcelDataSet;

// 保持你的Excel读取方法不变
public static DataSet ExcelToDataTable(string fileName) {
    using (var stream = File.Open(fileName, FileMode.Open, FileAccess.Read)) {
        using (var reader = ExcelReaderFactory.CreateReader(stream)) {
            var result = reader.AsDataSet(new ExcelDataSetConfiguration() {
                UseColumnDataType = true,
                ConfigureDataTable = (data) => new ExcelDataTableConfiguration() {
                    UseHeaderRow = true
                }
            });
            return result;
        }
    }
}

private void btnOpen_Click(object sender, EventArgs e) {
    try {
        using (OpenFileDialog ofd = new OpenFileDialog() { 
            Filter = "Excel 2003 Worksheet|*.xls|Excel 2007 Worksheet|*.xlsx", 
            ValidateNames = true, 
            Multiselect = false 
        }) {
            if (ofd.ShowDialog() == DialogResult.OK) {
                // 只读取一次Excel文件,把结果存入成员变量
                _currentExcelDataSet = ExcelToDataTable(ofd.FileName);
                
                comboBox1.Items.Clear();
                foreach (DataTable dt in _currentExcelDataSet.Tables) {
                    comboBox1.Items.Add(dt.TableName);
                }
                
                // 默认选中第一个工作表(如果Excel里有表的话)
                if (comboBox1.Items.Count > 0) {
                    comboBox1.SelectedIndex = 0;
                    // 加载第一个工作表的数据到DataGridView
                    dataGridView1.DataSource = _currentExcelDataSet.Tables[0];
                }
            }
        }
    } catch (Exception ex) {
        MessageBox.Show(ex.Message);
    }
}

第二步:添加ComboBox选择变更事件,实现工作表切换

给ComboBox绑定SelectedIndexChanged事件,用户切换选项时自动更新DataGridView的数据:

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
    // 确保缓存的DataSet存在,且用户已选中有效项
    if (_currentExcelDataSet != null && comboBox1.SelectedIndex != -1) {
        dataGridView1.DataSource = _currentExcelDataSet.Tables[comboBox1.SelectedIndex];
    }
}

别忘了在窗体构造函数里手动绑定事件(或者在设计器里可视化绑定):

public YourFormName() {
    InitializeComponent();
    comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
}

这样修改后,既解决了报错问题,又优化了文件读取效率,用户切换工作表的体验也更流畅。

内容的提问来源于stack exchange,提问作者user9178291

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:42:46