Home > Back-end >  looking for a searching in excel programm
looking for a searching in excel programm

Time:10-24

im looking for programm that reads Excel documents and can search for a word in that document thank you with this code am able to read all Cells but i want to add the function that i could search for a word that i input in(console.readLine)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;

namespace ReadFromExcelComponente
{


    class Program
    {
        static void Main(string[] args)
        {
            //lese den excel
            Excel.Application ExcelApp;
            Excel.Workbook workbook;
            Excel.Worksheet worksheet;
            Excel.Range range;
            int row = 0;              
            int column = 0;             

            ExcelApp = new Excel.Application();
            workbook = ExcelApp.Workbooks.Open(@"D:\Map", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
            worksheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1);

            range = worksheet.UsedRange;

            List<String> myList = new List<string>();
            for (row = 1; row <= range.Rows.Count; row  )
            {
                for (column = 1; column <= range.Columns.Count; column  )
                {
                    Console.WriteLine(" Coulmn Number: "   column   "--> "   (range.Cells[row, column] as Excel.Range).Value2);
                    myList.Add(range.Cells[column].ToString());
                }
            }

            Console.WriteLine(myList[2]);
            Console.WriteLine(range.Cells[2, 2].Value);




            workbook.Close(true, null, null);
            ExcelApp.Quit();

            Console.ReadKey();

        } 


    }
}

CodePudding user response:

Try this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;

namespace ReadFromExcelComponente
{


class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter the word you want to search for:");
        string SearchWord = Console.ReadLine();
        //lese den excel
        Excel.Application ExcelApp;
        Excel.Workbook workbook;
        Excel.Worksheet worksheet;
        Excel.Range range;
        int row = 0;              
        int column = 0;             

        ExcelApp = new Excel.Application();
        workbook = ExcelApp.Workbooks.Open(@"D:\Map", 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
        worksheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1);

        range = worksheet.UsedRange;

        for (row = 1; row <= range.Rows.Count; row  )
        {
            for (column = 1; column <= range.Columns.Count; column  )
            {
               if(range.Range(row, column).Value = SearchWord)
                 {
                  Console.WriteLine("Found word!");
                  break;
               }
            }
        }

        Console.WriteLine(myList[2]);
        Console.WriteLine(range.Cells[2, 2].Value);




        workbook.Close(true, null, null);
        ExcelApp.Quit();
        ExcelApp = null;
        Console.ReadKey();

    } 
}
      }

CodePudding user response:

When “your code” starts the Excel application and opens an Excel file… then YOUR CODE becomes responsible for “releasing” the COM objects it creates… namely… the workbook and the Excel application.

If you do not release those objects, as your current code doesn’t, then those objects will remain in memory as active objects and basically never get released. Even if your code closes the file and Excel app… YOUR CODE still has to explicitly “release” the COM object. Granted, if you reboot the machine or even quit the application… then those objects may/will get released.

Fortunately, it is not difficult to manage the Excel resources. One fairly straight forward approach is to use a try/catch/finally statement to manage the resources. The try portion is where we put ALL the code that deals with the Excel file(s). The catch portion is used to obviously catch the exceptions. And the finally portion is where we would put the code to “release” the Excel COM objects.

With this approach, we should be able to rest a little easier knowing that the COM objects will STILL be released… even if the code crashes while working with the Excel file.

Next, I am aware that sometimes you must use Interop to work with Excel files and I have used it often and know it can be awkward. Not to mention that Interop is notoriously SLOW especially when dealing with large Excel files. My point is that if you DO have a choice, I would highly recommend a third-party Excel library. There are many to chose from and some are free.

Getting down from my soap box…

Looking at your code, there is one thing I am not following when the code gets the UsedRange from the Excel worksheet…

range = worksheet.UsedRange;

This range is a basic Excel Range object containing all the “used” cells in the worksheet. So far so good…

