1

这是我在这里的第一篇文章,一般来说 - 我对 C# 很陌生,所以请原谅我的任何错误。我正在尝试执行以下操作:

    1. 我有一个带有 3 张 excel 表的 excel 文件:sheet1, sheet2, sheet3
    2. 在每张 excel 表格中,我都有一个包含 3 列的表格:ID、名称、NEW_ID。所有这 3 列都是字符串类型,因此数组也可以工作。
    3. 在我的代码开始时,我只想访问这个 excel 文件一次,并将这些工作表作为3 个单独的数组或列表输出到代码中,并让它们在代码执行结束时可用
    4. 我想将该数据填充到数组/列表中,因为稍后我必须在这些数组中搜索给定的 ID(列 ID)并从列 Name 和 NEW_ID 返回相应的值。我将不得不为大约 100k 个 ID 执行此操作,因此我不想每次都访问该文件,因为我相信它会减慢整个过程。
    5. 我知道如何使用 OLEDB 从 excel 访问数据,因为我在这里检查了其他主题,但我不知道如何将该数据输出到 3 个单独的数组/列表并在这些数组/列表中搜索给定 ID 并返回相应的数组项。

感谢您的任何帮助!

这是我正在运行的代码。有问题的部分是代码末尾的ReadExcel类:

public class RecursiveFileProcessor
{
    static void Main()
    {
        string InputMainFolder = "C:\\US\\";
        string OutputMainFolder = "C:\\BAJ\\";
        foreach (string InputFile in GetFiles(InputMainFolder))
        {
            Console.WriteLine(InputFile);
            string InputPath = Path.GetDirectoryName(InputFile);
            string InputFileName = Path.GetFileName(InputFile);
            string OuputPath = InputPath.Replace(InputMainFolder, OutputMainFolder);
            string OutputFile = System.IO.Path.Combine(OuputPath, InputFileName);

            // To copy a folder's contents to a new location: 
            // Create a new target folder, if necessary. 
            if (!System.IO.Directory.Exists(OuputPath))
            {
                System.IO.Directory.CreateDirectory(OuputPath);
                //Console.WriteLine("Ouput folder " + OuputPath + "created.");
            }

            // To copy a file to another location and  
            // overwrite the destination file if it already exists.
            if (File.Exists(OutputFile))
            {
                Console.WriteLine("ERROR: File Already Exists: " + OutputFile);
                continue;
            }
            else
            {
                System.IO.File.Copy(InputFile, OutputFile, true);
            }

            //Try to catch an exception
            try
            {
                //Here comes some important part of my code (that works fine)
            }

            catch (Exception exe)
            {
                //call LogFile method and pass argument as Exception message, event name, control name, error line number, current form name
                LogFile(exe.Message, exe.ToString(), exe.LineNumber(), InputFile, OutputMainFolder);
            }

        }
        //call excel reader for tests
        //THIS IS THE PLACE WHERE I WILL CALL MY EXCEL READER TO GET DATA INTO ARRAY/LIST/DATASET ETC
        {
            string MappingFile = "c:\\attributes mapping\\attributes mapping.xlsx";
            ReadExcel.ReadExcelToTable(MappingFile);
        }
        //That's the final line of the code
        Console.WriteLine("DONE: " + DateTime.Now.ToUniversalTime() + " UTC");
        Console.ReadLine();
    }

    static IEnumerable<string> GetFiles(string path)
    {
        Queue<string> queue = new Queue<string>();
        queue.Enqueue(path);
        while (queue.Count > 0)
        {
            path = queue.Dequeue();
            try
            {
                foreach (string subDir in Directory.GetDirectories(path))
                {
                    queue.Enqueue(subDir);
                }
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
            }
            string[] files = null;
            try
            {
                files = Directory.GetFiles(path);
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
            }
            if (files != null)
            {
                for (int i = 0; i < files.Length; i++)
                {
                    yield return files[i];
                }
            }
        }
    }
    //This function writes exception details to the file in the output folder
    public static void LogFile(string sExceptionName, string sEventName, int nErrorLineNo, string sFileName, string sOutputFolder)
    {
        StreamWriter log;
        if (!File.Exists(sOutputFolder + "logfile.txt"))
        {
            log = new StreamWriter(sOutputFolder + "logfile.txt");
        }
        else
        {
            log = File.AppendText(sOutputFolder + "logfile.txt");
        }
        // Write to the file:
        log.WriteLine("File Name:" + sFileName);
        log.WriteLine("Data Time:" + DateTime.Now);
        log.WriteLine("Error Line No.:" + nErrorLineNo);
        log.WriteLine("Exception Name:" + sExceptionName);
        log.WriteLine("Event Name:" + sEventName);
        log.WriteLine("--------------------------------------------------------------------------");

        // Close the stream:
        log.Close();
    }
}
//This part of code gets a line number where the exception appeared
public static class ExceptionHelper
{
    public static int LineNumber(this Exception e)
    {
        int linenum = 0;
        try
        {
            linenum = Convert.ToInt32(e.StackTrace.Substring(e.StackTrace.LastIndexOf(":line") + 5));
        }
        catch
        {
            //Stack trace is not available!
        }
        return linenum;
    }
}

好的,我已经设法将这些数据放入 DataTables 中:

//Reads excel file and creates data sets from each excel sheet
public static DataSet ReadExcelToTable(string FileName)
{
    //string HDR = hasHeaders ? "Yes" : "No";
    string strConn;
    if (FileName.Substring(FileName.LastIndexOf('.')).ToLower() == ".xlsx")
        strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + FileName + ";Extended Properties=\'Excel 8.0;HDR=YES;IMEX=1';";
    else
       strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FileName + ";Extended Properties=\'Excel 8.0;HDR=YES;IMEX=1';";

    DataSet output = new DataSet();

    using (OleDbConnection conn = new OleDbConnection(strConn))
    {
        conn.Open();

        DataTable schemaTable = conn.GetOleDbSchemaTable(
            OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });

        foreach (DataRow schemaRow in schemaTable.Rows)
        {
            string sheet = schemaRow["TABLE_NAME"].ToString();

            if (!sheet.EndsWith("_"))
            {
                try
                {
                    OleDbCommand cmd = new OleDbCommand("SELECT * FROM [" + sheet + "]", conn);
                    cmd.CommandType = CommandType.Text;

                    DataTable outputTable = new DataTable(sheet);
                    output.Tables.Add(outputTable);
                    new OleDbDataAdapter(cmd).Fill(outputTable);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message + string.Format("Sheet:{0}.File:F{1}", sheet, FileName), ex);
                }
            }
        }
    }
    return output;

这些数据表 (3) 必须在代码执行结束时可用。

ExcelReader 将返回 3 个 DataTables 作为输出,对吗?然后我必须在调用 ExcelReader 类并将这 3 个 DataTables 作为输出的地方之后继续编写代码。

现在我必须做这样的事情:

    1. 假设“InputPath”字符串是这样的:
    C:\BAJ\Sheet1\ABCDC:\BAJ\Sheet2\EFGHC:\BAJ\Sheet3\IJKL(这些是随机名称)
    2.如果“InputPath”包含“Sheet1”-->打开DataTable“Sheet1”
    3.检查DataTable“Sheet1”中是否可以在ID列中找到ID=ABCD(也取自“InputPath”变量)
    4. 如果找到 - 将对应的 NAME 和 NEW_ID 值作为变量返回,比如说:sName 和 sNew_Id

额外信息: ID 列中的 ID 是唯一的字符串,只能返回一个 Name 和一个 New_Id(也可以是字符串)。

有任何想法吗?

4

0 回答 0