C# 搜索整个工作簿并提取值

C# 搜索整个工作簿并提取值,c#,.net,vb.net,excel,c#-4.0,C#,.net,Vb.net,Excel,C# 4.0,在我的excel工作簿中 第一个“图纸”选项卡包含 Number Name Code Subject 100 Mark ABC Mathematics 101 John XYZ Physics The second sheet tab contains Number Name Code Subject 103 Mark DEF Chemistry 104 John GHI Biology 我想将代码(将是唯一的)作为参数传递,并搜索整个excel工作簿

在我的excel工作簿中

第一个“图纸”选项卡包含

Number Name Code    Subject
100    Mark ABC Mathematics
101    John XYZ Physics

The second sheet tab contains

Number Name Code    Subject
103    Mark DEF Chemistry
104    John GHI Biology
我想将代码(将是唯一的)作为参数传递,并搜索整个excel工作簿

并获取名称和主题

ie..从myexcelworkbook中选择名称、主题,其中的代码='ABC'

我能够获取工作表名称、列数等,但无法搜索整个excel工作簿并获取所需的值

        const string fileName="C:\\FileName.xls";

        OleDbConnectionStringBuilder connectionStringBuilder = new OleDbConnectionStringBuilder();
        connectionStringBuilder.Provider = "Microsoft.ACE.OLEDB.12.0";
        connectionStringBuilder.DataSource = fileName;
        connectionStringBuilder.Add("Mode", "Read");

        const string extendedProperties = "Excel 12.0;IMEX=1;HDR=YES";
        connectionStringBuilder.Add("Extended Properties", extendedProperties);
        using (OleDbConnection objConn = new OleDbConnection(connectionStringBuilder.ConnectionString))
       {
            objConn.Open();

            Microsoft.Office.Interop.Excel.Application xlsApp = new Microsoft.Office.Interop.Excel.Application();
            Workbook wb = xlsApp.Workbooks.Open(fileName, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true);

            Sheets sheets = wb.Worksheets;

            for (int i =1 ; i <= wb.Worksheets.Count; i++)
            {

                MessageBox.Show(wb.Sheets[i].Name.ToString()); - gives sheet names inside the workbook
            }

          Worksheet ws = (Worksheet)sheets.get_Item(1); - gives the elements of specified sheet tab
      }

  //To get elements inside a specific sheet of an excel workbook/get column names

        OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM [" + "Sheet1" + "$]", objConn); 

        OleDbDataAdapter objAdapter1 = new OleDbDataAdapter(); 

        objAdapter1.SelectCommand = objCmdSelect; 

        DataSet objDataset1 = new DataSet(); 

        objAdapter1.Fill(objDataset1);

        string columnNames = string.Empty;
        // For each DataTable, print the ColumnName. use dataset.Rows to iterate row data...
        foreach (System.Data.DataTable table in objDataset1.Tables)
        {
            foreach (DataColumn column in table.Columns)
            {
                if (columnNames.Length > 0)
                {
                    columnNames = columnNames + Environment.NewLine + column.ColumnName;
                }
                else
                {
                    columnNames = column.ColumnName;
                }

            }
        } 
const string fileName=“C:\\fileName.xls”;
OleDbConnectionStringBuilder connectionStringBuilder=新的OleDbConnectionStringBuilder();
connectionStringBuilder.Provider=“Microsoft.ACE.OLEDB.12.0”;
connectionStringBuilder.DataSource=文件名;
connectionStringBuilder.Add(“Mode”,“Read”);
const string extendedProperties=“Excel 12.0;IMEX=1;HDR=YES”;
connectionStringBuilder.Add(“扩展属性”,extendedProperties);
使用(OleDbConnection objConn=新的OleDbConnection(connectionStringBuilder.ConnectionString))
{
objConn.Open();
Microsoft.Office.Interop.Excel.Application xlsApp=新的Microsoft.Office.Interop.Excel.Application();
工作簿wb=xlsApp.Workbooks.Open(文件名,0,true,5,“,”,true,XlPlatform.xlWindows,“\t”,false,false,0,true);
工作表=wb.工作表;
对于(int i=1;i 0)
{
columnNames=columnNames+Environment.NewLine+column.ColumnName;
}
其他的
{
columnNames=column.ColumnName;
}
}
} 

有人能分享一些想法吗?这样我就可以找出excel工作簿中的唯一数据,并根据这些数据提取出所需的值?提前感谢。