But… later we see a double for loop through the range’s rows and columns. The code then puts the values of each cell into (List<string>) myList. This will work however it seems unnecessary. Even if you want to search for a word in all the cells, there is no need to put the cell values into a list… you ALREADY have the cells in the range variable! In other words, instead of adding the words to a list, just loop through range and search for it.

When I say you have the range to work with, this means the Excel.Range object. And you already know you can easily loop through that range object as your code demonstrates… HOWEVER… IF range is large, THEN, you will note a significant performance hit. Bottom line is that “looping” through Excel.Range’es is expensive and slow.

Basically we want to minimize any looping through the range. One possible solution is to cast the range into a two (2) dimensional Object array. THEN, do all the looping through the Object array, which should be significantly faster and it makes the code a little easier to read.

Therefore, the line of code…

range = worksheet.UsedRange;

may end up looking like…

range = worksheet.UsedRange;
object[,] worksheetValues = (object[,])range.Cells.Value;

Now, we can loop through the worksheetValues array instead of the range itself.

This “should” replace the mylist variable as it is not needed… all the values are in the worksheetValues array.

Now that we have a simple object array to “search” through… then all we need is a search term to look for. If we get the search term from the user, then we could create a method that takes that search term and the array to search through and return all the X and Y coordinates of the cells that the search term matched. This method may look something like…

private static List<Point> FindWordInArray(string target, object[,] data) {
  List<Point> foundIndexes = new List<Point>();
  for (int row = 1; row <= data.GetLength(0); row  ) {
    for (int col = 1; col <= data.GetLength(1); col  ) {
      if (data[row, col] != null) {
        if (data[row, col].ToString().Equals(target)) {
          foundIndexes.Add(new Point { X = col, Y = row });
        }
      }
    }
  }
  return foundIndexes;
}


public class Point {
  public int X { get; set; }
  public int Y { get; set; }
}

I am aware the Point class may not be needed and is only there to simplify the example.

Below is a small yet complete example of what is described above. This includes setting up the try/catch/finally code along with releasing the COM objects.

NOTE: Excel starts array indexing at 1. Therefore the object array worksheetValues will start at index 1.

Excel.Application ExcelApp = null;
Excel.Workbook workbook = null;
Excel.Worksheet worksheet= null;
Excel.Range range = null;
string searchWord = "";
try {
  ExcelApp = new Excel.Application();
  workbook = ExcelApp.Workbooks.Open(@"D:\Map", 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
  worksheet = (Excel.Worksheet)workbook.Worksheets.get_Item(1);
  range = worksheet.UsedRange;
  object[,] worksheetValues = (object[,])range.Cells.Value;
  Console.WriteLine("There are "   worksheetValues.GetLength(0)   " Rows and "   worksheetValues.GetLength(1)   " Columns");
  for (int row = 1; row <= worksheetValues.GetLength(0); row  ) {
    Console.Write("Row "   row   ": ");
    for (int col = 1; col <= worksheetValues.GetLength(1); col  ) {
      if (worksheetValues[row, col] != null) {
        Console.Write(worksheetValues[row, col]);
      }
      else {
        Console.Write(" - ");
      }
    }
    Console.WriteLine();
  }
  Console.WriteLine("Type the word you want to search for...");
  searchWord = Console.ReadLine().Trim();
  List<Point> foundItems = FindWordInArray(searchWord, worksheetValues);
  foreach (Point point in foundItems) {
    Console.WriteLine("Found at Row: "   point.Y   " - Col: "   point.X);
  }
}
catch (Exception ex) {
  Console.WriteLine("Excel error: "   ex.Message);
}
finally {
  if (range != null) {
    Marshal.ReleaseComObject(range);
  }
  if (worksheet != null) {
    Marshal.ReleaseComObject(worksheet);
  }
  if (workbook != null) {
    workbook.Close(true, null, null);
    Marshal.ReleaseComObject(workbook);
  }
  if (ExcelApp != null) {
    ExcelApp.Quit();
    Marshal.ReleaseComObject(ExcelApp);
  }
}

I hope this makes sense and helps.

  • Related