如果工作簿的结构如您所示,并且您将查询多个学生,那么,正如@Andy G所建议的,您可能会发现最简单的方法是将数据放入某种形式的记录集中,然后通过Linq或SQL或任何您喜欢的方式对其进行查询。由于您根本不希望修改Excel工作簿,因此这可能是一种更好的方法

或者,您可以使用excelapi,就像您也尝试使用它一样。您可以枚举工作表,对每个工作表运行查找。A洛杉矶:

internal void GetYourData()
{
    //... code to get the relevant Workbook and relevant/new Excel Application

    Tuple<string, string> pupil;
    string searchTerm = "ABC";

    //Get the cell of the match
    Range match = FindFirstOccurrenceInWorkbook(workbook, searchTerm);
    if (match != null)
    {
        //Do whatever - per your data structure, it is probably easiest to just use .Offset(row, column) property
        pupil = new Tuple<string, string>((string)match.Offset(0, -1).Value, (string)match.Offset(0, 1).Value);
    }

    //... code to do whatever with your results
}

internal static Range FindFirstOccurrenceInWorkbook(Workbook workbook, string searchTerm)
{
    if (workbook == null) throw new ArgumentNullException("workbook");
    if (searchTerm == null) throw new ArgumentNullException("searchTerm");

    Sheets wss = workbook.Worksheets;
    Range match = null;

    foreach (Worksheet ws in wss)
    {
        Range cells = ws.Cells;
        //Add more args as needed - this is just an example
        match = cells.Find(
                what: searchTerm,
                after: Type.Missing,
                lookIn: XlFindLookIn.xlFormulas,
                lookAt: XlLookAt.xlPart);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(cells);
        System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
        if (match != null)
        {
            break;
        }
    }
    System.Runtime.InteropServices.Marshal.ReleaseComObject(wss);
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();

    return match;
}
内部无效GetYourData()
{
//…获取相关工作簿和相关/新Excel应用程序的代码
二元组瞳孔;
字符串searchTerm=“ABC”;
//获取匹配的单元格
范围匹配=在工作簿(工作簿,搜索术语)中查找FirstToCurrenceInWorkbook;
如果(匹配!=null)
{
//不管做什么-根据您的数据结构,可能最容易只使用.Offset(行、列)属性
瞳孔=新元组((字符串)匹配.偏移量(0,-1).Value,(字符串)匹配.偏移量(0,1).Value);
}
//…对结果执行任何操作的代码
}
内部静态范围FindFirstOccurrenceInWorkbook(工作簿工作簿,字符串搜索术语)
{
如果(工作簿==null)抛出新的ArgumentNullException(“工作簿”);
如果(searchTerm==null)抛出新的ArgumentNullException(“searchTerm”);
工作表wss=工作簿。工作表;
范围匹配=空;
foreach(wss中的工作表ws)
{
范围单元格=ws.cells;
//根据需要添加更多参数-这只是一个示例
匹配=单元格。查找(
什么:搜索术语,
之后:Type.Missing,
lookIn:XlFindLookIn.xlFormulas,
lookAt:XlLookAt.xlPart);
System.Runtime.InteropServices.Marshal.ReleaseComObject(单元格);
System.Runtime.InteropServices.Marshal.ReleaseComObject(ws);
如果(匹配!=null)
{
打破
}
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(wss);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
复赛;
}

此外,如果不生成孤立引用,则不能像使用COM对象一样使用->这将阻止Excel应用程序关闭。您需要将所有要使用的对象属性(如工作簿.工作表)显式分配给变量,然后在变量即将超出范围时调用System.Runtime.InteropServices.Marshal.ReleaseCOMObject(对象)。

您尝试了什么?代码从COM互操作开始打开工作簿,然后切换到使用OleDb填充数据集。在同一代码块中执行这两项操作是不常见的。您将使用哪种方法来查找所需的值?如果您正在填充数据集,则互操作似乎不必要,您可以搜索或筛选数据表。谢谢。偏移量(-1,0)。值是抛出错误,我使用了get\u Offset新元组((字符串)匹配。get\u Offset(-1,0)。值,(字符串)匹配。get\u Offset(1,0)。值);但是输出结果不正确,让我再检查一次。@Sharpeye500哇塞-我把本来应该是列偏移量的内容作为行偏移量,反之亦然。(只需将偏移量(-1,0)更改为偏移量(0,-1)等)。此外,我使用的是NetOffice而不是Microsoft PIA,因此获取偏移量可能是您需要的。偏移量对我来说当然有用。谢谢,不用偏移量(0,1)。值,不管怎样,只要输出结果发生变化,我都可以传递列名?